Browse Source

Nightly + new DecomposeLerp for matrices

David Catuhe 7 years ago
parent
commit
de33cd2f31
44 changed files with 31246 additions and 30051 deletions
  1. 21667 21582
      Playground/babylon.d.txt
  2. 1 0
      Playground/scenes/dummy3.babylon
  3. 8095 8010
      dist/preview release/babylon.d.ts
  4. 55 55
      dist/preview release/babylon.js
  5. 315 45
      dist/preview release/babylon.max.js
  6. 167 40
      dist/preview release/babylon.no-module.max.js
  7. 53 53
      dist/preview release/babylon.worker.js
  8. 313 43
      dist/preview release/es6.js
  9. 2 2
      dist/preview release/gui/babylon.gui.js
  10. 4 4
      dist/preview release/gui/babylon.gui.min.js
  11. 4 4
      dist/preview release/inspector/babylon.inspector.bundle.js
  12. 3 3
      dist/preview release/inspector/babylon.inspector.min.js
  13. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  14. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  15. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  16. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  17. 2 2
      dist/preview release/loaders/babylonjs.loaders.js
  18. 3 3
      dist/preview release/loaders/babylonjs.loaders.min.js
  19. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  20. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  21. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  22. 2 2
      dist/preview release/materialsLibrary/babylonjs.materials.js
  23. 5 5
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  24. 1 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js
  25. 1 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js
  26. 2 2
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.js
  27. 1 1
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js
  28. 2 2
      dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.js
  29. 1 1
      dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js
  30. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  31. 2 2
      dist/preview release/serializers/babylonjs.serializers.js
  32. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  33. 2 7
      dist/preview release/typedocValidationBaseline.json
  34. 63 63
      dist/preview release/viewer/babylon.viewer.js
  35. 322 52
      dist/preview release/viewer/babylon.viewer.max.js
  36. 1 0
      dist/preview release/what's new.md
  37. 11 4
      src/Actions/babylon.actionManager.ts
  38. 11 0
      src/Animations/babylon.animation.ts
  39. 13 1
      src/Animations/babylon.runtimeAnimation.ts
  40. 17 0
      src/Materials/Textures/babylon.cubeTexture.ts
  41. 2 2
      src/Materials/Textures/babylon.hdrCubeTexture.ts
  42. 60 36
      src/Math/babylon.math.ts
  43. 30 10
      src/babylon.scene.ts
  44. BIN
      tests/validation/ReferenceImages/enableDisablePostProcess.png

File diff suppressed because it is too large
+ 21667 - 21582
Playground/babylon.d.txt


File diff suppressed because it is too large
+ 1 - 0
Playground/scenes/dummy3.babylon


File diff suppressed because it is too large
+ 8095 - 8010
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 55 - 55
dist/preview release/babylon.js


+ 315 - 45
dist/preview release/babylon.max.js

@@ -1,5 +1,3 @@
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 
 
 (function universalModuleDefinition(root, factory) {
 (function universalModuleDefinition(root, factory) {
@@ -33,6 +31,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
   OIMO = OIMO || this.OIMO;
   OIMO = OIMO || this.OIMO;
   earcut = earcut || this.earcut;
   earcut = earcut || this.earcut;
 
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 "use strict";
 var BABYLON;
 var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
@@ -4724,7 +4724,6 @@ var BABYLON;
         Quaternion.SlerpToRef = function (left, right, amount, result) {
         Quaternion.SlerpToRef = function (left, right, amount, result) {
             var num2;
             var num2;
             var num3;
             var num3;
-            var num = amount;
             var num4 = (((left.x * right.x) + (left.y * right.y)) + (left.z * right.z)) + (left.w * right.w);
             var num4 = (((left.x * right.x) + (left.y * right.y)) + (left.z * right.z)) + (left.w * right.w);
             var flag = false;
             var flag = false;
             if (num4 < 0) {
             if (num4 < 0) {
@@ -4732,14 +4731,14 @@ var BABYLON;
                 num4 = -num4;
                 num4 = -num4;
             }
             }
             if (num4 > 0.999999) {
             if (num4 > 0.999999) {
-                num3 = 1 - num;
-                num2 = flag ? -num : num;
+                num3 = 1 - amount;
+                num2 = flag ? -amount : amount;
             }
             }
             else {
             else {
                 var num5 = Math.acos(num4);
                 var num5 = Math.acos(num4);
                 var num6 = (1.0 / Math.sin(num5));
                 var num6 = (1.0 / Math.sin(num5));
-                num3 = (Math.sin((1.0 - num) * num5)) * num6;
-                num2 = flag ? ((-Math.sin(num * num5)) * num6) : ((Math.sin(num * num5)) * num6);
+                num3 = (Math.sin((1.0 - amount) * num5)) * num6;
+                num2 = flag ? ((-Math.sin(amount * num5)) * num6) : ((Math.sin(amount * num5)) * num6);
             }
             }
             result.x = (num3 * left.x) + (num2 * right.x);
             result.x = (num3 * left.x) + (num2 * right.x);
             result.y = (num3 * left.y) + (num2 * right.y);
             result.y = (num3 * left.y) + (num2 * right.y);
@@ -5165,24 +5164,28 @@ var BABYLON;
          * @returns true if operation was successful
          * @returns true if operation was successful
          */
          */
         Matrix.prototype.decompose = function (scale, rotation, translation) {
         Matrix.prototype.decompose = function (scale, rotation, translation) {
-            translation.x = this.m[12];
-            translation.y = this.m[13];
-            translation.z = this.m[14];
+            if (translation) {
+                translation.x = this.m[12];
+                translation.y = this.m[13];
+                translation.z = this.m[14];
+            }
             scale.x = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1] + this.m[2] * this.m[2]);
             scale.x = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1] + this.m[2] * this.m[2]);
             scale.y = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5] + this.m[6] * this.m[6]);
             scale.y = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5] + this.m[6] * this.m[6]);
             scale.z = Math.sqrt(this.m[8] * this.m[8] + this.m[9] * this.m[9] + this.m[10] * this.m[10]);
             scale.z = Math.sqrt(this.m[8] * this.m[8] + this.m[9] * this.m[9] + this.m[10] * this.m[10]);
             if (this.determinant() <= 0) {
             if (this.determinant() <= 0) {
                 scale.y *= -1;
                 scale.y *= -1;
             }
             }
-            if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
-                rotation.x = 0;
-                rotation.y = 0;
-                rotation.z = 0;
-                rotation.w = 1;
-                return false;
+            if (rotation) {
+                if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+                    rotation.x = 0;
+                    rotation.y = 0;
+                    rotation.z = 0;
+                    rotation.w = 1;
+                    return false;
+                }
+                Matrix.FromValuesToRef(this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0, this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0, this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0, 0, 0, 0, 1, MathTmp.Matrix[0]);
+                Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
             }
             }
-            Matrix.FromValuesToRef(this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0, this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0, this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0, 0, 0, 0, 1, MathTmp.Matrix[0]);
-            Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
             return true;
             return true;
         };
         };
         /**
         /**
@@ -5772,18 +5775,36 @@ var BABYLON;
          * @returns the new matrix
          * @returns the new matrix
          */
          */
         Matrix.DecomposeLerp = function (startValue, endValue, gradient) {
         Matrix.DecomposeLerp = function (startValue, endValue, gradient) {
-            var startScale = new Vector3(0, 0, 0);
-            var startRotation = new Quaternion();
-            var startTranslation = new Vector3(0, 0, 0);
+            var result = Matrix.Zero();
+            Matrix.DecomposeLerpToRef(startValue, endValue, gradient, result);
+            return result;
+        };
+        /**
+         * Update a matrix to values which are computed by:
+         * * decomposing the the "startValue" and "endValue" matrices into their respective scale, rotation and translation matrices
+         * * interpolating for "gradient" (float) the values between each of these decomposed matrices between the start and the end
+         * * recomposing a new matrix from these 3 interpolated scale, rotation and translation matrices
+         * @param startValue defines the first matrix
+         * @param endValue defines the second matrix
+         * @param gradient defines the gradient between the two matrices
+         * @param result defines the target matrix
+         */
+        Matrix.DecomposeLerpToRef = function (startValue, endValue, gradient, result) {
+            var startScale = MathTmp.Vector3[0];
+            var startRotation = MathTmp.Quaternion[0];
+            var startTranslation = MathTmp.Vector3[1];
             startValue.decompose(startScale, startRotation, startTranslation);
             startValue.decompose(startScale, startRotation, startTranslation);
-            var endScale = new Vector3(0, 0, 0);
-            var endRotation = new Quaternion();
-            var endTranslation = new Vector3(0, 0, 0);
+            var endScale = MathTmp.Vector3[2];
+            var endRotation = MathTmp.Quaternion[1];
+            var endTranslation = MathTmp.Vector3[3];
             endValue.decompose(endScale, endRotation, endTranslation);
             endValue.decompose(endScale, endRotation, endTranslation);
-            var resultScale = Vector3.Lerp(startScale, endScale, gradient);
-            var resultRotation = Quaternion.Slerp(startRotation, endRotation, gradient);
-            var resultTranslation = Vector3.Lerp(startTranslation, endTranslation, gradient);
-            return Matrix.Compose(resultScale, resultRotation, resultTranslation);
+            var resultScale = MathTmp.Vector3[4];
+            Vector3.LerpToRef(startScale, endScale, gradient, resultScale);
+            var resultRotation = MathTmp.Quaternion[2];
+            Quaternion.SlerpToRef(startRotation, endRotation, gradient, resultRotation);
+            var resultTranslation = MathTmp.Vector3[5];
+            Vector3.LerpToRef(startTranslation, endTranslation, gradient, resultTranslation);
+            Matrix.ComposeToRef(resultScale, resultRotation, resultTranslation, result);
         };
         };
         /**
         /**
          * Gets a new rotation matrix used to rotate an entity so as it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up"
          * Gets a new rotation matrix used to rotate an entity so as it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up"
@@ -7105,9 +7126,9 @@ var BABYLON;
     var MathTmp = /** @class */ (function () {
     var MathTmp = /** @class */ (function () {
         function MathTmp() {
         function MathTmp() {
         }
         }
-        MathTmp.Vector3 = [Vector3.Zero()];
+        MathTmp.Vector3 = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
         MathTmp.Matrix = [Matrix.Zero(), Matrix.Zero()];
         MathTmp.Matrix = [Matrix.Zero(), Matrix.Zero()];
-        MathTmp.Quaternion = [Quaternion.Zero()];
+        MathTmp.Quaternion = [Quaternion.Zero(), Quaternion.Zero(), Quaternion.Zero()];
         return MathTmp;
         return MathTmp;
     }());
     }());
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
@@ -25322,16 +25343,22 @@ var BABYLON;
                 var target = this._registeredForLateAnimationBindings.data[index];
                 var target = this._registeredForLateAnimationBindings.data[index];
                 for (var path in target._lateAnimationHolders) {
                 for (var path in target._lateAnimationHolders) {
                     var holder = target._lateAnimationHolders[path];
                     var holder = target._lateAnimationHolders[path];
+                    var originalValue = holder.animations[0].originalValue;
                     // Sanity check
                     // Sanity check
-                    if (!holder.animations[0].originalValue.scaleAndAddToRef) {
+                    if (!originalValue.scaleAndAddToRef) {
                         continue;
                         continue;
                     }
                     }
+                    var matrixDecomposeMode = BABYLON.Animation.AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix
                     var normalizer = 1.0;
                     var normalizer = 1.0;
                     var finalValue = void 0;
                     var finalValue = void 0;
                     if (holder.totalWeight < 1.0) {
                     if (holder.totalWeight < 1.0) {
-                        // We need to mix the original value in
-                        var originalValue = holder.animations[0].originalValue;
-                        finalValue = originalValue.scale(1.0 - holder.totalWeight);
+                        // We need to mix the original value in     
+                        if (matrixDecomposeMode) {
+                            finalValue = originalValue.clone();
+                        }
+                        else {
+                            finalValue = originalValue.scale(1.0 - holder.totalWeight);
+                        }
                     }
                     }
                     else {
                     else {
                         // We need to normalize the weights
                         // We need to normalize the weights
@@ -25339,11 +25366,27 @@ var BABYLON;
                     }
                     }
                     for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
                     for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
                         var runtimeAnimation = holder.animations[animIndex];
                         var runtimeAnimation = holder.animations[animIndex];
+                        var scale = runtimeAnimation.weight / normalizer;
                         if (finalValue) {
                         if (finalValue) {
-                            runtimeAnimation.currentValue.scaleAndAddToRef(runtimeAnimation.weight / normalizer, finalValue);
+                            if (matrixDecomposeMode) {
+                                BABYLON.Matrix.DecomposeLerpToRef(finalValue, runtimeAnimation.currentValue, scale, finalValue);
+                            }
+                            else {
+                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                            }
                         }
                         }
                         else {
                         else {
-                            finalValue = runtimeAnimation.currentValue.scale(runtimeAnimation.weight / normalizer);
+                            if (scale !== 1) {
+                                if (matrixDecomposeMode) {
+                                    finalValue = runtimeAnimation.currentValue.clone();
+                                }
+                                else {
+                                    finalValue = runtimeAnimation.currentValue.scale(scale);
+                                }
+                            }
+                            else {
+                                finalValue = runtimeAnimation.currentValue;
+                            }
                         }
                         }
                     }
                     }
                     runtimeAnimation.target[path] = finalValue;
                     runtimeAnimation.target[path] = finalValue;
@@ -25657,6 +25700,18 @@ var BABYLON;
             return index;
             return index;
         };
         };
         /**
         /**
+         * Removes the given effect layer from this scene.
+         * @param toRemove defines the effect layer to remove
+         * @returns the index of the removed effect layer
+         */
+        Scene.prototype.removeEffectLayer = function (toRemove) {
+            var index = this.effectLayers.indexOf(toRemove);
+            if (index !== -1) {
+                this.effectLayers.splice(index, 1);
+            }
+            return index;
+        };
+        /**
          * Removes the given texture from this scene.
          * Removes the given texture from this scene.
          * @param toRemove The texture to remove
          * @param toRemove The texture to remove
          * @returns The index of the removed texture
          * @returns The index of the removed texture
@@ -25765,6 +25820,13 @@ var BABYLON;
             this.lensFlareSystems.push(newLensFlareSystem);
             this.lensFlareSystems.push(newLensFlareSystem);
         };
         };
         /**
         /**
+         * Adds the given effect layer to this scene
+         * @param newEffectLayer defines the effect layer to add
+         */
+        Scene.prototype.addEffectLayer = function (newEffectLayer) {
+            this.effectLayers.push(newEffectLayer);
+        };
+        /**
          * Adds the given action manager to this scene
          * Adds the given action manager to this scene
          * @param newActionManager The action manager to add
          * @param newActionManager The action manager to add
          */
          */
@@ -26844,7 +26906,10 @@ var BABYLON;
                                 action._executeCurrent(BABYLON.ActionEvent.CreateNew(sourceMesh, undefined, otherMesh));
                                 action._executeCurrent(BABYLON.ActionEvent.CreateNew(sourceMesh, undefined, otherMesh));
                             }
                             }
                             //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.
                             //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.
-                            if (!sourceMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnIntersectionExitTrigger) || action.trigger === BABYLON.ActionManager.OnIntersectionExitTrigger) {
+                            if (!sourceMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnIntersectionExitTrigger, function (parameter) {
+                                var parameterMesh = parameter instanceof BABYLON.AbstractMesh ? parameter : parameter.mesh;
+                                return otherMesh === parameterMesh;
+                            }) || action.trigger === BABYLON.ActionManager.OnIntersectionExitTrigger) {
                                 sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);
                                 sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);
                             }
                             }
                         }
                         }
@@ -28253,6 +28318,10 @@ var BABYLON;
              * Textures to keep.
              * Textures to keep.
              */
              */
             this.textures = new Array();
             this.textures = new Array();
+            /**
+             * Effect layers to keep.
+             */
+            this.effectLayers = new Array();
         }
         }
         return KeepAssets;
         return KeepAssets;
     }());
     }());
@@ -28335,6 +28404,10 @@ var BABYLON;
              * Textures populated in the container.
              * Textures populated in the container.
              */
              */
             this.textures = new Array();
             this.textures = new Array();
+            /**
+             * Effect layers populated in the container.
+             */
+            this.effectLayers = new Array();
             this.scene = scene;
             this.scene = scene;
         }
         }
         /**
         /**
@@ -28390,7 +28463,10 @@ var BABYLON;
                 _this.scene.mainSoundTrack.AddSound(o);
                 _this.scene.mainSoundTrack.AddSound(o);
             });
             });
             this.textures.forEach(function (o) {
             this.textures.forEach(function (o) {
-                _this.scene.addTexture;
+                _this.scene.addTexture(o);
+            });
+            this.effectLayers.forEach(function (o) {
+                _this.scene.addEffectLayer(o);
             });
             });
         };
         };
         /**
         /**
@@ -28448,6 +28524,9 @@ var BABYLON;
             this.textures.forEach(function (o) {
             this.textures.forEach(function (o) {
                 _this.scene.removeTexture(o);
                 _this.scene.removeTexture(o);
             });
             });
+            this.effectLayers.forEach(function (o) {
+                _this.scene.removeEffectLayer(o);
+            });
         };
         };
         AssetContainer.prototype._moveAssets = function (sourceAssets, targetAssets, keepAssets) {
         AssetContainer.prototype._moveAssets = function (sourceAssets, targetAssets, keepAssets) {
             for (var _i = 0, sourceAssets_1 = sourceAssets; _i < sourceAssets_1.length; _i++) {
             for (var _i = 0, sourceAssets_1 = sourceAssets; _i < sourceAssets_1.length; _i++) {
@@ -28489,6 +28568,7 @@ var BABYLON;
             this._moveAssets(this.scene.mainSoundTrack.soundCollection, this.sounds, keepAssets.sounds);
             this._moveAssets(this.scene.mainSoundTrack.soundCollection, this.sounds, keepAssets.sounds);
             this._moveAssets(this.scene.transformNodes, this.transformNodes, keepAssets.transformNodes);
             this._moveAssets(this.scene.transformNodes, this.transformNodes, keepAssets.transformNodes);
             this._moveAssets(this.scene.textures, this.textures, keepAssets.textures);
             this._moveAssets(this.scene.textures, this.textures, keepAssets.textures);
+            this._moveAssets(this.scene.effectLayers, this.effectLayers, keepAssets.effectLayers);
             this.removeAllFromScene();
             this.removeAllFromScene();
         };
         };
         return AssetContainer;
         return AssetContainer;
@@ -49879,6 +49959,9 @@ var BABYLON;
             return BABYLON.Color3.Lerp(startValue, endValue, gradient);
             return BABYLON.Color3.Lerp(startValue, endValue, gradient);
         };
         };
         Animation.prototype.matrixInterpolateFunction = function (startValue, endValue, gradient) {
         Animation.prototype.matrixInterpolateFunction = function (startValue, endValue, gradient) {
+            if (Animation.AllowMatrixDecomposeForInterpolation) {
+                return BABYLON.Matrix.DecomposeLerp(startValue, endValue, gradient);
+            }
             return BABYLON.Matrix.Lerp(startValue, endValue, gradient);
             return BABYLON.Matrix.Lerp(startValue, endValue, gradient);
         };
         };
         Animation.prototype.clone = function () {
         Animation.prototype.clone = function () {
@@ -50097,7 +50180,14 @@ var BABYLON;
                 }
                 }
             }
             }
         };
         };
+        /**
+         * Use matrix interpolation instead of using direct key value when animating matrices
+         */
         Animation.AllowMatricesInterpolation = false;
         Animation.AllowMatricesInterpolation = false;
+        /**
+         * When matrix interpolation is enabled, this boolean forces the system to use Matrix.DecomposeLerp instead of Matrix.Lerp. Interpolation is more precise but slower
+         */
+        Animation.AllowMatrixDecomposeForInterpolation = true;
         // Statics
         // Statics
         Animation._ANIMATIONTYPE_FLOAT = 0;
         Animation._ANIMATIONTYPE_FLOAT = 0;
         Animation._ANIMATIONTYPE_VECTOR3 = 1;
         Animation._ANIMATIONTYPE_VECTOR3 = 1;
@@ -50694,7 +50784,22 @@ var BABYLON;
                     }
                     }
                 }
                 }
                 else if (this._originalBlendValue.m) {
                 else if (this._originalBlendValue.m) {
-                    this._currentValue = BABYLON.Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                    if (BABYLON.Animation.AllowMatrixDecomposeForInterpolation) {
+                        if (this._currentValue) {
+                            BABYLON.Matrix.DecomposeLerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
+                        }
+                        else {
+                            this._currentValue = BABYLON.Matrix.DecomposeLerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                        }
+                    }
+                    else {
+                        if (this._currentValue) {
+                            BABYLON.Matrix.LerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
+                        }
+                        else {
+                            this._currentValue = BABYLON.Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                        }
+                    }
                 }
                 }
                 else {
                 else {
                     this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
                     this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
@@ -52105,14 +52210,22 @@ var BABYLON;
         };
         };
         /**
         /**
          * Does this action manager handles actions of a given trigger
          * Does this action manager handles actions of a given trigger
-         * @param {number} trigger - the trigger to be tested
-         * @return {boolean} whether the trigger is handeled
+         * @param trigger defines the trigger to be tested
+         * @param parameterPredicate defines an optional predicate to filter triggers by parameter
+         * @return whether the trigger is handled
          */
          */
-        ActionManager.prototype.hasSpecificTrigger = function (trigger) {
+        ActionManager.prototype.hasSpecificTrigger = function (trigger, parameterPredicate) {
             for (var index = 0; index < this.actions.length; index++) {
             for (var index = 0; index < this.actions.length; index++) {
                 var action = this.actions[index];
                 var action = this.actions[index];
                 if (action.trigger === trigger) {
                 if (action.trigger === trigger) {
-                    return true;
+                    if (parameterPredicate) {
+                        if (parameterPredicate(action.getTriggerParameter())) {
+                            return true;
+                        }
+                    }
+                    else {
+                        return true;
+                    }
                 }
                 }
             }
             }
             return false;
             return false;
@@ -61733,6 +61846,11 @@ var BABYLON;
 
 
 "use strict";
 "use strict";
 
 
+
+
+
+
+
 var BABYLON;
 var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     var CubeTexture = /** @class */ (function (_super) {
     var CubeTexture = /** @class */ (function (_super) {
@@ -61753,6 +61871,7 @@ var BABYLON;
              * It must define where the camera used to render the texture was set
              * It must define where the camera used to render the texture was set
              */
              */
             _this.boundingBoxPosition = BABYLON.Vector3.Zero();
             _this.boundingBoxPosition = BABYLON.Vector3.Zero();
+            _this._rotationY = 0;
             _this.name = rootUrl;
             _this.name = rootUrl;
             _this.url = rootUrl;
             _this.url = rootUrl;
             _this._noMipmap = noMipmap;
             _this._noMipmap = noMipmap;
@@ -61829,6 +61948,23 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        Object.defineProperty(CubeTexture.prototype, "rotationY", {
+            /**
+             * Gets texture matrix rotation angle around Y axis radians.
+             */
+            get: function () {
+                return this._rotationY;
+            },
+            /**
+             * Sets texture matrix rotation angle around Y axis in radians.
+             */
+            set: function (value) {
+                this._rotationY = value;
+                this.setReflectionTextureMatrix(BABYLON.Matrix.RotationY(this._rotationY));
+            },
+            enumerable: true,
+            configurable: true
+        });
         CubeTexture.CreateFromImages = function (files, scene, noMipmap) {
         CubeTexture.CreateFromImages = function (files, scene, noMipmap) {
             var rootUrlKey = "";
             var rootUrlKey = "";
             files.forEach(function (url) { return rootUrlKey += url; });
             files.forEach(function (url) { return rootUrlKey += url; });
@@ -61894,6 +62030,9 @@ var BABYLON;
                 return new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
                 return new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
             }, this);
             }, this);
         };
         };
+        __decorate([
+            BABYLON.serialize("rotationY")
+        ], CubeTexture.prototype, "_rotationY", void 0);
         return CubeTexture;
         return CubeTexture;
     }(BABYLON.BaseTexture));
     }(BABYLON.BaseTexture));
     BABYLON.CubeTexture = CubeTexture;
     BABYLON.CubeTexture = CubeTexture;
@@ -66429,6 +66568,13 @@ var BABYLON;
                     light_2._includedOnlyMeshesIds = [];
                     light_2._includedOnlyMeshesIds = [];
                 }
                 }
             }
             }
+            // Effect layers
+            if (parsedData.effectLayers) {
+                for (index = 0; index < parsedData.effectLayers.length; index++) {
+                    var effectLayer = BABYLON.EffectLayer.Parse(parsedData.effectLayers[index], scene, rootUrl);
+                    container.effectLayers.push(effectLayer);
+                }
+            }
             // Actions (scene)
             // Actions (scene)
             if (parsedData.actions !== undefined && parsedData.actions !== null) {
             if (parsedData.actions !== undefined && parsedData.actions !== null) {
                 BABYLON.ActionManager.Parse(parsedData.actions, null, scene);
                 BABYLON.ActionManager.Parse(parsedData.actions, null, scene);
@@ -73892,7 +74038,7 @@ var BABYLON;
                 return this._circleOfConfusion.focalLength;
                 return this._circleOfConfusion.focalLength;
             },
             },
             /**
             /**
-             * The focal the length of the camera used in the effect
+             * The focal the length of the camera used in the effect in scene units/1000 (eg. millimeter)
              */
              */
             set: function (value) {
             set: function (value) {
                 this._circleOfConfusion.focalLength = value;
                 this._circleOfConfusion.focalLength = value;
@@ -78768,6 +78914,7 @@ var BABYLON;
              */
              */
             _this.isPMREM = false;
             _this.isPMREM = false;
             _this._isBlocking = true;
             _this._isBlocking = true;
+            _this._rotationY = 0;
             /**
             /**
              * Gets or sets the center of the bounding box associated with the cube texture
              * Gets or sets the center of the bounding box associated with the cube texture
              * It must define where the camera used to render the texture was set
              * It must define where the camera used to render the texture was set
@@ -78830,6 +78977,23 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        Object.defineProperty(HDRCubeTexture.prototype, "rotationY", {
+            /**
+             * Gets texture matrix rotation angle around Y axis radians.
+             */
+            get: function () {
+                return this._rotationY;
+            },
+            /**
+             * Sets texture matrix rotation angle around Y axis in radians.
+             */
+            set: function (value) {
+                this._rotationY = value;
+                this.setReflectionTextureMatrix(BABYLON.Matrix.RotationY(this._rotationY));
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(HDRCubeTexture.prototype, "boundingBoxSize", {
         Object.defineProperty(HDRCubeTexture.prototype, "boundingBoxSize", {
             get: function () {
             get: function () {
                 return this._boundingBoxSize;
                 return this._boundingBoxSize;
@@ -79123,6 +79287,9 @@ var BABYLON;
                 if (parsedTexture.boundingBoxSize) {
                 if (parsedTexture.boundingBoxSize) {
                     texture.boundingBoxSize = BABYLON.Vector3.FromArray(parsedTexture.boundingBoxSize);
                     texture.boundingBoxSize = BABYLON.Vector3.FromArray(parsedTexture.boundingBoxSize);
                 }
                 }
+                if (parsedTexture.rotationY) {
+                    texture.rotationY = parsedTexture.rotationY;
+                }
             }
             }
             return texture;
             return texture;
         };
         };
@@ -79144,6 +79311,7 @@ var BABYLON;
             serializationObject.customType = "BABYLON.HDRCubeTexture";
             serializationObject.customType = "BABYLON.HDRCubeTexture";
             serializationObject.noMipmap = this._noMipmap;
             serializationObject.noMipmap = this._noMipmap;
             serializationObject.isBlocking = this._isBlocking;
             serializationObject.isBlocking = this._isBlocking;
+            serializationObject.rotationY = this._rotationY;
             return serializationObject;
             return serializationObject;
         };
         };
         /**
         /**
@@ -90153,6 +90321,17 @@ var BABYLON;
         EffectLayer.prototype.getClassName = function () {
         EffectLayer.prototype.getClassName = function () {
             return "EffectLayer";
             return "EffectLayer";
         };
         };
+        /**
+         * Creates an effect layer from parsed effect layer data
+         * @param parsedEffectLayer defines effect layer data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing the effect layer information
+         * @returns a parsed effect Layer
+         */
+        EffectLayer.Parse = function (parsedEffectLayer, scene, rootUrl) {
+            var effectLayerType = BABYLON.Tools.Instantiate(parsedEffectLayer.customType);
+            return effectLayerType.Parse(parsedEffectLayer, scene, rootUrl);
+        };
         __decorate([
         __decorate([
             BABYLON.serialize()
             BABYLON.serialize()
         ], EffectLayer.prototype, "name", void 0);
         ], EffectLayer.prototype, "name", void 0);
@@ -90640,6 +90819,73 @@ var BABYLON;
             _super.prototype.dispose.call(this);
             _super.prototype.dispose.call(this);
         };
         };
         /**
         /**
+          * Gets the class name of the effect layer
+          * @returns the string with the class name of the effect layer
+          */
+        HighlightLayer.prototype.getClassName = function () {
+            return "HighlightLayer";
+        };
+        /**
+         * Serializes this Highlight layer
+         * @returns a serialized Highlight layer object
+         */
+        HighlightLayer.prototype.serialize = function () {
+            var serializationObject = BABYLON.SerializationHelper.Serialize(this);
+            serializationObject.customType = "BABYLON.HighlightLayer";
+            // Highlighted meshes
+            serializationObject.meshes = [];
+            if (this._meshes) {
+                for (var m in this._meshes) {
+                    var mesh = this._meshes[m];
+                    if (mesh) {
+                        serializationObject.meshes.push({
+                            glowEmissiveOnly: mesh.glowEmissiveOnly,
+                            color: mesh.color.asArray(),
+                            meshId: mesh.mesh.id
+                        });
+                    }
+                }
+            }
+            // Excluded meshes
+            serializationObject.excludedMeshes = [];
+            if (this._excludedMeshes) {
+                for (var e in this._excludedMeshes) {
+                    var excludedMesh = this._excludedMeshes[e];
+                    if (excludedMesh) {
+                        serializationObject.excludedMeshes.push(excludedMesh.mesh.id);
+                    }
+                }
+            }
+            return serializationObject;
+        };
+        /**
+         * Creates a Highlight layer from parsed Highlight layer data
+         * @param parsedHightlightLayer defines the Highlight layer data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing the Highlight layer information
+         * @returns a parsed Highlight layer
+         */
+        HighlightLayer.Parse = function (parsedHightlightLayer, scene, rootUrl) {
+            var hl = BABYLON.SerializationHelper.Parse(function () { return new HighlightLayer(parsedHightlightLayer.name, scene, parsedHightlightLayer.options); }, parsedHightlightLayer, scene, rootUrl);
+            var index;
+            // Excluded meshes
+            for (index = 0; index < parsedHightlightLayer.excludedMeshes.length; index++) {
+                var mesh = scene.getMeshByID(parsedHightlightLayer.excludedMeshes[index]);
+                if (mesh) {
+                    hl.addExcludedMesh(mesh);
+                }
+            }
+            // Included meshes
+            for (index = 0; index < parsedHightlightLayer.meshes.length; index++) {
+                var highlightedMesh = parsedHightlightLayer.meshes[index];
+                var mesh = scene.getMeshByID(highlightedMesh.meshId);
+                if (mesh) {
+                    hl.addMesh(mesh, BABYLON.Color3.FromArray(highlightedMesh.color), highlightedMesh.glowEmissiveOnly);
+                }
+            }
+            return hl;
+        };
+        /**
          * Effect Name of the highlight layer.
          * Effect Name of the highlight layer.
          */
          */
         HighlightLayer.EffectName = "HighlightLayer";
         HighlightLayer.EffectName = "HighlightLayer";
@@ -90656,6 +90902,21 @@ var BABYLON;
          * Stencil value used for the other meshes in the scene.
          * Stencil value used for the other meshes in the scene.
          */
          */
         HighlightLayer.NormalMeshStencilReference = 0x01;
         HighlightLayer.NormalMeshStencilReference = 0x01;
+        __decorate([
+            BABYLON.serialize()
+        ], HighlightLayer.prototype, "innerGlow", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], HighlightLayer.prototype, "outerGlow", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], HighlightLayer.prototype, "blurHorizontalSize", null);
+        __decorate([
+            BABYLON.serialize()
+        ], HighlightLayer.prototype, "blurVerticalSize", null);
+        __decorate([
+            BABYLON.serialize("options")
+        ], HighlightLayer.prototype, "_options", void 0);
         return HighlightLayer;
         return HighlightLayer;
     }(BABYLON.EffectLayer));
     }(BABYLON.EffectLayer));
     BABYLON.HighlightLayer = HighlightLayer;
     BABYLON.HighlightLayer = HighlightLayer;
@@ -90992,6 +91253,7 @@ var BABYLON;
          */
          */
         GlowLayer.prototype.serialize = function () {
         GlowLayer.prototype.serialize = function () {
             var serializationObject = BABYLON.SerializationHelper.Serialize(this);
             var serializationObject = BABYLON.SerializationHelper.Serialize(this);
+            serializationObject.customType = "BABYLON.GlowLayer";
             var index;
             var index;
             // Included meshes
             // Included meshes
             serializationObject.includedMeshes = [];
             serializationObject.includedMeshes = [];
@@ -91060,7 +91322,7 @@ var BABYLON;
             BABYLON.serialize()
             BABYLON.serialize()
         ], GlowLayer.prototype, "intensity", null);
         ], GlowLayer.prototype, "intensity", null);
         __decorate([
         __decorate([
-            BABYLON.serialize('options')
+            BABYLON.serialize("options")
         ], GlowLayer.prototype, "_options", void 0);
         ], GlowLayer.prototype, "_options", void 0);
         return GlowLayer;
         return GlowLayer;
     }(BABYLON.EffectLayer));
     }(BABYLON.EffectLayer));
@@ -92113,6 +92375,14 @@ var BABYLON;
                     serializationObject.sounds.push(soundtrack.soundCollection[soundId].serialize());
                     serializationObject.sounds.push(soundtrack.soundCollection[soundId].serialize());
                 }
                 }
             }
             }
+            // Effect layers
+            serializationObject.effectLayers = [];
+            for (index = 0; index < scene.effectLayers.length; index++) {
+                var layer = scene.effectLayers[index];
+                if (layer.serialize) {
+                    serializationObject.effectLayers.push(layer.serialize());
+                }
+            }
             return serializationObject;
             return serializationObject;
         };
         };
         SceneSerializer.SerializeMesh = function (toSerialize /* Mesh || Mesh[] */, withParents, withChildren) {
         SceneSerializer.SerializeMesh = function (toSerialize /* Mesh || Mesh[] */, withParents, withChildren) {

+ 167 - 40
dist/preview release/babylon.no-module.max.js

@@ -4691,7 +4691,6 @@ var BABYLON;
         Quaternion.SlerpToRef = function (left, right, amount, result) {
         Quaternion.SlerpToRef = function (left, right, amount, result) {
             var num2;
             var num2;
             var num3;
             var num3;
-            var num = amount;
             var num4 = (((left.x * right.x) + (left.y * right.y)) + (left.z * right.z)) + (left.w * right.w);
             var num4 = (((left.x * right.x) + (left.y * right.y)) + (left.z * right.z)) + (left.w * right.w);
             var flag = false;
             var flag = false;
             if (num4 < 0) {
             if (num4 < 0) {
@@ -4699,14 +4698,14 @@ var BABYLON;
                 num4 = -num4;
                 num4 = -num4;
             }
             }
             if (num4 > 0.999999) {
             if (num4 > 0.999999) {
-                num3 = 1 - num;
-                num2 = flag ? -num : num;
+                num3 = 1 - amount;
+                num2 = flag ? -amount : amount;
             }
             }
             else {
             else {
                 var num5 = Math.acos(num4);
                 var num5 = Math.acos(num4);
                 var num6 = (1.0 / Math.sin(num5));
                 var num6 = (1.0 / Math.sin(num5));
-                num3 = (Math.sin((1.0 - num) * num5)) * num6;
-                num2 = flag ? ((-Math.sin(num * num5)) * num6) : ((Math.sin(num * num5)) * num6);
+                num3 = (Math.sin((1.0 - amount) * num5)) * num6;
+                num2 = flag ? ((-Math.sin(amount * num5)) * num6) : ((Math.sin(amount * num5)) * num6);
             }
             }
             result.x = (num3 * left.x) + (num2 * right.x);
             result.x = (num3 * left.x) + (num2 * right.x);
             result.y = (num3 * left.y) + (num2 * right.y);
             result.y = (num3 * left.y) + (num2 * right.y);
@@ -5132,24 +5131,28 @@ var BABYLON;
          * @returns true if operation was successful
          * @returns true if operation was successful
          */
          */
         Matrix.prototype.decompose = function (scale, rotation, translation) {
         Matrix.prototype.decompose = function (scale, rotation, translation) {
-            translation.x = this.m[12];
-            translation.y = this.m[13];
-            translation.z = this.m[14];
+            if (translation) {
+                translation.x = this.m[12];
+                translation.y = this.m[13];
+                translation.z = this.m[14];
+            }
             scale.x = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1] + this.m[2] * this.m[2]);
             scale.x = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1] + this.m[2] * this.m[2]);
             scale.y = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5] + this.m[6] * this.m[6]);
             scale.y = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5] + this.m[6] * this.m[6]);
             scale.z = Math.sqrt(this.m[8] * this.m[8] + this.m[9] * this.m[9] + this.m[10] * this.m[10]);
             scale.z = Math.sqrt(this.m[8] * this.m[8] + this.m[9] * this.m[9] + this.m[10] * this.m[10]);
             if (this.determinant() <= 0) {
             if (this.determinant() <= 0) {
                 scale.y *= -1;
                 scale.y *= -1;
             }
             }
-            if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
-                rotation.x = 0;
-                rotation.y = 0;
-                rotation.z = 0;
-                rotation.w = 1;
-                return false;
+            if (rotation) {
+                if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+                    rotation.x = 0;
+                    rotation.y = 0;
+                    rotation.z = 0;
+                    rotation.w = 1;
+                    return false;
+                }
+                Matrix.FromValuesToRef(this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0, this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0, this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0, 0, 0, 0, 1, MathTmp.Matrix[0]);
+                Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
             }
             }
-            Matrix.FromValuesToRef(this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0, this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0, this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0, 0, 0, 0, 1, MathTmp.Matrix[0]);
-            Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
             return true;
             return true;
         };
         };
         /**
         /**
@@ -5739,18 +5742,36 @@ var BABYLON;
          * @returns the new matrix
          * @returns the new matrix
          */
          */
         Matrix.DecomposeLerp = function (startValue, endValue, gradient) {
         Matrix.DecomposeLerp = function (startValue, endValue, gradient) {
-            var startScale = new Vector3(0, 0, 0);
-            var startRotation = new Quaternion();
-            var startTranslation = new Vector3(0, 0, 0);
+            var result = Matrix.Zero();
+            Matrix.DecomposeLerpToRef(startValue, endValue, gradient, result);
+            return result;
+        };
+        /**
+         * Update a matrix to values which are computed by:
+         * * decomposing the the "startValue" and "endValue" matrices into their respective scale, rotation and translation matrices
+         * * interpolating for "gradient" (float) the values between each of these decomposed matrices between the start and the end
+         * * recomposing a new matrix from these 3 interpolated scale, rotation and translation matrices
+         * @param startValue defines the first matrix
+         * @param endValue defines the second matrix
+         * @param gradient defines the gradient between the two matrices
+         * @param result defines the target matrix
+         */
+        Matrix.DecomposeLerpToRef = function (startValue, endValue, gradient, result) {
+            var startScale = MathTmp.Vector3[0];
+            var startRotation = MathTmp.Quaternion[0];
+            var startTranslation = MathTmp.Vector3[1];
             startValue.decompose(startScale, startRotation, startTranslation);
             startValue.decompose(startScale, startRotation, startTranslation);
-            var endScale = new Vector3(0, 0, 0);
-            var endRotation = new Quaternion();
-            var endTranslation = new Vector3(0, 0, 0);
+            var endScale = MathTmp.Vector3[2];
+            var endRotation = MathTmp.Quaternion[1];
+            var endTranslation = MathTmp.Vector3[3];
             endValue.decompose(endScale, endRotation, endTranslation);
             endValue.decompose(endScale, endRotation, endTranslation);
-            var resultScale = Vector3.Lerp(startScale, endScale, gradient);
-            var resultRotation = Quaternion.Slerp(startRotation, endRotation, gradient);
-            var resultTranslation = Vector3.Lerp(startTranslation, endTranslation, gradient);
-            return Matrix.Compose(resultScale, resultRotation, resultTranslation);
+            var resultScale = MathTmp.Vector3[4];
+            Vector3.LerpToRef(startScale, endScale, gradient, resultScale);
+            var resultRotation = MathTmp.Quaternion[2];
+            Quaternion.SlerpToRef(startRotation, endRotation, gradient, resultRotation);
+            var resultTranslation = MathTmp.Vector3[5];
+            Vector3.LerpToRef(startTranslation, endTranslation, gradient, resultTranslation);
+            Matrix.ComposeToRef(resultScale, resultRotation, resultTranslation, result);
         };
         };
         /**
         /**
          * Gets a new rotation matrix used to rotate an entity so as it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up"
          * Gets a new rotation matrix used to rotate an entity so as it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up"
@@ -7072,9 +7093,9 @@ var BABYLON;
     var MathTmp = /** @class */ (function () {
     var MathTmp = /** @class */ (function () {
         function MathTmp() {
         function MathTmp() {
         }
         }
-        MathTmp.Vector3 = [Vector3.Zero()];
+        MathTmp.Vector3 = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
         MathTmp.Matrix = [Matrix.Zero(), Matrix.Zero()];
         MathTmp.Matrix = [Matrix.Zero(), Matrix.Zero()];
-        MathTmp.Quaternion = [Quaternion.Zero()];
+        MathTmp.Quaternion = [Quaternion.Zero(), Quaternion.Zero(), Quaternion.Zero()];
         return MathTmp;
         return MathTmp;
     }());
     }());
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
@@ -25289,16 +25310,22 @@ var BABYLON;
                 var target = this._registeredForLateAnimationBindings.data[index];
                 var target = this._registeredForLateAnimationBindings.data[index];
                 for (var path in target._lateAnimationHolders) {
                 for (var path in target._lateAnimationHolders) {
                     var holder = target._lateAnimationHolders[path];
                     var holder = target._lateAnimationHolders[path];
+                    var originalValue = holder.animations[0].originalValue;
                     // Sanity check
                     // Sanity check
-                    if (!holder.animations[0].originalValue.scaleAndAddToRef) {
+                    if (!originalValue.scaleAndAddToRef) {
                         continue;
                         continue;
                     }
                     }
+                    var matrixDecomposeMode = BABYLON.Animation.AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix
                     var normalizer = 1.0;
                     var normalizer = 1.0;
                     var finalValue = void 0;
                     var finalValue = void 0;
                     if (holder.totalWeight < 1.0) {
                     if (holder.totalWeight < 1.0) {
-                        // We need to mix the original value in
-                        var originalValue = holder.animations[0].originalValue;
-                        finalValue = originalValue.scale(1.0 - holder.totalWeight);
+                        // We need to mix the original value in     
+                        if (matrixDecomposeMode) {
+                            finalValue = originalValue.clone();
+                        }
+                        else {
+                            finalValue = originalValue.scale(1.0 - holder.totalWeight);
+                        }
                     }
                     }
                     else {
                     else {
                         // We need to normalize the weights
                         // We need to normalize the weights
@@ -25306,11 +25333,27 @@ var BABYLON;
                     }
                     }
                     for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
                     for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
                         var runtimeAnimation = holder.animations[animIndex];
                         var runtimeAnimation = holder.animations[animIndex];
+                        var scale = runtimeAnimation.weight / normalizer;
                         if (finalValue) {
                         if (finalValue) {
-                            runtimeAnimation.currentValue.scaleAndAddToRef(runtimeAnimation.weight / normalizer, finalValue);
+                            if (matrixDecomposeMode) {
+                                BABYLON.Matrix.DecomposeLerpToRef(finalValue, runtimeAnimation.currentValue, scale, finalValue);
+                            }
+                            else {
+                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                            }
                         }
                         }
                         else {
                         else {
-                            finalValue = runtimeAnimation.currentValue.scale(runtimeAnimation.weight / normalizer);
+                            if (scale !== 1) {
+                                if (matrixDecomposeMode) {
+                                    finalValue = runtimeAnimation.currentValue.clone();
+                                }
+                                else {
+                                    finalValue = runtimeAnimation.currentValue.scale(scale);
+                                }
+                            }
+                            else {
+                                finalValue = runtimeAnimation.currentValue;
+                            }
                         }
                         }
                     }
                     }
                     runtimeAnimation.target[path] = finalValue;
                     runtimeAnimation.target[path] = finalValue;
@@ -26830,7 +26873,10 @@ var BABYLON;
                                 action._executeCurrent(BABYLON.ActionEvent.CreateNew(sourceMesh, undefined, otherMesh));
                                 action._executeCurrent(BABYLON.ActionEvent.CreateNew(sourceMesh, undefined, otherMesh));
                             }
                             }
                             //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.
                             //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.
-                            if (!sourceMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnIntersectionExitTrigger) || action.trigger === BABYLON.ActionManager.OnIntersectionExitTrigger) {
+                            if (!sourceMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnIntersectionExitTrigger, function (parameter) {
+                                var parameterMesh = parameter instanceof BABYLON.AbstractMesh ? parameter : parameter.mesh;
+                                return otherMesh === parameterMesh;
+                            }) || action.trigger === BABYLON.ActionManager.OnIntersectionExitTrigger) {
                                 sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);
                                 sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);
                             }
                             }
                         }
                         }
@@ -49880,6 +49926,9 @@ var BABYLON;
             return BABYLON.Color3.Lerp(startValue, endValue, gradient);
             return BABYLON.Color3.Lerp(startValue, endValue, gradient);
         };
         };
         Animation.prototype.matrixInterpolateFunction = function (startValue, endValue, gradient) {
         Animation.prototype.matrixInterpolateFunction = function (startValue, endValue, gradient) {
+            if (Animation.AllowMatrixDecomposeForInterpolation) {
+                return BABYLON.Matrix.DecomposeLerp(startValue, endValue, gradient);
+            }
             return BABYLON.Matrix.Lerp(startValue, endValue, gradient);
             return BABYLON.Matrix.Lerp(startValue, endValue, gradient);
         };
         };
         Animation.prototype.clone = function () {
         Animation.prototype.clone = function () {
@@ -50098,7 +50147,14 @@ var BABYLON;
                 }
                 }
             }
             }
         };
         };
+        /**
+         * Use matrix interpolation instead of using direct key value when animating matrices
+         */
         Animation.AllowMatricesInterpolation = false;
         Animation.AllowMatricesInterpolation = false;
+        /**
+         * When matrix interpolation is enabled, this boolean forces the system to use Matrix.DecomposeLerp instead of Matrix.Lerp. Interpolation is more precise but slower
+         */
+        Animation.AllowMatrixDecomposeForInterpolation = true;
         // Statics
         // Statics
         Animation._ANIMATIONTYPE_FLOAT = 0;
         Animation._ANIMATIONTYPE_FLOAT = 0;
         Animation._ANIMATIONTYPE_VECTOR3 = 1;
         Animation._ANIMATIONTYPE_VECTOR3 = 1;
@@ -50695,7 +50751,22 @@ var BABYLON;
                     }
                     }
                 }
                 }
                 else if (this._originalBlendValue.m) {
                 else if (this._originalBlendValue.m) {
-                    this._currentValue = BABYLON.Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                    if (BABYLON.Animation.AllowMatrixDecomposeForInterpolation) {
+                        if (this._currentValue) {
+                            BABYLON.Matrix.DecomposeLerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
+                        }
+                        else {
+                            this._currentValue = BABYLON.Matrix.DecomposeLerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                        }
+                    }
+                    else {
+                        if (this._currentValue) {
+                            BABYLON.Matrix.LerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
+                        }
+                        else {
+                            this._currentValue = BABYLON.Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                        }
+                    }
                 }
                 }
                 else {
                 else {
                     this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
                     this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
@@ -52106,14 +52177,22 @@ var BABYLON;
         };
         };
         /**
         /**
          * Does this action manager handles actions of a given trigger
          * Does this action manager handles actions of a given trigger
-         * @param {number} trigger - the trigger to be tested
-         * @return {boolean} whether the trigger is handeled
+         * @param trigger defines the trigger to be tested
+         * @param parameterPredicate defines an optional predicate to filter triggers by parameter
+         * @return whether the trigger is handled
          */
          */
-        ActionManager.prototype.hasSpecificTrigger = function (trigger) {
+        ActionManager.prototype.hasSpecificTrigger = function (trigger, parameterPredicate) {
             for (var index = 0; index < this.actions.length; index++) {
             for (var index = 0; index < this.actions.length; index++) {
                 var action = this.actions[index];
                 var action = this.actions[index];
                 if (action.trigger === trigger) {
                 if (action.trigger === trigger) {
-                    return true;
+                    if (parameterPredicate) {
+                        if (parameterPredicate(action.getTriggerParameter())) {
+                            return true;
+                        }
+                    }
+                    else {
+                        return true;
+                    }
                 }
                 }
             }
             }
             return false;
             return false;
@@ -61734,6 +61813,11 @@ var BABYLON;
 
 
 "use strict";
 "use strict";
 
 
+
+
+
+
+
 var BABYLON;
 var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     var CubeTexture = /** @class */ (function (_super) {
     var CubeTexture = /** @class */ (function (_super) {
@@ -61754,6 +61838,7 @@ var BABYLON;
              * It must define where the camera used to render the texture was set
              * It must define where the camera used to render the texture was set
              */
              */
             _this.boundingBoxPosition = BABYLON.Vector3.Zero();
             _this.boundingBoxPosition = BABYLON.Vector3.Zero();
+            _this._rotationY = 0;
             _this.name = rootUrl;
             _this.name = rootUrl;
             _this.url = rootUrl;
             _this.url = rootUrl;
             _this._noMipmap = noMipmap;
             _this._noMipmap = noMipmap;
@@ -61830,6 +61915,23 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        Object.defineProperty(CubeTexture.prototype, "rotationY", {
+            /**
+             * Gets texture matrix rotation angle around Y axis radians.
+             */
+            get: function () {
+                return this._rotationY;
+            },
+            /**
+             * Sets texture matrix rotation angle around Y axis in radians.
+             */
+            set: function (value) {
+                this._rotationY = value;
+                this.setReflectionTextureMatrix(BABYLON.Matrix.RotationY(this._rotationY));
+            },
+            enumerable: true,
+            configurable: true
+        });
         CubeTexture.CreateFromImages = function (files, scene, noMipmap) {
         CubeTexture.CreateFromImages = function (files, scene, noMipmap) {
             var rootUrlKey = "";
             var rootUrlKey = "";
             files.forEach(function (url) { return rootUrlKey += url; });
             files.forEach(function (url) { return rootUrlKey += url; });
@@ -61895,6 +61997,9 @@ var BABYLON;
                 return new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
                 return new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
             }, this);
             }, this);
         };
         };
+        __decorate([
+            BABYLON.serialize("rotationY")
+        ], CubeTexture.prototype, "_rotationY", void 0);
         return CubeTexture;
         return CubeTexture;
     }(BABYLON.BaseTexture));
     }(BABYLON.BaseTexture));
     BABYLON.CubeTexture = CubeTexture;
     BABYLON.CubeTexture = CubeTexture;
@@ -78776,6 +78881,7 @@ var BABYLON;
              */
              */
             _this.isPMREM = false;
             _this.isPMREM = false;
             _this._isBlocking = true;
             _this._isBlocking = true;
+            _this._rotationY = 0;
             /**
             /**
              * Gets or sets the center of the bounding box associated with the cube texture
              * Gets or sets the center of the bounding box associated with the cube texture
              * It must define where the camera used to render the texture was set
              * It must define where the camera used to render the texture was set
@@ -78838,6 +78944,23 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        Object.defineProperty(HDRCubeTexture.prototype, "rotationY", {
+            /**
+             * Gets texture matrix rotation angle around Y axis radians.
+             */
+            get: function () {
+                return this._rotationY;
+            },
+            /**
+             * Sets texture matrix rotation angle around Y axis in radians.
+             */
+            set: function (value) {
+                this._rotationY = value;
+                this.setReflectionTextureMatrix(BABYLON.Matrix.RotationY(this._rotationY));
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(HDRCubeTexture.prototype, "boundingBoxSize", {
         Object.defineProperty(HDRCubeTexture.prototype, "boundingBoxSize", {
             get: function () {
             get: function () {
                 return this._boundingBoxSize;
                 return this._boundingBoxSize;
@@ -79131,6 +79254,9 @@ var BABYLON;
                 if (parsedTexture.boundingBoxSize) {
                 if (parsedTexture.boundingBoxSize) {
                     texture.boundingBoxSize = BABYLON.Vector3.FromArray(parsedTexture.boundingBoxSize);
                     texture.boundingBoxSize = BABYLON.Vector3.FromArray(parsedTexture.boundingBoxSize);
                 }
                 }
+                if (parsedTexture.rotationY) {
+                    texture.rotationY = parsedTexture.rotationY;
+                }
             }
             }
             return texture;
             return texture;
         };
         };
@@ -79152,6 +79278,7 @@ var BABYLON;
             serializationObject.customType = "BABYLON.HDRCubeTexture";
             serializationObject.customType = "BABYLON.HDRCubeTexture";
             serializationObject.noMipmap = this._noMipmap;
             serializationObject.noMipmap = this._noMipmap;
             serializationObject.isBlocking = this._isBlocking;
             serializationObject.isBlocking = this._isBlocking;
+            serializationObject.rotationY = this._rotationY;
             return serializationObject;
             return serializationObject;
         };
         };
         /**
         /**

File diff suppressed because it is too large
+ 53 - 53
dist/preview release/babylon.worker.js


+ 313 - 43
dist/preview release/es6.js

@@ -4691,7 +4691,6 @@ var BABYLON;
         Quaternion.SlerpToRef = function (left, right, amount, result) {
         Quaternion.SlerpToRef = function (left, right, amount, result) {
             var num2;
             var num2;
             var num3;
             var num3;
-            var num = amount;
             var num4 = (((left.x * right.x) + (left.y * right.y)) + (left.z * right.z)) + (left.w * right.w);
             var num4 = (((left.x * right.x) + (left.y * right.y)) + (left.z * right.z)) + (left.w * right.w);
             var flag = false;
             var flag = false;
             if (num4 < 0) {
             if (num4 < 0) {
@@ -4699,14 +4698,14 @@ var BABYLON;
                 num4 = -num4;
                 num4 = -num4;
             }
             }
             if (num4 > 0.999999) {
             if (num4 > 0.999999) {
-                num3 = 1 - num;
-                num2 = flag ? -num : num;
+                num3 = 1 - amount;
+                num2 = flag ? -amount : amount;
             }
             }
             else {
             else {
                 var num5 = Math.acos(num4);
                 var num5 = Math.acos(num4);
                 var num6 = (1.0 / Math.sin(num5));
                 var num6 = (1.0 / Math.sin(num5));
-                num3 = (Math.sin((1.0 - num) * num5)) * num6;
-                num2 = flag ? ((-Math.sin(num * num5)) * num6) : ((Math.sin(num * num5)) * num6);
+                num3 = (Math.sin((1.0 - amount) * num5)) * num6;
+                num2 = flag ? ((-Math.sin(amount * num5)) * num6) : ((Math.sin(amount * num5)) * num6);
             }
             }
             result.x = (num3 * left.x) + (num2 * right.x);
             result.x = (num3 * left.x) + (num2 * right.x);
             result.y = (num3 * left.y) + (num2 * right.y);
             result.y = (num3 * left.y) + (num2 * right.y);
@@ -5132,24 +5131,28 @@ var BABYLON;
          * @returns true if operation was successful
          * @returns true if operation was successful
          */
          */
         Matrix.prototype.decompose = function (scale, rotation, translation) {
         Matrix.prototype.decompose = function (scale, rotation, translation) {
-            translation.x = this.m[12];
-            translation.y = this.m[13];
-            translation.z = this.m[14];
+            if (translation) {
+                translation.x = this.m[12];
+                translation.y = this.m[13];
+                translation.z = this.m[14];
+            }
             scale.x = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1] + this.m[2] * this.m[2]);
             scale.x = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1] + this.m[2] * this.m[2]);
             scale.y = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5] + this.m[6] * this.m[6]);
             scale.y = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5] + this.m[6] * this.m[6]);
             scale.z = Math.sqrt(this.m[8] * this.m[8] + this.m[9] * this.m[9] + this.m[10] * this.m[10]);
             scale.z = Math.sqrt(this.m[8] * this.m[8] + this.m[9] * this.m[9] + this.m[10] * this.m[10]);
             if (this.determinant() <= 0) {
             if (this.determinant() <= 0) {
                 scale.y *= -1;
                 scale.y *= -1;
             }
             }
-            if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
-                rotation.x = 0;
-                rotation.y = 0;
-                rotation.z = 0;
-                rotation.w = 1;
-                return false;
+            if (rotation) {
+                if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+                    rotation.x = 0;
+                    rotation.y = 0;
+                    rotation.z = 0;
+                    rotation.w = 1;
+                    return false;
+                }
+                Matrix.FromValuesToRef(this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0, this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0, this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0, 0, 0, 0, 1, MathTmp.Matrix[0]);
+                Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
             }
             }
-            Matrix.FromValuesToRef(this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0, this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0, this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0, 0, 0, 0, 1, MathTmp.Matrix[0]);
-            Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
             return true;
             return true;
         };
         };
         /**
         /**
@@ -5739,18 +5742,36 @@ var BABYLON;
          * @returns the new matrix
          * @returns the new matrix
          */
          */
         Matrix.DecomposeLerp = function (startValue, endValue, gradient) {
         Matrix.DecomposeLerp = function (startValue, endValue, gradient) {
-            var startScale = new Vector3(0, 0, 0);
-            var startRotation = new Quaternion();
-            var startTranslation = new Vector3(0, 0, 0);
+            var result = Matrix.Zero();
+            Matrix.DecomposeLerpToRef(startValue, endValue, gradient, result);
+            return result;
+        };
+        /**
+         * Update a matrix to values which are computed by:
+         * * decomposing the the "startValue" and "endValue" matrices into their respective scale, rotation and translation matrices
+         * * interpolating for "gradient" (float) the values between each of these decomposed matrices between the start and the end
+         * * recomposing a new matrix from these 3 interpolated scale, rotation and translation matrices
+         * @param startValue defines the first matrix
+         * @param endValue defines the second matrix
+         * @param gradient defines the gradient between the two matrices
+         * @param result defines the target matrix
+         */
+        Matrix.DecomposeLerpToRef = function (startValue, endValue, gradient, result) {
+            var startScale = MathTmp.Vector3[0];
+            var startRotation = MathTmp.Quaternion[0];
+            var startTranslation = MathTmp.Vector3[1];
             startValue.decompose(startScale, startRotation, startTranslation);
             startValue.decompose(startScale, startRotation, startTranslation);
-            var endScale = new Vector3(0, 0, 0);
-            var endRotation = new Quaternion();
-            var endTranslation = new Vector3(0, 0, 0);
+            var endScale = MathTmp.Vector3[2];
+            var endRotation = MathTmp.Quaternion[1];
+            var endTranslation = MathTmp.Vector3[3];
             endValue.decompose(endScale, endRotation, endTranslation);
             endValue.decompose(endScale, endRotation, endTranslation);
-            var resultScale = Vector3.Lerp(startScale, endScale, gradient);
-            var resultRotation = Quaternion.Slerp(startRotation, endRotation, gradient);
-            var resultTranslation = Vector3.Lerp(startTranslation, endTranslation, gradient);
-            return Matrix.Compose(resultScale, resultRotation, resultTranslation);
+            var resultScale = MathTmp.Vector3[4];
+            Vector3.LerpToRef(startScale, endScale, gradient, resultScale);
+            var resultRotation = MathTmp.Quaternion[2];
+            Quaternion.SlerpToRef(startRotation, endRotation, gradient, resultRotation);
+            var resultTranslation = MathTmp.Vector3[5];
+            Vector3.LerpToRef(startTranslation, endTranslation, gradient, resultTranslation);
+            Matrix.ComposeToRef(resultScale, resultRotation, resultTranslation, result);
         };
         };
         /**
         /**
          * Gets a new rotation matrix used to rotate an entity so as it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up"
          * Gets a new rotation matrix used to rotate an entity so as it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up"
@@ -7072,9 +7093,9 @@ var BABYLON;
     var MathTmp = /** @class */ (function () {
     var MathTmp = /** @class */ (function () {
         function MathTmp() {
         function MathTmp() {
         }
         }
-        MathTmp.Vector3 = [Vector3.Zero()];
+        MathTmp.Vector3 = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
         MathTmp.Matrix = [Matrix.Zero(), Matrix.Zero()];
         MathTmp.Matrix = [Matrix.Zero(), Matrix.Zero()];
-        MathTmp.Quaternion = [Quaternion.Zero()];
+        MathTmp.Quaternion = [Quaternion.Zero(), Quaternion.Zero(), Quaternion.Zero()];
         return MathTmp;
         return MathTmp;
     }());
     }());
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
@@ -25289,16 +25310,22 @@ var BABYLON;
                 var target = this._registeredForLateAnimationBindings.data[index];
                 var target = this._registeredForLateAnimationBindings.data[index];
                 for (var path in target._lateAnimationHolders) {
                 for (var path in target._lateAnimationHolders) {
                     var holder = target._lateAnimationHolders[path];
                     var holder = target._lateAnimationHolders[path];
+                    var originalValue = holder.animations[0].originalValue;
                     // Sanity check
                     // Sanity check
-                    if (!holder.animations[0].originalValue.scaleAndAddToRef) {
+                    if (!originalValue.scaleAndAddToRef) {
                         continue;
                         continue;
                     }
                     }
+                    var matrixDecomposeMode = BABYLON.Animation.AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix
                     var normalizer = 1.0;
                     var normalizer = 1.0;
                     var finalValue = void 0;
                     var finalValue = void 0;
                     if (holder.totalWeight < 1.0) {
                     if (holder.totalWeight < 1.0) {
-                        // We need to mix the original value in
-                        var originalValue = holder.animations[0].originalValue;
-                        finalValue = originalValue.scale(1.0 - holder.totalWeight);
+                        // We need to mix the original value in     
+                        if (matrixDecomposeMode) {
+                            finalValue = originalValue.clone();
+                        }
+                        else {
+                            finalValue = originalValue.scale(1.0 - holder.totalWeight);
+                        }
                     }
                     }
                     else {
                     else {
                         // We need to normalize the weights
                         // We need to normalize the weights
@@ -25306,11 +25333,27 @@ var BABYLON;
                     }
                     }
                     for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
                     for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
                         var runtimeAnimation = holder.animations[animIndex];
                         var runtimeAnimation = holder.animations[animIndex];
+                        var scale = runtimeAnimation.weight / normalizer;
                         if (finalValue) {
                         if (finalValue) {
-                            runtimeAnimation.currentValue.scaleAndAddToRef(runtimeAnimation.weight / normalizer, finalValue);
+                            if (matrixDecomposeMode) {
+                                BABYLON.Matrix.DecomposeLerpToRef(finalValue, runtimeAnimation.currentValue, scale, finalValue);
+                            }
+                            else {
+                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                            }
                         }
                         }
                         else {
                         else {
-                            finalValue = runtimeAnimation.currentValue.scale(runtimeAnimation.weight / normalizer);
+                            if (scale !== 1) {
+                                if (matrixDecomposeMode) {
+                                    finalValue = runtimeAnimation.currentValue.clone();
+                                }
+                                else {
+                                    finalValue = runtimeAnimation.currentValue.scale(scale);
+                                }
+                            }
+                            else {
+                                finalValue = runtimeAnimation.currentValue;
+                            }
                         }
                         }
                     }
                     }
                     runtimeAnimation.target[path] = finalValue;
                     runtimeAnimation.target[path] = finalValue;
@@ -25624,6 +25667,18 @@ var BABYLON;
             return index;
             return index;
         };
         };
         /**
         /**
+         * Removes the given effect layer from this scene.
+         * @param toRemove defines the effect layer to remove
+         * @returns the index of the removed effect layer
+         */
+        Scene.prototype.removeEffectLayer = function (toRemove) {
+            var index = this.effectLayers.indexOf(toRemove);
+            if (index !== -1) {
+                this.effectLayers.splice(index, 1);
+            }
+            return index;
+        };
+        /**
          * Removes the given texture from this scene.
          * Removes the given texture from this scene.
          * @param toRemove The texture to remove
          * @param toRemove The texture to remove
          * @returns The index of the removed texture
          * @returns The index of the removed texture
@@ -25732,6 +25787,13 @@ var BABYLON;
             this.lensFlareSystems.push(newLensFlareSystem);
             this.lensFlareSystems.push(newLensFlareSystem);
         };
         };
         /**
         /**
+         * Adds the given effect layer to this scene
+         * @param newEffectLayer defines the effect layer to add
+         */
+        Scene.prototype.addEffectLayer = function (newEffectLayer) {
+            this.effectLayers.push(newEffectLayer);
+        };
+        /**
          * Adds the given action manager to this scene
          * Adds the given action manager to this scene
          * @param newActionManager The action manager to add
          * @param newActionManager The action manager to add
          */
          */
@@ -26811,7 +26873,10 @@ var BABYLON;
                                 action._executeCurrent(BABYLON.ActionEvent.CreateNew(sourceMesh, undefined, otherMesh));
                                 action._executeCurrent(BABYLON.ActionEvent.CreateNew(sourceMesh, undefined, otherMesh));
                             }
                             }
                             //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.
                             //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.
-                            if (!sourceMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnIntersectionExitTrigger) || action.trigger === BABYLON.ActionManager.OnIntersectionExitTrigger) {
+                            if (!sourceMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnIntersectionExitTrigger, function (parameter) {
+                                var parameterMesh = parameter instanceof BABYLON.AbstractMesh ? parameter : parameter.mesh;
+                                return otherMesh === parameterMesh;
+                            }) || action.trigger === BABYLON.ActionManager.OnIntersectionExitTrigger) {
                                 sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);
                                 sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);
                             }
                             }
                         }
                         }
@@ -28220,6 +28285,10 @@ var BABYLON;
              * Textures to keep.
              * Textures to keep.
              */
              */
             this.textures = new Array();
             this.textures = new Array();
+            /**
+             * Effect layers to keep.
+             */
+            this.effectLayers = new Array();
         }
         }
         return KeepAssets;
         return KeepAssets;
     }());
     }());
@@ -28302,6 +28371,10 @@ var BABYLON;
              * Textures populated in the container.
              * Textures populated in the container.
              */
              */
             this.textures = new Array();
             this.textures = new Array();
+            /**
+             * Effect layers populated in the container.
+             */
+            this.effectLayers = new Array();
             this.scene = scene;
             this.scene = scene;
         }
         }
         /**
         /**
@@ -28357,7 +28430,10 @@ var BABYLON;
                 _this.scene.mainSoundTrack.AddSound(o);
                 _this.scene.mainSoundTrack.AddSound(o);
             });
             });
             this.textures.forEach(function (o) {
             this.textures.forEach(function (o) {
-                _this.scene.addTexture;
+                _this.scene.addTexture(o);
+            });
+            this.effectLayers.forEach(function (o) {
+                _this.scene.addEffectLayer(o);
             });
             });
         };
         };
         /**
         /**
@@ -28415,6 +28491,9 @@ var BABYLON;
             this.textures.forEach(function (o) {
             this.textures.forEach(function (o) {
                 _this.scene.removeTexture(o);
                 _this.scene.removeTexture(o);
             });
             });
+            this.effectLayers.forEach(function (o) {
+                _this.scene.removeEffectLayer(o);
+            });
         };
         };
         AssetContainer.prototype._moveAssets = function (sourceAssets, targetAssets, keepAssets) {
         AssetContainer.prototype._moveAssets = function (sourceAssets, targetAssets, keepAssets) {
             for (var _i = 0, sourceAssets_1 = sourceAssets; _i < sourceAssets_1.length; _i++) {
             for (var _i = 0, sourceAssets_1 = sourceAssets; _i < sourceAssets_1.length; _i++) {
@@ -28456,6 +28535,7 @@ var BABYLON;
             this._moveAssets(this.scene.mainSoundTrack.soundCollection, this.sounds, keepAssets.sounds);
             this._moveAssets(this.scene.mainSoundTrack.soundCollection, this.sounds, keepAssets.sounds);
             this._moveAssets(this.scene.transformNodes, this.transformNodes, keepAssets.transformNodes);
             this._moveAssets(this.scene.transformNodes, this.transformNodes, keepAssets.transformNodes);
             this._moveAssets(this.scene.textures, this.textures, keepAssets.textures);
             this._moveAssets(this.scene.textures, this.textures, keepAssets.textures);
+            this._moveAssets(this.scene.effectLayers, this.effectLayers, keepAssets.effectLayers);
             this.removeAllFromScene();
             this.removeAllFromScene();
         };
         };
         return AssetContainer;
         return AssetContainer;
@@ -49846,6 +49926,9 @@ var BABYLON;
             return BABYLON.Color3.Lerp(startValue, endValue, gradient);
             return BABYLON.Color3.Lerp(startValue, endValue, gradient);
         };
         };
         Animation.prototype.matrixInterpolateFunction = function (startValue, endValue, gradient) {
         Animation.prototype.matrixInterpolateFunction = function (startValue, endValue, gradient) {
+            if (Animation.AllowMatrixDecomposeForInterpolation) {
+                return BABYLON.Matrix.DecomposeLerp(startValue, endValue, gradient);
+            }
             return BABYLON.Matrix.Lerp(startValue, endValue, gradient);
             return BABYLON.Matrix.Lerp(startValue, endValue, gradient);
         };
         };
         Animation.prototype.clone = function () {
         Animation.prototype.clone = function () {
@@ -50064,7 +50147,14 @@ var BABYLON;
                 }
                 }
             }
             }
         };
         };
+        /**
+         * Use matrix interpolation instead of using direct key value when animating matrices
+         */
         Animation.AllowMatricesInterpolation = false;
         Animation.AllowMatricesInterpolation = false;
+        /**
+         * When matrix interpolation is enabled, this boolean forces the system to use Matrix.DecomposeLerp instead of Matrix.Lerp. Interpolation is more precise but slower
+         */
+        Animation.AllowMatrixDecomposeForInterpolation = true;
         // Statics
         // Statics
         Animation._ANIMATIONTYPE_FLOAT = 0;
         Animation._ANIMATIONTYPE_FLOAT = 0;
         Animation._ANIMATIONTYPE_VECTOR3 = 1;
         Animation._ANIMATIONTYPE_VECTOR3 = 1;
@@ -50661,7 +50751,22 @@ var BABYLON;
                     }
                     }
                 }
                 }
                 else if (this._originalBlendValue.m) {
                 else if (this._originalBlendValue.m) {
-                    this._currentValue = BABYLON.Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                    if (BABYLON.Animation.AllowMatrixDecomposeForInterpolation) {
+                        if (this._currentValue) {
+                            BABYLON.Matrix.DecomposeLerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
+                        }
+                        else {
+                            this._currentValue = BABYLON.Matrix.DecomposeLerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                        }
+                    }
+                    else {
+                        if (this._currentValue) {
+                            BABYLON.Matrix.LerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
+                        }
+                        else {
+                            this._currentValue = BABYLON.Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                        }
+                    }
                 }
                 }
                 else {
                 else {
                     this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
                     this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
@@ -52072,14 +52177,22 @@ var BABYLON;
         };
         };
         /**
         /**
          * Does this action manager handles actions of a given trigger
          * Does this action manager handles actions of a given trigger
-         * @param {number} trigger - the trigger to be tested
-         * @return {boolean} whether the trigger is handeled
+         * @param trigger defines the trigger to be tested
+         * @param parameterPredicate defines an optional predicate to filter triggers by parameter
+         * @return whether the trigger is handled
          */
          */
-        ActionManager.prototype.hasSpecificTrigger = function (trigger) {
+        ActionManager.prototype.hasSpecificTrigger = function (trigger, parameterPredicate) {
             for (var index = 0; index < this.actions.length; index++) {
             for (var index = 0; index < this.actions.length; index++) {
                 var action = this.actions[index];
                 var action = this.actions[index];
                 if (action.trigger === trigger) {
                 if (action.trigger === trigger) {
-                    return true;
+                    if (parameterPredicate) {
+                        if (parameterPredicate(action.getTriggerParameter())) {
+                            return true;
+                        }
+                    }
+                    else {
+                        return true;
+                    }
                 }
                 }
             }
             }
             return false;
             return false;
@@ -61700,6 +61813,11 @@ var BABYLON;
 
 
 "use strict";
 "use strict";
 
 
+
+
+
+
+
 var BABYLON;
 var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     var CubeTexture = /** @class */ (function (_super) {
     var CubeTexture = /** @class */ (function (_super) {
@@ -61720,6 +61838,7 @@ var BABYLON;
              * It must define where the camera used to render the texture was set
              * It must define where the camera used to render the texture was set
              */
              */
             _this.boundingBoxPosition = BABYLON.Vector3.Zero();
             _this.boundingBoxPosition = BABYLON.Vector3.Zero();
+            _this._rotationY = 0;
             _this.name = rootUrl;
             _this.name = rootUrl;
             _this.url = rootUrl;
             _this.url = rootUrl;
             _this._noMipmap = noMipmap;
             _this._noMipmap = noMipmap;
@@ -61796,6 +61915,23 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        Object.defineProperty(CubeTexture.prototype, "rotationY", {
+            /**
+             * Gets texture matrix rotation angle around Y axis radians.
+             */
+            get: function () {
+                return this._rotationY;
+            },
+            /**
+             * Sets texture matrix rotation angle around Y axis in radians.
+             */
+            set: function (value) {
+                this._rotationY = value;
+                this.setReflectionTextureMatrix(BABYLON.Matrix.RotationY(this._rotationY));
+            },
+            enumerable: true,
+            configurable: true
+        });
         CubeTexture.CreateFromImages = function (files, scene, noMipmap) {
         CubeTexture.CreateFromImages = function (files, scene, noMipmap) {
             var rootUrlKey = "";
             var rootUrlKey = "";
             files.forEach(function (url) { return rootUrlKey += url; });
             files.forEach(function (url) { return rootUrlKey += url; });
@@ -61861,6 +61997,9 @@ var BABYLON;
                 return new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
                 return new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
             }, this);
             }, this);
         };
         };
+        __decorate([
+            BABYLON.serialize("rotationY")
+        ], CubeTexture.prototype, "_rotationY", void 0);
         return CubeTexture;
         return CubeTexture;
     }(BABYLON.BaseTexture));
     }(BABYLON.BaseTexture));
     BABYLON.CubeTexture = CubeTexture;
     BABYLON.CubeTexture = CubeTexture;
@@ -66396,6 +66535,13 @@ var BABYLON;
                     light_2._includedOnlyMeshesIds = [];
                     light_2._includedOnlyMeshesIds = [];
                 }
                 }
             }
             }
+            // Effect layers
+            if (parsedData.effectLayers) {
+                for (index = 0; index < parsedData.effectLayers.length; index++) {
+                    var effectLayer = BABYLON.EffectLayer.Parse(parsedData.effectLayers[index], scene, rootUrl);
+                    container.effectLayers.push(effectLayer);
+                }
+            }
             // Actions (scene)
             // Actions (scene)
             if (parsedData.actions !== undefined && parsedData.actions !== null) {
             if (parsedData.actions !== undefined && parsedData.actions !== null) {
                 BABYLON.ActionManager.Parse(parsedData.actions, null, scene);
                 BABYLON.ActionManager.Parse(parsedData.actions, null, scene);
@@ -73859,7 +74005,7 @@ var BABYLON;
                 return this._circleOfConfusion.focalLength;
                 return this._circleOfConfusion.focalLength;
             },
             },
             /**
             /**
-             * The focal the length of the camera used in the effect
+             * The focal the length of the camera used in the effect in scene units/1000 (eg. millimeter)
              */
              */
             set: function (value) {
             set: function (value) {
                 this._circleOfConfusion.focalLength = value;
                 this._circleOfConfusion.focalLength = value;
@@ -78735,6 +78881,7 @@ var BABYLON;
              */
              */
             _this.isPMREM = false;
             _this.isPMREM = false;
             _this._isBlocking = true;
             _this._isBlocking = true;
+            _this._rotationY = 0;
             /**
             /**
              * Gets or sets the center of the bounding box associated with the cube texture
              * Gets or sets the center of the bounding box associated with the cube texture
              * It must define where the camera used to render the texture was set
              * It must define where the camera used to render the texture was set
@@ -78797,6 +78944,23 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        Object.defineProperty(HDRCubeTexture.prototype, "rotationY", {
+            /**
+             * Gets texture matrix rotation angle around Y axis radians.
+             */
+            get: function () {
+                return this._rotationY;
+            },
+            /**
+             * Sets texture matrix rotation angle around Y axis in radians.
+             */
+            set: function (value) {
+                this._rotationY = value;
+                this.setReflectionTextureMatrix(BABYLON.Matrix.RotationY(this._rotationY));
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(HDRCubeTexture.prototype, "boundingBoxSize", {
         Object.defineProperty(HDRCubeTexture.prototype, "boundingBoxSize", {
             get: function () {
             get: function () {
                 return this._boundingBoxSize;
                 return this._boundingBoxSize;
@@ -79090,6 +79254,9 @@ var BABYLON;
                 if (parsedTexture.boundingBoxSize) {
                 if (parsedTexture.boundingBoxSize) {
                     texture.boundingBoxSize = BABYLON.Vector3.FromArray(parsedTexture.boundingBoxSize);
                     texture.boundingBoxSize = BABYLON.Vector3.FromArray(parsedTexture.boundingBoxSize);
                 }
                 }
+                if (parsedTexture.rotationY) {
+                    texture.rotationY = parsedTexture.rotationY;
+                }
             }
             }
             return texture;
             return texture;
         };
         };
@@ -79111,6 +79278,7 @@ var BABYLON;
             serializationObject.customType = "BABYLON.HDRCubeTexture";
             serializationObject.customType = "BABYLON.HDRCubeTexture";
             serializationObject.noMipmap = this._noMipmap;
             serializationObject.noMipmap = this._noMipmap;
             serializationObject.isBlocking = this._isBlocking;
             serializationObject.isBlocking = this._isBlocking;
+            serializationObject.rotationY = this._rotationY;
             return serializationObject;
             return serializationObject;
         };
         };
         /**
         /**
@@ -90120,6 +90288,17 @@ var BABYLON;
         EffectLayer.prototype.getClassName = function () {
         EffectLayer.prototype.getClassName = function () {
             return "EffectLayer";
             return "EffectLayer";
         };
         };
+        /**
+         * Creates an effect layer from parsed effect layer data
+         * @param parsedEffectLayer defines effect layer data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing the effect layer information
+         * @returns a parsed effect Layer
+         */
+        EffectLayer.Parse = function (parsedEffectLayer, scene, rootUrl) {
+            var effectLayerType = BABYLON.Tools.Instantiate(parsedEffectLayer.customType);
+            return effectLayerType.Parse(parsedEffectLayer, scene, rootUrl);
+        };
         __decorate([
         __decorate([
             BABYLON.serialize()
             BABYLON.serialize()
         ], EffectLayer.prototype, "name", void 0);
         ], EffectLayer.prototype, "name", void 0);
@@ -90607,6 +90786,73 @@ var BABYLON;
             _super.prototype.dispose.call(this);
             _super.prototype.dispose.call(this);
         };
         };
         /**
         /**
+          * Gets the class name of the effect layer
+          * @returns the string with the class name of the effect layer
+          */
+        HighlightLayer.prototype.getClassName = function () {
+            return "HighlightLayer";
+        };
+        /**
+         * Serializes this Highlight layer
+         * @returns a serialized Highlight layer object
+         */
+        HighlightLayer.prototype.serialize = function () {
+            var serializationObject = BABYLON.SerializationHelper.Serialize(this);
+            serializationObject.customType = "BABYLON.HighlightLayer";
+            // Highlighted meshes
+            serializationObject.meshes = [];
+            if (this._meshes) {
+                for (var m in this._meshes) {
+                    var mesh = this._meshes[m];
+                    if (mesh) {
+                        serializationObject.meshes.push({
+                            glowEmissiveOnly: mesh.glowEmissiveOnly,
+                            color: mesh.color.asArray(),
+                            meshId: mesh.mesh.id
+                        });
+                    }
+                }
+            }
+            // Excluded meshes
+            serializationObject.excludedMeshes = [];
+            if (this._excludedMeshes) {
+                for (var e in this._excludedMeshes) {
+                    var excludedMesh = this._excludedMeshes[e];
+                    if (excludedMesh) {
+                        serializationObject.excludedMeshes.push(excludedMesh.mesh.id);
+                    }
+                }
+            }
+            return serializationObject;
+        };
+        /**
+         * Creates a Highlight layer from parsed Highlight layer data
+         * @param parsedHightlightLayer defines the Highlight layer data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing the Highlight layer information
+         * @returns a parsed Highlight layer
+         */
+        HighlightLayer.Parse = function (parsedHightlightLayer, scene, rootUrl) {
+            var hl = BABYLON.SerializationHelper.Parse(function () { return new HighlightLayer(parsedHightlightLayer.name, scene, parsedHightlightLayer.options); }, parsedHightlightLayer, scene, rootUrl);
+            var index;
+            // Excluded meshes
+            for (index = 0; index < parsedHightlightLayer.excludedMeshes.length; index++) {
+                var mesh = scene.getMeshByID(parsedHightlightLayer.excludedMeshes[index]);
+                if (mesh) {
+                    hl.addExcludedMesh(mesh);
+                }
+            }
+            // Included meshes
+            for (index = 0; index < parsedHightlightLayer.meshes.length; index++) {
+                var highlightedMesh = parsedHightlightLayer.meshes[index];
+                var mesh = scene.getMeshByID(highlightedMesh.meshId);
+                if (mesh) {
+                    hl.addMesh(mesh, BABYLON.Color3.FromArray(highlightedMesh.color), highlightedMesh.glowEmissiveOnly);
+                }
+            }
+            return hl;
+        };
+        /**
          * Effect Name of the highlight layer.
          * Effect Name of the highlight layer.
          */
          */
         HighlightLayer.EffectName = "HighlightLayer";
         HighlightLayer.EffectName = "HighlightLayer";
@@ -90623,6 +90869,21 @@ var BABYLON;
          * Stencil value used for the other meshes in the scene.
          * Stencil value used for the other meshes in the scene.
          */
          */
         HighlightLayer.NormalMeshStencilReference = 0x01;
         HighlightLayer.NormalMeshStencilReference = 0x01;
+        __decorate([
+            BABYLON.serialize()
+        ], HighlightLayer.prototype, "innerGlow", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], HighlightLayer.prototype, "outerGlow", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], HighlightLayer.prototype, "blurHorizontalSize", null);
+        __decorate([
+            BABYLON.serialize()
+        ], HighlightLayer.prototype, "blurVerticalSize", null);
+        __decorate([
+            BABYLON.serialize("options")
+        ], HighlightLayer.prototype, "_options", void 0);
         return HighlightLayer;
         return HighlightLayer;
     }(BABYLON.EffectLayer));
     }(BABYLON.EffectLayer));
     BABYLON.HighlightLayer = HighlightLayer;
     BABYLON.HighlightLayer = HighlightLayer;
@@ -90959,6 +91220,7 @@ var BABYLON;
          */
          */
         GlowLayer.prototype.serialize = function () {
         GlowLayer.prototype.serialize = function () {
             var serializationObject = BABYLON.SerializationHelper.Serialize(this);
             var serializationObject = BABYLON.SerializationHelper.Serialize(this);
+            serializationObject.customType = "BABYLON.GlowLayer";
             var index;
             var index;
             // Included meshes
             // Included meshes
             serializationObject.includedMeshes = [];
             serializationObject.includedMeshes = [];
@@ -91027,7 +91289,7 @@ var BABYLON;
             BABYLON.serialize()
             BABYLON.serialize()
         ], GlowLayer.prototype, "intensity", null);
         ], GlowLayer.prototype, "intensity", null);
         __decorate([
         __decorate([
-            BABYLON.serialize('options')
+            BABYLON.serialize("options")
         ], GlowLayer.prototype, "_options", void 0);
         ], GlowLayer.prototype, "_options", void 0);
         return GlowLayer;
         return GlowLayer;
     }(BABYLON.EffectLayer));
     }(BABYLON.EffectLayer));
@@ -92080,6 +92342,14 @@ var BABYLON;
                     serializationObject.sounds.push(soundtrack.soundCollection[soundId].serialize());
                     serializationObject.sounds.push(soundtrack.soundCollection[soundId].serialize());
                 }
                 }
             }
             }
+            // Effect layers
+            serializationObject.effectLayers = [];
+            for (index = 0; index < scene.effectLayers.length; index++) {
+                var layer = scene.effectLayers[index];
+                if (layer.serialize) {
+                    serializationObject.effectLayers.push(layer.serialize());
+                }
+            }
             return serializationObject;
             return serializationObject;
         };
         };
         SceneSerializer.SerializeMesh = function (toSerialize /* Mesh || Mesh[] */, withParents, withChildren) {
         SceneSerializer.SerializeMesh = function (toSerialize /* Mesh || Mesh[] */, withParents, withChildren) {

+ 2 - 2
dist/preview release/gui/babylon.gui.js

@@ -1,5 +1,3 @@
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 
 
 (function universalModuleDefinition(root, factory) {
 (function universalModuleDefinition(root, factory) {
@@ -23,6 +21,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 })(this, function(BABYLON) {
 })(this, function(BABYLON) {
   BABYLON = BABYLON || this.BABYLON;
   BABYLON = BABYLON || this.BABYLON;
 
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 "use strict";
 /// <reference path="../../dist/preview release/babylon.d.ts"/>
 /// <reference path="../../dist/preview release/babylon.d.ts"/>
 
 

File diff suppressed because it is too large
+ 4 - 4
dist/preview release/gui/babylon.gui.min.js


File diff suppressed because it is too large
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


File diff suppressed because it is too large
+ 3 - 3
dist/preview release/inspector/babylon.inspector.min.js


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


File diff suppressed because it is too large
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


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

@@ -1,5 +1,3 @@
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 
 
 (function universalModuleDefinition(root, factory) {
 (function universalModuleDefinition(root, factory) {
@@ -23,6 +21,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 })(this, function(BABYLON) {
 })(this, function(BABYLON) {
   BABYLON = BABYLON || this.BABYLON;
   BABYLON = BABYLON || this.BABYLON;
 
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 "use strict";
 
 
 var BABYLON;
 var BABYLON;

File diff suppressed because it is too large
+ 3 - 3
dist/preview release/loaders/babylonjs.loaders.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylonjs.materials.js

@@ -1,5 +1,3 @@
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 
 
 (function universalModuleDefinition(root, factory) {
 (function universalModuleDefinition(root, factory) {
@@ -23,6 +21,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 })(this, function(BABYLON) {
 })(this, function(BABYLON) {
   BABYLON = BABYLON || this.BABYLON;
   BABYLON = BABYLON || this.BABYLON;
 
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 "use strict";
 
 
 
 

File diff suppressed because it is too large
+ 5 - 5
dist/preview release/materialsLibrary/babylonjs.materials.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js


+ 2 - 2
dist/preview release/postProcessesLibrary/babylonjs.postProcess.js

@@ -1,5 +1,3 @@
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 
 
 (function universalModuleDefinition(root, factory) {
 (function universalModuleDefinition(root, factory) {
@@ -23,6 +21,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 })(this, function(BABYLON) {
 })(this, function(BABYLON) {
   BABYLON = BABYLON || this.BABYLON;
   BABYLON = BABYLON || this.BABYLON;
 
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 "use strict";
 
 
 
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js


+ 2 - 2
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.js

@@ -1,5 +1,3 @@
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 
 
 (function universalModuleDefinition(root, factory) {
 (function universalModuleDefinition(root, factory) {
@@ -23,6 +21,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 })(this, function(BABYLON) {
 })(this, function(BABYLON) {
   BABYLON = BABYLON || this.BABYLON;
   BABYLON = BABYLON || this.BABYLON;
 
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 "use strict";
 
 
 
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


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

@@ -1,5 +1,3 @@
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 
 
 (function universalModuleDefinition(root, factory) {
 (function universalModuleDefinition(root, factory) {
@@ -23,6 +21,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 })(this, function(BABYLON) {
 })(this, function(BABYLON) {
   BABYLON = BABYLON || this.BABYLON;
   BABYLON = BABYLON || this.BABYLON;
 
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 "use strict";
 
 
 var BABYLON;
 var BABYLON;

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


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

@@ -1,7 +1,7 @@
 {
 {
-  "errors": 5492,
+  "errors": 5491,
   "babylon.typedoc.json": {
   "babylon.typedoc.json": {
-    "errors": 5492,
+    "errors": 5491,
     "AnimationKeyInterpolation": {
     "AnimationKeyInterpolation": {
       "Enumeration": {
       "Enumeration": {
         "Comments": {
         "Comments": {
@@ -2312,11 +2312,6 @@
           "Comments": {
           "Comments": {
             "MissingText": true
             "MissingText": true
           }
           }
-        },
-        "AllowMatricesInterpolation": {
-          "Comments": {
-            "MissingText": true
-          }
         }
         }
       },
       },
       "Method": {
       "Method": {

File diff suppressed because it is too large
+ 63 - 63
dist/preview release/viewer/babylon.viewer.js


+ 322 - 52
dist/preview release/viewer/babylon.viewer.max.js

@@ -86,9 +86,7 @@ var BabylonViewer =
 /* 0 */
 /* 0 */
 /***/ (function(module, exports, __webpack_require__) {
 /***/ (function(module, exports, __webpack_require__) {
 
 
-/* WEBPACK VAR INJECTION */(function(global) {var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
-
+/* WEBPACK VAR INJECTION */(function(global) {
 
 
 (function universalModuleDefinition(root, factory) {
 (function universalModuleDefinition(root, factory) {
     var amdDependencies = [];
     var amdDependencies = [];
@@ -121,6 +119,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
   OIMO = OIMO || this.OIMO;
   OIMO = OIMO || this.OIMO;
   earcut = earcut || this.earcut;
   earcut = earcut || this.earcut;
 
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 "use strict";
 var BABYLON;
 var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
@@ -4812,7 +4812,6 @@ var BABYLON;
         Quaternion.SlerpToRef = function (left, right, amount, result) {
         Quaternion.SlerpToRef = function (left, right, amount, result) {
             var num2;
             var num2;
             var num3;
             var num3;
-            var num = amount;
             var num4 = (((left.x * right.x) + (left.y * right.y)) + (left.z * right.z)) + (left.w * right.w);
             var num4 = (((left.x * right.x) + (left.y * right.y)) + (left.z * right.z)) + (left.w * right.w);
             var flag = false;
             var flag = false;
             if (num4 < 0) {
             if (num4 < 0) {
@@ -4820,14 +4819,14 @@ var BABYLON;
                 num4 = -num4;
                 num4 = -num4;
             }
             }
             if (num4 > 0.999999) {
             if (num4 > 0.999999) {
-                num3 = 1 - num;
-                num2 = flag ? -num : num;
+                num3 = 1 - amount;
+                num2 = flag ? -amount : amount;
             }
             }
             else {
             else {
                 var num5 = Math.acos(num4);
                 var num5 = Math.acos(num4);
                 var num6 = (1.0 / Math.sin(num5));
                 var num6 = (1.0 / Math.sin(num5));
-                num3 = (Math.sin((1.0 - num) * num5)) * num6;
-                num2 = flag ? ((-Math.sin(num * num5)) * num6) : ((Math.sin(num * num5)) * num6);
+                num3 = (Math.sin((1.0 - amount) * num5)) * num6;
+                num2 = flag ? ((-Math.sin(amount * num5)) * num6) : ((Math.sin(amount * num5)) * num6);
             }
             }
             result.x = (num3 * left.x) + (num2 * right.x);
             result.x = (num3 * left.x) + (num2 * right.x);
             result.y = (num3 * left.y) + (num2 * right.y);
             result.y = (num3 * left.y) + (num2 * right.y);
@@ -5253,24 +5252,28 @@ var BABYLON;
          * @returns true if operation was successful
          * @returns true if operation was successful
          */
          */
         Matrix.prototype.decompose = function (scale, rotation, translation) {
         Matrix.prototype.decompose = function (scale, rotation, translation) {
-            translation.x = this.m[12];
-            translation.y = this.m[13];
-            translation.z = this.m[14];
+            if (translation) {
+                translation.x = this.m[12];
+                translation.y = this.m[13];
+                translation.z = this.m[14];
+            }
             scale.x = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1] + this.m[2] * this.m[2]);
             scale.x = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1] + this.m[2] * this.m[2]);
             scale.y = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5] + this.m[6] * this.m[6]);
             scale.y = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5] + this.m[6] * this.m[6]);
             scale.z = Math.sqrt(this.m[8] * this.m[8] + this.m[9] * this.m[9] + this.m[10] * this.m[10]);
             scale.z = Math.sqrt(this.m[8] * this.m[8] + this.m[9] * this.m[9] + this.m[10] * this.m[10]);
             if (this.determinant() <= 0) {
             if (this.determinant() <= 0) {
                 scale.y *= -1;
                 scale.y *= -1;
             }
             }
-            if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
-                rotation.x = 0;
-                rotation.y = 0;
-                rotation.z = 0;
-                rotation.w = 1;
-                return false;
+            if (rotation) {
+                if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+                    rotation.x = 0;
+                    rotation.y = 0;
+                    rotation.z = 0;
+                    rotation.w = 1;
+                    return false;
+                }
+                Matrix.FromValuesToRef(this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0, this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0, this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0, 0, 0, 0, 1, MathTmp.Matrix[0]);
+                Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
             }
             }
-            Matrix.FromValuesToRef(this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0, this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0, this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0, 0, 0, 0, 1, MathTmp.Matrix[0]);
-            Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
             return true;
             return true;
         };
         };
         /**
         /**
@@ -5860,18 +5863,36 @@ var BABYLON;
          * @returns the new matrix
          * @returns the new matrix
          */
          */
         Matrix.DecomposeLerp = function (startValue, endValue, gradient) {
         Matrix.DecomposeLerp = function (startValue, endValue, gradient) {
-            var startScale = new Vector3(0, 0, 0);
-            var startRotation = new Quaternion();
-            var startTranslation = new Vector3(0, 0, 0);
+            var result = Matrix.Zero();
+            Matrix.DecomposeLerpToRef(startValue, endValue, gradient, result);
+            return result;
+        };
+        /**
+         * Update a matrix to values which are computed by:
+         * * decomposing the the "startValue" and "endValue" matrices into their respective scale, rotation and translation matrices
+         * * interpolating for "gradient" (float) the values between each of these decomposed matrices between the start and the end
+         * * recomposing a new matrix from these 3 interpolated scale, rotation and translation matrices
+         * @param startValue defines the first matrix
+         * @param endValue defines the second matrix
+         * @param gradient defines the gradient between the two matrices
+         * @param result defines the target matrix
+         */
+        Matrix.DecomposeLerpToRef = function (startValue, endValue, gradient, result) {
+            var startScale = MathTmp.Vector3[0];
+            var startRotation = MathTmp.Quaternion[0];
+            var startTranslation = MathTmp.Vector3[1];
             startValue.decompose(startScale, startRotation, startTranslation);
             startValue.decompose(startScale, startRotation, startTranslation);
-            var endScale = new Vector3(0, 0, 0);
-            var endRotation = new Quaternion();
-            var endTranslation = new Vector3(0, 0, 0);
+            var endScale = MathTmp.Vector3[2];
+            var endRotation = MathTmp.Quaternion[1];
+            var endTranslation = MathTmp.Vector3[3];
             endValue.decompose(endScale, endRotation, endTranslation);
             endValue.decompose(endScale, endRotation, endTranslation);
-            var resultScale = Vector3.Lerp(startScale, endScale, gradient);
-            var resultRotation = Quaternion.Slerp(startRotation, endRotation, gradient);
-            var resultTranslation = Vector3.Lerp(startTranslation, endTranslation, gradient);
-            return Matrix.Compose(resultScale, resultRotation, resultTranslation);
+            var resultScale = MathTmp.Vector3[4];
+            Vector3.LerpToRef(startScale, endScale, gradient, resultScale);
+            var resultRotation = MathTmp.Quaternion[2];
+            Quaternion.SlerpToRef(startRotation, endRotation, gradient, resultRotation);
+            var resultTranslation = MathTmp.Vector3[5];
+            Vector3.LerpToRef(startTranslation, endTranslation, gradient, resultTranslation);
+            Matrix.ComposeToRef(resultScale, resultRotation, resultTranslation, result);
         };
         };
         /**
         /**
          * Gets a new rotation matrix used to rotate an entity so as it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up"
          * Gets a new rotation matrix used to rotate an entity so as it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up"
@@ -7193,9 +7214,9 @@ var BABYLON;
     var MathTmp = /** @class */ (function () {
     var MathTmp = /** @class */ (function () {
         function MathTmp() {
         function MathTmp() {
         }
         }
-        MathTmp.Vector3 = [Vector3.Zero()];
+        MathTmp.Vector3 = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
         MathTmp.Matrix = [Matrix.Zero(), Matrix.Zero()];
         MathTmp.Matrix = [Matrix.Zero(), Matrix.Zero()];
-        MathTmp.Quaternion = [Quaternion.Zero()];
+        MathTmp.Quaternion = [Quaternion.Zero(), Quaternion.Zero(), Quaternion.Zero()];
         return MathTmp;
         return MathTmp;
     }());
     }());
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
@@ -25410,16 +25431,22 @@ var BABYLON;
                 var target = this._registeredForLateAnimationBindings.data[index];
                 var target = this._registeredForLateAnimationBindings.data[index];
                 for (var path in target._lateAnimationHolders) {
                 for (var path in target._lateAnimationHolders) {
                     var holder = target._lateAnimationHolders[path];
                     var holder = target._lateAnimationHolders[path];
+                    var originalValue = holder.animations[0].originalValue;
                     // Sanity check
                     // Sanity check
-                    if (!holder.animations[0].originalValue.scaleAndAddToRef) {
+                    if (!originalValue.scaleAndAddToRef) {
                         continue;
                         continue;
                     }
                     }
+                    var matrixDecomposeMode = BABYLON.Animation.AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix
                     var normalizer = 1.0;
                     var normalizer = 1.0;
                     var finalValue = void 0;
                     var finalValue = void 0;
                     if (holder.totalWeight < 1.0) {
                     if (holder.totalWeight < 1.0) {
-                        // We need to mix the original value in
-                        var originalValue = holder.animations[0].originalValue;
-                        finalValue = originalValue.scale(1.0 - holder.totalWeight);
+                        // We need to mix the original value in     
+                        if (matrixDecomposeMode) {
+                            finalValue = originalValue.clone();
+                        }
+                        else {
+                            finalValue = originalValue.scale(1.0 - holder.totalWeight);
+                        }
                     }
                     }
                     else {
                     else {
                         // We need to normalize the weights
                         // We need to normalize the weights
@@ -25427,11 +25454,27 @@ var BABYLON;
                     }
                     }
                     for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
                     for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
                         var runtimeAnimation = holder.animations[animIndex];
                         var runtimeAnimation = holder.animations[animIndex];
+                        var scale = runtimeAnimation.weight / normalizer;
                         if (finalValue) {
                         if (finalValue) {
-                            runtimeAnimation.currentValue.scaleAndAddToRef(runtimeAnimation.weight / normalizer, finalValue);
+                            if (matrixDecomposeMode) {
+                                BABYLON.Matrix.DecomposeLerpToRef(finalValue, runtimeAnimation.currentValue, scale, finalValue);
+                            }
+                            else {
+                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                            }
                         }
                         }
                         else {
                         else {
-                            finalValue = runtimeAnimation.currentValue.scale(runtimeAnimation.weight / normalizer);
+                            if (scale !== 1) {
+                                if (matrixDecomposeMode) {
+                                    finalValue = runtimeAnimation.currentValue.clone();
+                                }
+                                else {
+                                    finalValue = runtimeAnimation.currentValue.scale(scale);
+                                }
+                            }
+                            else {
+                                finalValue = runtimeAnimation.currentValue;
+                            }
                         }
                         }
                     }
                     }
                     runtimeAnimation.target[path] = finalValue;
                     runtimeAnimation.target[path] = finalValue;
@@ -25745,6 +25788,18 @@ var BABYLON;
             return index;
             return index;
         };
         };
         /**
         /**
+         * Removes the given effect layer from this scene.
+         * @param toRemove defines the effect layer to remove
+         * @returns the index of the removed effect layer
+         */
+        Scene.prototype.removeEffectLayer = function (toRemove) {
+            var index = this.effectLayers.indexOf(toRemove);
+            if (index !== -1) {
+                this.effectLayers.splice(index, 1);
+            }
+            return index;
+        };
+        /**
          * Removes the given texture from this scene.
          * Removes the given texture from this scene.
          * @param toRemove The texture to remove
          * @param toRemove The texture to remove
          * @returns The index of the removed texture
          * @returns The index of the removed texture
@@ -25853,6 +25908,13 @@ var BABYLON;
             this.lensFlareSystems.push(newLensFlareSystem);
             this.lensFlareSystems.push(newLensFlareSystem);
         };
         };
         /**
         /**
+         * Adds the given effect layer to this scene
+         * @param newEffectLayer defines the effect layer to add
+         */
+        Scene.prototype.addEffectLayer = function (newEffectLayer) {
+            this.effectLayers.push(newEffectLayer);
+        };
+        /**
          * Adds the given action manager to this scene
          * Adds the given action manager to this scene
          * @param newActionManager The action manager to add
          * @param newActionManager The action manager to add
          */
          */
@@ -26932,7 +26994,10 @@ var BABYLON;
                                 action._executeCurrent(BABYLON.ActionEvent.CreateNew(sourceMesh, undefined, otherMesh));
                                 action._executeCurrent(BABYLON.ActionEvent.CreateNew(sourceMesh, undefined, otherMesh));
                             }
                             }
                             //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.
                             //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.
-                            if (!sourceMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnIntersectionExitTrigger) || action.trigger === BABYLON.ActionManager.OnIntersectionExitTrigger) {
+                            if (!sourceMesh.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnIntersectionExitTrigger, function (parameter) {
+                                var parameterMesh = parameter instanceof BABYLON.AbstractMesh ? parameter : parameter.mesh;
+                                return otherMesh === parameterMesh;
+                            }) || action.trigger === BABYLON.ActionManager.OnIntersectionExitTrigger) {
                                 sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);
                                 sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);
                             }
                             }
                         }
                         }
@@ -28341,6 +28406,10 @@ var BABYLON;
              * Textures to keep.
              * Textures to keep.
              */
              */
             this.textures = new Array();
             this.textures = new Array();
+            /**
+             * Effect layers to keep.
+             */
+            this.effectLayers = new Array();
         }
         }
         return KeepAssets;
         return KeepAssets;
     }());
     }());
@@ -28423,6 +28492,10 @@ var BABYLON;
              * Textures populated in the container.
              * Textures populated in the container.
              */
              */
             this.textures = new Array();
             this.textures = new Array();
+            /**
+             * Effect layers populated in the container.
+             */
+            this.effectLayers = new Array();
             this.scene = scene;
             this.scene = scene;
         }
         }
         /**
         /**
@@ -28478,7 +28551,10 @@ var BABYLON;
                 _this.scene.mainSoundTrack.AddSound(o);
                 _this.scene.mainSoundTrack.AddSound(o);
             });
             });
             this.textures.forEach(function (o) {
             this.textures.forEach(function (o) {
-                _this.scene.addTexture;
+                _this.scene.addTexture(o);
+            });
+            this.effectLayers.forEach(function (o) {
+                _this.scene.addEffectLayer(o);
             });
             });
         };
         };
         /**
         /**
@@ -28536,6 +28612,9 @@ var BABYLON;
             this.textures.forEach(function (o) {
             this.textures.forEach(function (o) {
                 _this.scene.removeTexture(o);
                 _this.scene.removeTexture(o);
             });
             });
+            this.effectLayers.forEach(function (o) {
+                _this.scene.removeEffectLayer(o);
+            });
         };
         };
         AssetContainer.prototype._moveAssets = function (sourceAssets, targetAssets, keepAssets) {
         AssetContainer.prototype._moveAssets = function (sourceAssets, targetAssets, keepAssets) {
             for (var _i = 0, sourceAssets_1 = sourceAssets; _i < sourceAssets_1.length; _i++) {
             for (var _i = 0, sourceAssets_1 = sourceAssets; _i < sourceAssets_1.length; _i++) {
@@ -28577,6 +28656,7 @@ var BABYLON;
             this._moveAssets(this.scene.mainSoundTrack.soundCollection, this.sounds, keepAssets.sounds);
             this._moveAssets(this.scene.mainSoundTrack.soundCollection, this.sounds, keepAssets.sounds);
             this._moveAssets(this.scene.transformNodes, this.transformNodes, keepAssets.transformNodes);
             this._moveAssets(this.scene.transformNodes, this.transformNodes, keepAssets.transformNodes);
             this._moveAssets(this.scene.textures, this.textures, keepAssets.textures);
             this._moveAssets(this.scene.textures, this.textures, keepAssets.textures);
+            this._moveAssets(this.scene.effectLayers, this.effectLayers, keepAssets.effectLayers);
             this.removeAllFromScene();
             this.removeAllFromScene();
         };
         };
         return AssetContainer;
         return AssetContainer;
@@ -49967,6 +50047,9 @@ var BABYLON;
             return BABYLON.Color3.Lerp(startValue, endValue, gradient);
             return BABYLON.Color3.Lerp(startValue, endValue, gradient);
         };
         };
         Animation.prototype.matrixInterpolateFunction = function (startValue, endValue, gradient) {
         Animation.prototype.matrixInterpolateFunction = function (startValue, endValue, gradient) {
+            if (Animation.AllowMatrixDecomposeForInterpolation) {
+                return BABYLON.Matrix.DecomposeLerp(startValue, endValue, gradient);
+            }
             return BABYLON.Matrix.Lerp(startValue, endValue, gradient);
             return BABYLON.Matrix.Lerp(startValue, endValue, gradient);
         };
         };
         Animation.prototype.clone = function () {
         Animation.prototype.clone = function () {
@@ -50185,7 +50268,14 @@ var BABYLON;
                 }
                 }
             }
             }
         };
         };
+        /**
+         * Use matrix interpolation instead of using direct key value when animating matrices
+         */
         Animation.AllowMatricesInterpolation = false;
         Animation.AllowMatricesInterpolation = false;
+        /**
+         * When matrix interpolation is enabled, this boolean forces the system to use Matrix.DecomposeLerp instead of Matrix.Lerp. Interpolation is more precise but slower
+         */
+        Animation.AllowMatrixDecomposeForInterpolation = true;
         // Statics
         // Statics
         Animation._ANIMATIONTYPE_FLOAT = 0;
         Animation._ANIMATIONTYPE_FLOAT = 0;
         Animation._ANIMATIONTYPE_VECTOR3 = 1;
         Animation._ANIMATIONTYPE_VECTOR3 = 1;
@@ -50782,7 +50872,22 @@ var BABYLON;
                     }
                     }
                 }
                 }
                 else if (this._originalBlendValue.m) {
                 else if (this._originalBlendValue.m) {
-                    this._currentValue = BABYLON.Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                    if (BABYLON.Animation.AllowMatrixDecomposeForInterpolation) {
+                        if (this._currentValue) {
+                            BABYLON.Matrix.DecomposeLerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
+                        }
+                        else {
+                            this._currentValue = BABYLON.Matrix.DecomposeLerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                        }
+                    }
+                    else {
+                        if (this._currentValue) {
+                            BABYLON.Matrix.LerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
+                        }
+                        else {
+                            this._currentValue = BABYLON.Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                        }
+                    }
                 }
                 }
                 else {
                 else {
                     this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
                     this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
@@ -52193,14 +52298,22 @@ var BABYLON;
         };
         };
         /**
         /**
          * Does this action manager handles actions of a given trigger
          * Does this action manager handles actions of a given trigger
-         * @param {number} trigger - the trigger to be tested
-         * @return {boolean} whether the trigger is handeled
+         * @param trigger defines the trigger to be tested
+         * @param parameterPredicate defines an optional predicate to filter triggers by parameter
+         * @return whether the trigger is handled
          */
          */
-        ActionManager.prototype.hasSpecificTrigger = function (trigger) {
+        ActionManager.prototype.hasSpecificTrigger = function (trigger, parameterPredicate) {
             for (var index = 0; index < this.actions.length; index++) {
             for (var index = 0; index < this.actions.length; index++) {
                 var action = this.actions[index];
                 var action = this.actions[index];
                 if (action.trigger === trigger) {
                 if (action.trigger === trigger) {
-                    return true;
+                    if (parameterPredicate) {
+                        if (parameterPredicate(action.getTriggerParameter())) {
+                            return true;
+                        }
+                    }
+                    else {
+                        return true;
+                    }
                 }
                 }
             }
             }
             return false;
             return false;
@@ -61821,6 +61934,11 @@ var BABYLON;
 
 
 "use strict";
 "use strict";
 
 
+
+
+
+
+
 var BABYLON;
 var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     var CubeTexture = /** @class */ (function (_super) {
     var CubeTexture = /** @class */ (function (_super) {
@@ -61841,6 +61959,7 @@ var BABYLON;
              * It must define where the camera used to render the texture was set
              * It must define where the camera used to render the texture was set
              */
              */
             _this.boundingBoxPosition = BABYLON.Vector3.Zero();
             _this.boundingBoxPosition = BABYLON.Vector3.Zero();
+            _this._rotationY = 0;
             _this.name = rootUrl;
             _this.name = rootUrl;
             _this.url = rootUrl;
             _this.url = rootUrl;
             _this._noMipmap = noMipmap;
             _this._noMipmap = noMipmap;
@@ -61917,6 +62036,23 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        Object.defineProperty(CubeTexture.prototype, "rotationY", {
+            /**
+             * Gets texture matrix rotation angle around Y axis radians.
+             */
+            get: function () {
+                return this._rotationY;
+            },
+            /**
+             * Sets texture matrix rotation angle around Y axis in radians.
+             */
+            set: function (value) {
+                this._rotationY = value;
+                this.setReflectionTextureMatrix(BABYLON.Matrix.RotationY(this._rotationY));
+            },
+            enumerable: true,
+            configurable: true
+        });
         CubeTexture.CreateFromImages = function (files, scene, noMipmap) {
         CubeTexture.CreateFromImages = function (files, scene, noMipmap) {
             var rootUrlKey = "";
             var rootUrlKey = "";
             files.forEach(function (url) { return rootUrlKey += url; });
             files.forEach(function (url) { return rootUrlKey += url; });
@@ -61982,6 +62118,9 @@ var BABYLON;
                 return new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
                 return new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
             }, this);
             }, this);
         };
         };
+        __decorate([
+            BABYLON.serialize("rotationY")
+        ], CubeTexture.prototype, "_rotationY", void 0);
         return CubeTexture;
         return CubeTexture;
     }(BABYLON.BaseTexture));
     }(BABYLON.BaseTexture));
     BABYLON.CubeTexture = CubeTexture;
     BABYLON.CubeTexture = CubeTexture;
@@ -66517,6 +66656,13 @@ var BABYLON;
                     light_2._includedOnlyMeshesIds = [];
                     light_2._includedOnlyMeshesIds = [];
                 }
                 }
             }
             }
+            // Effect layers
+            if (parsedData.effectLayers) {
+                for (index = 0; index < parsedData.effectLayers.length; index++) {
+                    var effectLayer = BABYLON.EffectLayer.Parse(parsedData.effectLayers[index], scene, rootUrl);
+                    container.effectLayers.push(effectLayer);
+                }
+            }
             // Actions (scene)
             // Actions (scene)
             if (parsedData.actions !== undefined && parsedData.actions !== null) {
             if (parsedData.actions !== undefined && parsedData.actions !== null) {
                 BABYLON.ActionManager.Parse(parsedData.actions, null, scene);
                 BABYLON.ActionManager.Parse(parsedData.actions, null, scene);
@@ -73980,7 +74126,7 @@ var BABYLON;
                 return this._circleOfConfusion.focalLength;
                 return this._circleOfConfusion.focalLength;
             },
             },
             /**
             /**
-             * The focal the length of the camera used in the effect
+             * The focal the length of the camera used in the effect in scene units/1000 (eg. millimeter)
              */
              */
             set: function (value) {
             set: function (value) {
                 this._circleOfConfusion.focalLength = value;
                 this._circleOfConfusion.focalLength = value;
@@ -78856,6 +79002,7 @@ var BABYLON;
              */
              */
             _this.isPMREM = false;
             _this.isPMREM = false;
             _this._isBlocking = true;
             _this._isBlocking = true;
+            _this._rotationY = 0;
             /**
             /**
              * Gets or sets the center of the bounding box associated with the cube texture
              * Gets or sets the center of the bounding box associated with the cube texture
              * It must define where the camera used to render the texture was set
              * It must define where the camera used to render the texture was set
@@ -78918,6 +79065,23 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        Object.defineProperty(HDRCubeTexture.prototype, "rotationY", {
+            /**
+             * Gets texture matrix rotation angle around Y axis radians.
+             */
+            get: function () {
+                return this._rotationY;
+            },
+            /**
+             * Sets texture matrix rotation angle around Y axis in radians.
+             */
+            set: function (value) {
+                this._rotationY = value;
+                this.setReflectionTextureMatrix(BABYLON.Matrix.RotationY(this._rotationY));
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(HDRCubeTexture.prototype, "boundingBoxSize", {
         Object.defineProperty(HDRCubeTexture.prototype, "boundingBoxSize", {
             get: function () {
             get: function () {
                 return this._boundingBoxSize;
                 return this._boundingBoxSize;
@@ -79211,6 +79375,9 @@ var BABYLON;
                 if (parsedTexture.boundingBoxSize) {
                 if (parsedTexture.boundingBoxSize) {
                     texture.boundingBoxSize = BABYLON.Vector3.FromArray(parsedTexture.boundingBoxSize);
                     texture.boundingBoxSize = BABYLON.Vector3.FromArray(parsedTexture.boundingBoxSize);
                 }
                 }
+                if (parsedTexture.rotationY) {
+                    texture.rotationY = parsedTexture.rotationY;
+                }
             }
             }
             return texture;
             return texture;
         };
         };
@@ -79232,6 +79399,7 @@ var BABYLON;
             serializationObject.customType = "BABYLON.HDRCubeTexture";
             serializationObject.customType = "BABYLON.HDRCubeTexture";
             serializationObject.noMipmap = this._noMipmap;
             serializationObject.noMipmap = this._noMipmap;
             serializationObject.isBlocking = this._isBlocking;
             serializationObject.isBlocking = this._isBlocking;
+            serializationObject.rotationY = this._rotationY;
             return serializationObject;
             return serializationObject;
         };
         };
         /**
         /**
@@ -90241,6 +90409,17 @@ var BABYLON;
         EffectLayer.prototype.getClassName = function () {
         EffectLayer.prototype.getClassName = function () {
             return "EffectLayer";
             return "EffectLayer";
         };
         };
+        /**
+         * Creates an effect layer from parsed effect layer data
+         * @param parsedEffectLayer defines effect layer data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing the effect layer information
+         * @returns a parsed effect Layer
+         */
+        EffectLayer.Parse = function (parsedEffectLayer, scene, rootUrl) {
+            var effectLayerType = BABYLON.Tools.Instantiate(parsedEffectLayer.customType);
+            return effectLayerType.Parse(parsedEffectLayer, scene, rootUrl);
+        };
         __decorate([
         __decorate([
             BABYLON.serialize()
             BABYLON.serialize()
         ], EffectLayer.prototype, "name", void 0);
         ], EffectLayer.prototype, "name", void 0);
@@ -90728,6 +90907,73 @@ var BABYLON;
             _super.prototype.dispose.call(this);
             _super.prototype.dispose.call(this);
         };
         };
         /**
         /**
+          * Gets the class name of the effect layer
+          * @returns the string with the class name of the effect layer
+          */
+        HighlightLayer.prototype.getClassName = function () {
+            return "HighlightLayer";
+        };
+        /**
+         * Serializes this Highlight layer
+         * @returns a serialized Highlight layer object
+         */
+        HighlightLayer.prototype.serialize = function () {
+            var serializationObject = BABYLON.SerializationHelper.Serialize(this);
+            serializationObject.customType = "BABYLON.HighlightLayer";
+            // Highlighted meshes
+            serializationObject.meshes = [];
+            if (this._meshes) {
+                for (var m in this._meshes) {
+                    var mesh = this._meshes[m];
+                    if (mesh) {
+                        serializationObject.meshes.push({
+                            glowEmissiveOnly: mesh.glowEmissiveOnly,
+                            color: mesh.color.asArray(),
+                            meshId: mesh.mesh.id
+                        });
+                    }
+                }
+            }
+            // Excluded meshes
+            serializationObject.excludedMeshes = [];
+            if (this._excludedMeshes) {
+                for (var e in this._excludedMeshes) {
+                    var excludedMesh = this._excludedMeshes[e];
+                    if (excludedMesh) {
+                        serializationObject.excludedMeshes.push(excludedMesh.mesh.id);
+                    }
+                }
+            }
+            return serializationObject;
+        };
+        /**
+         * Creates a Highlight layer from parsed Highlight layer data
+         * @param parsedHightlightLayer defines the Highlight layer data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing the Highlight layer information
+         * @returns a parsed Highlight layer
+         */
+        HighlightLayer.Parse = function (parsedHightlightLayer, scene, rootUrl) {
+            var hl = BABYLON.SerializationHelper.Parse(function () { return new HighlightLayer(parsedHightlightLayer.name, scene, parsedHightlightLayer.options); }, parsedHightlightLayer, scene, rootUrl);
+            var index;
+            // Excluded meshes
+            for (index = 0; index < parsedHightlightLayer.excludedMeshes.length; index++) {
+                var mesh = scene.getMeshByID(parsedHightlightLayer.excludedMeshes[index]);
+                if (mesh) {
+                    hl.addExcludedMesh(mesh);
+                }
+            }
+            // Included meshes
+            for (index = 0; index < parsedHightlightLayer.meshes.length; index++) {
+                var highlightedMesh = parsedHightlightLayer.meshes[index];
+                var mesh = scene.getMeshByID(highlightedMesh.meshId);
+                if (mesh) {
+                    hl.addMesh(mesh, BABYLON.Color3.FromArray(highlightedMesh.color), highlightedMesh.glowEmissiveOnly);
+                }
+            }
+            return hl;
+        };
+        /**
          * Effect Name of the highlight layer.
          * Effect Name of the highlight layer.
          */
          */
         HighlightLayer.EffectName = "HighlightLayer";
         HighlightLayer.EffectName = "HighlightLayer";
@@ -90744,6 +90990,21 @@ var BABYLON;
          * Stencil value used for the other meshes in the scene.
          * Stencil value used for the other meshes in the scene.
          */
          */
         HighlightLayer.NormalMeshStencilReference = 0x01;
         HighlightLayer.NormalMeshStencilReference = 0x01;
+        __decorate([
+            BABYLON.serialize()
+        ], HighlightLayer.prototype, "innerGlow", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], HighlightLayer.prototype, "outerGlow", void 0);
+        __decorate([
+            BABYLON.serialize()
+        ], HighlightLayer.prototype, "blurHorizontalSize", null);
+        __decorate([
+            BABYLON.serialize()
+        ], HighlightLayer.prototype, "blurVerticalSize", null);
+        __decorate([
+            BABYLON.serialize("options")
+        ], HighlightLayer.prototype, "_options", void 0);
         return HighlightLayer;
         return HighlightLayer;
     }(BABYLON.EffectLayer));
     }(BABYLON.EffectLayer));
     BABYLON.HighlightLayer = HighlightLayer;
     BABYLON.HighlightLayer = HighlightLayer;
@@ -91080,6 +91341,7 @@ var BABYLON;
          */
          */
         GlowLayer.prototype.serialize = function () {
         GlowLayer.prototype.serialize = function () {
             var serializationObject = BABYLON.SerializationHelper.Serialize(this);
             var serializationObject = BABYLON.SerializationHelper.Serialize(this);
+            serializationObject.customType = "BABYLON.GlowLayer";
             var index;
             var index;
             // Included meshes
             // Included meshes
             serializationObject.includedMeshes = [];
             serializationObject.includedMeshes = [];
@@ -91148,7 +91410,7 @@ var BABYLON;
             BABYLON.serialize()
             BABYLON.serialize()
         ], GlowLayer.prototype, "intensity", null);
         ], GlowLayer.prototype, "intensity", null);
         __decorate([
         __decorate([
-            BABYLON.serialize('options')
+            BABYLON.serialize("options")
         ], GlowLayer.prototype, "_options", void 0);
         ], GlowLayer.prototype, "_options", void 0);
         return GlowLayer;
         return GlowLayer;
     }(BABYLON.EffectLayer));
     }(BABYLON.EffectLayer));
@@ -92201,6 +92463,14 @@ var BABYLON;
                     serializationObject.sounds.push(soundtrack.soundCollection[soundId].serialize());
                     serializationObject.sounds.push(soundtrack.soundCollection[soundId].serialize());
                 }
                 }
             }
             }
+            // Effect layers
+            serializationObject.effectLayers = [];
+            for (index = 0; index < scene.effectLayers.length; index++) {
+                var layer = scene.effectLayers[index];
+                if (layer.serialize) {
+                    serializationObject.effectLayers.push(layer.serialize());
+                }
+            }
             return serializationObject;
             return serializationObject;
         };
         };
         SceneSerializer.SerializeMesh = function (toSerialize /* Mesh || Mesh[] */, withParents, withChildren) {
         SceneSerializer.SerializeMesh = function (toSerialize /* Mesh || Mesh[] */, withParents, withChildren) {
@@ -99396,8 +99666,6 @@ module.exports = "SHARE";
 /* 34 */
 /* 34 */
 /***/ (function(module, exports, __webpack_require__) {
 /***/ (function(module, exports, __webpack_require__) {
 
 
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 
 
 (function universalModuleDefinition(root, factory) {
 (function universalModuleDefinition(root, factory) {
@@ -99421,6 +99689,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 })(this, function(BABYLON) {
 })(this, function(BABYLON) {
   BABYLON = BABYLON || this.BABYLON;
   BABYLON = BABYLON || this.BABYLON;
 
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 "use strict";
 
 
 var BABYLON;
 var BABYLON;
@@ -103219,7 +103489,7 @@ var BABYLON;
                     _this._babylonScene = scene;
                     _this._babylonScene = scene;
                     _this._rootUrl = rootUrl;
                     _this._rootUrl = rootUrl;
                     _this._progressCallback = onProgress;
                     _this._progressCallback = onProgress;
-                    _this._state = BABYLON.GLTFLoaderState.Loading;
+                    _this._state = BABYLON.GLTFLoaderState.LOADING;
                     _this._loadData(data);
                     _this._loadData(data);
                     _this._checkExtensions();
                     _this._checkExtensions();
                     var promises = new Array();
                     var promises = new Array();
@@ -103237,7 +103507,7 @@ var BABYLON;
                         promises.push(_this._compileShadowGeneratorsAsync());
                         promises.push(_this._compileShadowGeneratorsAsync());
                     }
                     }
                     var resultPromise = Promise.all(promises).then(function () {
                     var resultPromise = Promise.all(promises).then(function () {
-                        _this._state = BABYLON.GLTFLoaderState.Ready;
+                        _this._state = BABYLON.GLTFLoaderState.READY;
                         _this._startAnimations();
                         _this._startAnimations();
                     });
                     });
                     resultPromise.then(function () {
                     resultPromise.then(function () {
@@ -103245,7 +103515,7 @@ var BABYLON;
                         BABYLON.Tools.SetImmediate(function () {
                         BABYLON.Tools.SetImmediate(function () {
                             if (!_this._disposed) {
                             if (!_this._disposed) {
                                 Promise.all(_this._completePromises).then(function () {
                                 Promise.all(_this._completePromises).then(function () {
-                                    _this._state = BABYLON.GLTFLoaderState.Complete;
+                                    _this._state = BABYLON.GLTFLoaderState.COMPLETE;
                                     _this.onCompleteObservable.notifyObservers(_this);
                                     _this.onCompleteObservable.notifyObservers(_this);
                                     _this.onCompleteObservable.clear();
                                     _this.onCompleteObservable.clear();
                                     _this._clear();
                                     _this._clear();
@@ -104283,7 +104553,7 @@ var BABYLON;
                     }, function (event) {
                     }, function (event) {
                         if (!_this._disposed) {
                         if (!_this._disposed) {
                             try {
                             try {
-                                if (request && _this._state === BABYLON.GLTFLoaderState.Loading) {
+                                if (request && _this._state === BABYLON.GLTFLoaderState.LOADING) {
                                     request._lengthComputable = event.lengthComputable;
                                     request._lengthComputable = event.lengthComputable;
                                     request._loaded = event.loaded;
                                     request._loaded = event.loaded;
                                     request._total = event.total;
                                     request._total = event.total;

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

@@ -30,6 +30,7 @@
 
 
 ## Updates
 ## Updates
 
 
+- Improved [animation blending](https://www.babylonjs-playground.com/#DMLMIP) ([deltakosh](https://github.com/deltakosh))
 - New [particle system emitter shapes](http://doc.babylonjs.com/babylon101/particles#particles-shapes): cone and sphere ([IbraheemOsama](https://github.com/IbraheemOsama))
 - New [particle system emitter shapes](http://doc.babylonjs.com/babylon101/particles#particles-shapes): cone and sphere ([IbraheemOsama](https://github.com/IbraheemOsama))
 - Added support for 16bits TGA ([deltakosh](https://github.com/deltakosh))
 - Added support for 16bits TGA ([deltakosh](https://github.com/deltakosh))
 - New `AnimationPropertiesOverride` class used to simplify setting animation properties on child animations. [Documentation](http://doc.babylonjs.com/babylon101/animations#overriding-properties) ([deltakosh](https://github.com/deltakosh))
 - New `AnimationPropertiesOverride` class used to simplify setting animation properties on child animations. [Documentation](http://doc.babylonjs.com/babylon101/animations#overriding-properties) ([deltakosh](https://github.com/deltakosh))

+ 11 - 4
src/Actions/babylon.actionManager.ts

@@ -197,15 +197,22 @@
 
 
         /**
         /**
          * Does this action manager handles actions of a given trigger
          * Does this action manager handles actions of a given trigger
-         * @param {number} trigger - the trigger to be tested
-         * @return {boolean} whether the trigger is handeled 
+         * @param trigger defines the trigger to be tested
+         * @param parameterPredicate defines an optional predicate to filter triggers by parameter
+         * @return whether the trigger is handled 
          */
          */
-        public hasSpecificTrigger(trigger: number): boolean {
+        public hasSpecificTrigger(trigger: number, parameterPredicate?: (parameter: any) => boolean): boolean {
             for (var index = 0; index < this.actions.length; index++) {
             for (var index = 0; index < this.actions.length; index++) {
                 var action = this.actions[index];
                 var action = this.actions[index];
 
 
                 if (action.trigger === trigger) {
                 if (action.trigger === trigger) {
-                    return true;
+                    if (parameterPredicate) {
+                        if (parameterPredicate(action.getTriggerParameter())) {
+                            return true;
+                        }
+                    } else {
+                        return true;
+                    }
                 }
                 }
             }
             }
 
 

+ 11 - 0
src/Animations/babylon.animation.ts

@@ -97,8 +97,16 @@
     }
     }
 
 
     export class Animation {
     export class Animation {
+        /**
+         * Use matrix interpolation instead of using direct key value when animating matrices
+         */
         public static AllowMatricesInterpolation = false;
         public static AllowMatricesInterpolation = false;
 
 
+        /**
+         * When matrix interpolation is enabled, this boolean forces the system to use Matrix.DecomposeLerp instead of Matrix.Lerp. Interpolation is more precise but slower
+         */
+        public static AllowMatrixDecomposeForInterpolation = true;
+
         private _keys: Array<IAnimationKey>;
         private _keys: Array<IAnimationKey>;
         private _easingFunction: IEasingFunction;
         private _easingFunction: IEasingFunction;
 
 
@@ -449,6 +457,9 @@
         }
         }
 
 
         public matrixInterpolateFunction(startValue: Matrix, endValue: Matrix, gradient: number): Matrix {
         public matrixInterpolateFunction(startValue: Matrix, endValue: Matrix, gradient: number): Matrix {
+            if (Animation.AllowMatrixDecomposeForInterpolation) {
+                return Matrix.DecomposeLerp(startValue, endValue, gradient);
+            }
             return Matrix.Lerp(startValue, endValue, gradient);
             return Matrix.Lerp(startValue, endValue, gradient);
         }
         }
 
 

+ 13 - 1
src/Animations/babylon.runtimeAnimation.ts

@@ -308,7 +308,19 @@
                     }
                     }
 
 
                 } else if (this._originalBlendValue.m) { // Matrix
                 } else if (this._originalBlendValue.m) { // Matrix
-                    this._currentValue = Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                    if (Animation.AllowMatrixDecomposeForInterpolation) {
+                        if (this._currentValue) {
+                            Matrix.DecomposeLerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
+                        } else {
+                            this._currentValue = Matrix.DecomposeLerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                        }
+                    } else {
+                        if (this._currentValue) {
+                            Matrix.LerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
+                        } else {
+                            this._currentValue = Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                        }
+                    }
                 } else { // Direct value
                 } else { // Direct value
                     this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
                     this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
                 }
                 }

+ 17 - 0
src/Materials/Textures/babylon.cubeTexture.ts

@@ -31,6 +31,23 @@
             return this._boundingBoxSize;
             return this._boundingBoxSize;
         }
         }
 
 
+
+        @serialize("rotationY")
+        protected _rotationY: number = 0;
+        /**
+         * Sets texture matrix rotation angle around Y axis in radians.
+         */
+        public set rotationY(value: number) {
+            this._rotationY = value;
+            this.setReflectionTextureMatrix(BABYLON.Matrix.RotationY(this._rotationY));
+        }
+        /**
+         * Gets texture matrix rotation angle around Y axis radians.
+         */
+        public get rotationY(): number {
+            return this._rotationY;
+        }        
+
         private _noMipmap: boolean;
         private _noMipmap: boolean;
         private _files: string[];
         private _files: string[];
         private _extensions: string[];
         private _extensions: string[];

+ 2 - 2
src/Materials/Textures/babylon.hdrCubeTexture.ts

@@ -59,14 +59,14 @@ module BABYLON {
 
 
         protected _rotationY: number = 0;
         protected _rotationY: number = 0;
         /**
         /**
-         * Sets texture matrix rotation angle (theta) Y in radians.
+         * Sets texture matrix rotation angle around Y axis in radians.
          */
          */
         public set rotationY(value: number) {
         public set rotationY(value: number) {
             this._rotationY = value;
             this._rotationY = value;
             this.setReflectionTextureMatrix(BABYLON.Matrix.RotationY(this._rotationY));
             this.setReflectionTextureMatrix(BABYLON.Matrix.RotationY(this._rotationY));
         }
         }
         /**
         /**
-         * Gets texture matrix rotation angle (theta) Y radians.
+         * Gets texture matrix rotation angle around Y axis radians.
          */
          */
         public get rotationY(): number {
         public get rotationY(): number {
             return this._rotationY;
             return this._rotationY;

+ 60 - 36
src/Math/babylon.math.ts

@@ -3552,7 +3552,6 @@
         public static SlerpToRef(left: Quaternion, right: Quaternion, amount: number, result: Quaternion): void {
         public static SlerpToRef(left: Quaternion, right: Quaternion, amount: number, result: Quaternion): void {
             var num2;
             var num2;
             var num3;
             var num3;
-            var num = amount;
             var num4 = (((left.x * right.x) + (left.y * right.y)) + (left.z * right.z)) + (left.w * right.w);
             var num4 = (((left.x * right.x) + (left.y * right.y)) + (left.z * right.z)) + (left.w * right.w);
             var flag = false;
             var flag = false;
 
 
@@ -3562,14 +3561,14 @@
             }
             }
 
 
             if (num4 > 0.999999) {
             if (num4 > 0.999999) {
-                num3 = 1 - num;
-                num2 = flag ? -num : num;
+                num3 = 1 - amount;
+                num2 = flag ? -amount : amount;
             }
             }
             else {
             else {
                 var num5 = Math.acos(num4);
                 var num5 = Math.acos(num4);
                 var num6 = (1.0 / Math.sin(num5));
                 var num6 = (1.0 / Math.sin(num5));
-                num3 = (Math.sin((1.0 - num) * num5)) * num6;
-                num2 = flag ? ((-Math.sin(num * num5)) * num6) : ((Math.sin(num * num5)) * num6);
+                num3 = (Math.sin((1.0 - amount) * num5)) * num6;
+                num2 = flag ? ((-Math.sin(amount * num5)) * num6) : ((Math.sin(amount * num5)) * num6);
             }
             }
 
 
             result.x = (num3 * left.x) + (num2 * right.x);
             result.x = (num3 * left.x) + (num2 * right.x);
@@ -4042,7 +4041,8 @@
                 hash = (hash * 397) ^ (this.m[i] || 0);
                 hash = (hash * 397) ^ (this.m[i] || 0);
             }
             }
             return hash;
             return hash;
-        }
+        }     
+
         /**
         /**
          * Decomposes the current Matrix into a translation, rotation and scaling components
          * Decomposes the current Matrix into a translation, rotation and scaling components
          * @param scale defines the scale vector3 passed as a reference to update
          * @param scale defines the scale vector3 passed as a reference to update
@@ -4050,10 +4050,12 @@
          * @param translation defines the translation vector3 passed as a reference to update
          * @param translation defines the translation vector3 passed as a reference to update
          * @returns true if operation was successful
          * @returns true if operation was successful
          */
          */
-        public decompose(scale: Vector3, rotation: Quaternion, translation: Vector3): boolean {
-            translation.x = this.m[12];
-            translation.y = this.m[13];
-            translation.z = this.m[14];
+        public decompose(scale: Vector3, rotation?: Quaternion, translation?: Vector3): boolean {
+            if (translation) {
+                translation.x = this.m[12];
+                translation.y = this.m[13];
+                translation.z = this.m[14];
+            }
 
 
             scale.x = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1] + this.m[2] * this.m[2]);
             scale.x = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1] + this.m[2] * this.m[2]);
             scale.y = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5] + this.m[6] * this.m[6]);
             scale.y = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5] + this.m[6] * this.m[6]);
@@ -4063,21 +4065,23 @@
                 scale.y *= -1;
                 scale.y *= -1;
             }
             }
 
 
-            if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
-                rotation.x = 0;
-                rotation.y = 0;
-                rotation.z = 0;
-                rotation.w = 1;
-                return false;
-            }
+            if (rotation) {
+                if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+                    rotation.x = 0;
+                    rotation.y = 0;
+                    rotation.z = 0;
+                    rotation.w = 1;
+                    return false;
+                }
 
 
-            Matrix.FromValuesToRef(
-                this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0,
-                this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0,
-                this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0,
-                0, 0, 0, 1, MathTmp.Matrix[0]);
+                Matrix.FromValuesToRef(
+                    this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0,
+                    this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0,
+                    this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0,
+                    0, 0, 0, 1, MathTmp.Matrix[0]);
 
 
-            Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
+                Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
+            }
 
 
             return true;
             return true;
         }
         }
@@ -4769,22 +4773,42 @@
          * @returns the new matrix
          * @returns the new matrix
          */
          */
         public static DecomposeLerp(startValue: Matrix, endValue: Matrix, gradient: number): Matrix {
         public static DecomposeLerp(startValue: Matrix, endValue: Matrix, gradient: number): Matrix {
-            var startScale = new Vector3(0, 0, 0);
-            var startRotation = new Quaternion();
-            var startTranslation = new Vector3(0, 0, 0);
+            var result = Matrix.Zero();
+            Matrix.DecomposeLerpToRef(startValue, endValue, gradient, result);
+            return result;
+        }
+
+        /**
+         * Update a matrix to values which are computed by: 
+         * * decomposing the the "startValue" and "endValue" matrices into their respective scale, rotation and translation matrices
+         * * interpolating for "gradient" (float) the values between each of these decomposed matrices between the start and the end
+         * * recomposing a new matrix from these 3 interpolated scale, rotation and translation matrices
+         * @param startValue defines the first matrix
+         * @param endValue defines the second matrix
+         * @param gradient defines the gradient between the two matrices
+         * @param result defines the target matrix
+         */
+        public static DecomposeLerpToRef(startValue: Matrix, endValue: Matrix, gradient: number, result: Matrix) {
+            var startScale = MathTmp.Vector3[0];
+            var startRotation = MathTmp.Quaternion[0];
+            var startTranslation = MathTmp.Vector3[1];
             startValue.decompose(startScale, startRotation, startTranslation);
             startValue.decompose(startScale, startRotation, startTranslation);
 
 
-            var endScale = new Vector3(0, 0, 0);
-            var endRotation = new Quaternion();
-            var endTranslation = new Vector3(0, 0, 0);
+            var endScale = MathTmp.Vector3[2];
+            var endRotation = MathTmp.Quaternion[1];
+            var endTranslation = MathTmp.Vector3[3];
             endValue.decompose(endScale, endRotation, endTranslation);
             endValue.decompose(endScale, endRotation, endTranslation);
 
 
-            var resultScale = Vector3.Lerp(startScale, endScale, gradient);
-            var resultRotation = Quaternion.Slerp(startRotation, endRotation, gradient);
-            var resultTranslation = Vector3.Lerp(startTranslation, endTranslation, gradient);
+            var resultScale = MathTmp.Vector3[4];
+            Vector3.LerpToRef(startScale, endScale, gradient, resultScale);
+            var resultRotation = MathTmp.Quaternion[2];
+            Quaternion.SlerpToRef(startRotation, endRotation, gradient, resultRotation);
+            
+            var resultTranslation = MathTmp.Vector3[5];
+            Vector3.LerpToRef(startTranslation, endTranslation, gradient, resultTranslation);
 
 
-            return Matrix.Compose(resultScale, resultRotation, resultTranslation);
-        }
+            Matrix.ComposeToRef(resultScale, resultRotation, resultTranslation, result);
+        }        
 
 
         /**
         /**
          * Gets a new rotation matrix used to rotate an entity so as it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up"
          * Gets a new rotation matrix used to rotate an entity so as it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up"
@@ -6264,8 +6288,8 @@
     }
     }
     // Same as Tmp but not exported to keep it onyl for math functions to avoid conflicts
     // Same as Tmp but not exported to keep it onyl for math functions to avoid conflicts
     class MathTmp {
     class MathTmp {
-        public static Vector3: Vector3[] = [Vector3.Zero()];
+        public static Vector3: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
         public static Matrix: Matrix[] = [Matrix.Zero(), Matrix.Zero()];
         public static Matrix: Matrix[] = [Matrix.Zero(), Matrix.Zero()];
-        public static Quaternion: Quaternion[] = [Quaternion.Zero()];
+        public static Quaternion: Quaternion[] = [Quaternion.Zero(), Quaternion.Zero(), Quaternion.Zero()];
     }
     }
 }
 }

+ 30 - 10
src/babylon.scene.ts

@@ -2693,32 +2693,49 @@
                 var target = this._registeredForLateAnimationBindings.data[index];
                 var target = this._registeredForLateAnimationBindings.data[index];
 
 
                 for (var path in target._lateAnimationHolders) {
                 for (var path in target._lateAnimationHolders) {
-                    var holder = target._lateAnimationHolders[path];       
+                    var holder = target._lateAnimationHolders[path];                     
+                    let originalValue = holder.animations[0].originalValue;      
                     
                     
                     // Sanity check
                     // Sanity check
-                    if (!holder.animations[0].originalValue.scaleAndAddToRef) {
+                    if (!originalValue.scaleAndAddToRef) {
                         continue;
                         continue;
                     }
                     }
 
 
+                    let matrixDecomposeMode = Animation.AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix
                     let normalizer = 1.0;
                     let normalizer = 1.0;
                     let finalValue: any;
                     let finalValue: any;
 
 
                     if (holder.totalWeight < 1.0) {
                     if (holder.totalWeight < 1.0) {
-                        // We need to mix the original value in
-                        let originalValue = holder.animations[0].originalValue;                       
-
-                        finalValue = originalValue.scale(1.0 - holder.totalWeight)
+                        // We need to mix the original value in     
+                        if (matrixDecomposeMode) {
+                            finalValue = originalValue.clone();
+                        } else {            
+                            finalValue = originalValue.scale(1.0 - holder.totalWeight)
+                        }
                     } else {
                     } else {
                         // We need to normalize the weights
                         // We need to normalize the weights
                         normalizer = holder.totalWeight;
                         normalizer = holder.totalWeight;
                     }
                     }
 
 
                     for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
                     for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
-                        var runtimeAnimation = holder.animations[animIndex];    
+                        var runtimeAnimation = holder.animations[animIndex];   
+                        var scale = runtimeAnimation.weight / normalizer;
                         if (finalValue) {
                         if (finalValue) {
-                            runtimeAnimation.currentValue.scaleAndAddToRef(runtimeAnimation.weight / normalizer, finalValue);
+                            if (matrixDecomposeMode) {
+                                Matrix.DecomposeLerpToRef(finalValue, runtimeAnimation.currentValue, scale, finalValue);
+                            } else {
+                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                            }
                         } else {
                         } else {
-                            finalValue = runtimeAnimation.currentValue.scale(runtimeAnimation.weight / normalizer);
+                            if (scale !== 1) {
+                                if (matrixDecomposeMode) {
+                                    finalValue = runtimeAnimation.currentValue.clone();
+                                } else {
+                                    finalValue = runtimeAnimation.currentValue.scale(scale);
+                                }
+                            } else {
+                                finalValue = runtimeAnimation.currentValue;
+                            }
                         }
                         }
                     }
                     }
 
 
@@ -4498,7 +4515,10 @@
                             }
                             }
 
 
                             //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.
                             //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.
-                            if (!sourceMesh.actionManager.hasSpecificTrigger(ActionManager.OnIntersectionExitTrigger) || action.trigger === ActionManager.OnIntersectionExitTrigger) {
+                            if (!sourceMesh.actionManager.hasSpecificTrigger(ActionManager.OnIntersectionExitTrigger, parameter => {
+                                var parameterMesh = parameter instanceof AbstractMesh ? parameter : parameter.mesh;
+                                return otherMesh === parameterMesh;
+                            }) || action.trigger === ActionManager.OnIntersectionExitTrigger) {
                                 sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);
                                 sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);
                             }
                             }
                         }
                         }

BIN
tests/validation/ReferenceImages/enableDisablePostProcess.png