David Catuhe 7 年之前
父節點
當前提交
6d45e1863a

文件差異過大導致無法顯示
+ 13995 - 13986
Playground/babylon.d.txt


文件差異過大導致無法顯示
+ 13985 - 13976
dist/preview release/babylon.d.ts


文件差異過大導致無法顯示
+ 33 - 33
dist/preview release/babylon.js


+ 177 - 84
dist/preview release/babylon.max.js

@@ -4433,6 +4433,18 @@ var BABYLON;
             return this;
         };
         /**
+         * Multiplies in place the current quaternion by a scale factor
+         * @param value defines the scale factor
+         * @returns the current modified quaternion
+         */
+        Quaternion.prototype.scaleInPlace = function (value) {
+            this.x *= value;
+            this.y *= value;
+            this.z *= value;
+            this.w *= value;
+            return this;
+        };
+        /**
          * Scale the current quaternion values by a factor and add the result to a given quaternion
          * @param scale defines the scale factor
          * @param result defines the Quaternion object where to store the result
@@ -5293,20 +5305,23 @@ var BABYLON;
                 translation.y = this.m[13];
                 translation.z = this.m[14];
             }
+            scale = scale || MathTmp.Vector3[0];
             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.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) {
                 scale.y *= -1;
             }
-            if (rotation) {
-                if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+            if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+                if (rotation) {
                     rotation.x = 0;
                     rotation.y = 0;
                     rotation.z = 0;
                     rotation.w = 1;
-                    return false;
                 }
+                return false;
+            }
+            if (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);
             }
@@ -5441,13 +5456,18 @@ var BABYLON;
          */
         Matrix.prototype.getRotationMatrixToRef = function (result) {
             var m = this.m;
-            var xs = m[0] * m[1] * m[2] * m[3] < 0 ? -1 : 1;
-            var ys = m[4] * m[5] * m[6] * m[7] < 0 ? -1 : 1;
-            var zs = m[8] * m[9] * m[10] * m[11] < 0 ? -1 : 1;
-            var sx = xs * Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
-            var sy = ys * Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);
-            var sz = zs * Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);
-            Matrix.FromValuesToRef(m[0] / sx, m[1] / sx, m[2] / sx, 0, m[4] / sy, m[5] / sy, m[6] / sy, 0, m[8] / sz, m[9] / sz, m[10] / sz, 0, 0, 0, 0, 1, result);
+            var sx = Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
+            var sy = Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);
+            var sz = Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);
+            if (this.determinant() <= 0) {
+                sy *= -1;
+            }
+            if (sx === 0 || sy === 0 || sz === 0) {
+                Matrix.IdentityToRef(result);
+            }
+            else {
+                Matrix.FromValuesToRef(m[0] / sx, m[1] / sx, m[2] / sx, 0, m[4] / sy, m[5] / sy, m[6] / sy, 0, m[8] / sz, m[9] / sz, m[10] / sz, 0, 0, 0, 0, 1, result);
+            }
             return this;
         };
         // Statics
@@ -25438,6 +25458,46 @@ var BABYLON;
             target._lateAnimationHolders[runtimeAnimation.targetPath].animations.push(runtimeAnimation);
             target._lateAnimationHolders[runtimeAnimation.targetPath].totalWeight += runtimeAnimation.weight;
         };
+        Scene.prototype._processLateAnimationBindingsForMatrices = function (holder, originalValue) {
+            var normalizer = 1.0;
+            var finalPosition = BABYLON.Tmp.Vector3[0];
+            var finalScaling = BABYLON.Tmp.Vector3[1];
+            var finalQuaternion = BABYLON.Tmp.Quaternion[0];
+            var startIndex = 0;
+            var originalAnimation = holder.animations[0];
+            var scale = 1;
+            if (holder.totalWeight < 1.0) {
+                // We need to mix the original value in                     
+                originalValue.decompose(finalScaling, finalQuaternion, finalPosition);
+                scale = 1.0 - holder.totalWeight;
+            }
+            else {
+                startIndex = 1;
+                // We need to normalize the weights
+                normalizer = holder.totalWeight;
+                originalAnimation.currentValue.decompose(finalScaling, finalQuaternion, finalPosition);
+                scale = originalAnimation.weight / normalizer;
+                if (scale == 1) {
+                    return originalAnimation.currentValue;
+                }
+            }
+            finalScaling.scaleInPlace(scale);
+            finalPosition.scaleInPlace(scale);
+            finalQuaternion.scaleInPlace(scale);
+            for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
+                var runtimeAnimation = holder.animations[animIndex];
+                var scale = runtimeAnimation.weight / normalizer;
+                var currentPosition = BABYLON.Tmp.Vector3[2];
+                var currentScaling = BABYLON.Tmp.Vector3[3];
+                var currentQuaternion = BABYLON.Tmp.Quaternion[1];
+                runtimeAnimation.currentValue.decompose(currentScaling, currentQuaternion, currentPosition);
+                currentScaling.scaleAndAddToRef(scale, finalScaling);
+                currentQuaternion.scaleAndAddToRef(scale, finalQuaternion);
+                currentPosition.scaleAndAddToRef(scale, finalPosition);
+            }
+            BABYLON.Matrix.ComposeToRef(finalScaling, finalQuaternion, finalPosition, originalAnimation._workValue);
+            return originalAnimation._workValue;
+        };
         Scene.prototype._processLateAnimationBindings = function () {
             if (!this._registeredForLateAnimationBindings.length) {
                 return;
@@ -25446,53 +25506,55 @@ var BABYLON;
                 var target = this._registeredForLateAnimationBindings.data[index];
                 for (var path in target._lateAnimationHolders) {
                     var holder = target._lateAnimationHolders[path];
-                    var originalValue = holder.animations[0].originalValue;
-                    // Sanity check
-                    if (!originalValue.scaleAndAddToRef) {
-                        continue;
-                    }
+                    var originalAnimation = holder.animations[0];
+                    var originalValue = originalAnimation.originalValue;
+                    var finalTarget = originalAnimation.target;
                     var matrixDecomposeMode = BABYLON.Animation.AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix
-                    var normalizer = 1.0;
                     var finalValue = void 0;
-                    if (holder.totalWeight < 1.0) {
-                        // We need to mix the original value in     
-                        if (matrixDecomposeMode) {
-                            finalValue = originalValue.clone();
-                        }
-                        else {
-                            finalValue = originalValue.scale(1.0 - holder.totalWeight);
-                        }
+                    if (matrixDecomposeMode) {
+                        finalValue = this._processLateAnimationBindingsForMatrices(holder, originalValue);
                     }
                     else {
-                        // We need to normalize the weights
-                        normalizer = holder.totalWeight;
-                    }
-                    for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
-                        var runtimeAnimation = holder.animations[animIndex];
-                        var scale = runtimeAnimation.weight / normalizer;
-                        if (finalValue) {
-                            if (matrixDecomposeMode) {
-                                BABYLON.Matrix.DecomposeLerpToRef(finalValue, runtimeAnimation.currentValue, scale, finalValue);
+                        var startIndex = 0;
+                        var normalizer = 1.0;
+                        if (holder.totalWeight < 1.0) {
+                            // We need to mix the original value in     
+                            if (originalValue.scale) {
+                                finalValue = originalValue.scale(1.0 - holder.totalWeight);
                             }
                             else {
-                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                                finalValue = originalValue * (1.0 - holder.totalWeight);
                             }
                         }
                         else {
-                            if (scale !== 1) {
-                                if (matrixDecomposeMode) {
-                                    finalValue = runtimeAnimation.currentValue.clone();
+                            // We need to normalize the weights
+                            normalizer = holder.totalWeight;
+                            var scale_1 = originalAnimation.weight / normalizer;
+                            if (scale_1 !== 1) {
+                                if (originalAnimation.currentValue.scale) {
+                                    finalValue = originalAnimation.currentValue.scale(scale_1);
                                 }
                                 else {
-                                    finalValue = runtimeAnimation.currentValue.scale(scale);
+                                    finalValue = originalAnimation.currentValue * scale_1;
                                 }
                             }
                             else {
-                                finalValue = runtimeAnimation.currentValue;
+                                finalValue = originalAnimation.currentValue;
+                            }
+                            startIndex = 1;
+                        }
+                        for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
+                            var runtimeAnimation = holder.animations[animIndex];
+                            var scale = runtimeAnimation.weight / normalizer;
+                            if (runtimeAnimation.currentValue.scaleAndAddToRef) {
+                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                            }
+                            else {
+                                finalValue += runtimeAnimation.currentValue * scale;
                             }
                         }
                     }
-                    runtimeAnimation.target[path] = finalValue;
+                    finalTarget[path] = finalValue;
                 }
                 target._lateAnimationHolders = {};
             }
@@ -51055,12 +51117,24 @@ var BABYLON;
          */
         RuntimeAnimation.prototype.setValue = function (currentValue, weight) {
             if (weight === void 0) { weight = 1.0; }
+            if (this._target instanceof Array) {
+                for (var _i = 0, _a = this._target; _i < _a.length; _i++) {
+                    var target = _a[_i];
+                    this._setValue(target, currentValue, weight);
+                }
+            }
+            else {
+                this._setValue(this._target, currentValue, weight);
+            }
+        };
+        RuntimeAnimation.prototype._setValue = function (target, currentValue, weight) {
+            if (weight === void 0) { weight = 1.0; }
             // Set value
             var path;
             var destination;
             var targetPropertyPath = this._animation.targetPropertyPath;
             if (targetPropertyPath.length > 1) {
-                var property = this._target[targetPropertyPath[0]];
+                var property = target[targetPropertyPath[0]];
                 for (var index = 1; index < targetPropertyPath.length - 1; index++) {
                     property = property[targetPropertyPath[index]];
                 }
@@ -51069,14 +51143,14 @@ var BABYLON;
             }
             else {
                 path = targetPropertyPath[0];
-                destination = this._target;
+                destination = target;
             }
             this._targetPath = path;
             this._activeTarget = destination;
             this._weight = weight;
             // Blending
-            var enableBlending = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;
-            var blendingSpeed = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
+            var enableBlending = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;
+            var blendingSpeed = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
             if (enableBlending && this._blendingFactor <= 1.0) {
                 if (!this._originalBlendValue) {
                     var originalValue = destination[path];
@@ -51146,8 +51220,8 @@ var BABYLON;
             else {
                 destination[path] = this._currentValue;
             }
-            if (this._target.markAsDirty) {
-                this._target.markAsDirty(this._animation.targetProperty);
+            if (target.markAsDirty) {
+                target.markAsDirty(this._animation.targetProperty);
             }
         };
         RuntimeAnimation.prototype._getCorrectLoopMode = function () {
@@ -51359,11 +51433,11 @@ var BABYLON;
             this._speedRatio = 1;
             this._weight = -1.0;
             this.animationStarted = false;
+            this._scene = scene;
             if (animations) {
                 this.appendAnimations(target, animations);
             }
             this._speedRatio = speedRatio;
-            this._scene = scene;
             scene._activeAnimatables.push(this);
         }
         Object.defineProperty(Animatable.prototype, "syncRoot", {
@@ -76661,7 +76735,7 @@ var BABYLON;
             _this._negateScaleChildren = BABYLON.Vector3.One();
             _this._scalingDeterminant = 1;
             _this._skeleton = skeleton;
-            _this._localMatrix = localMatrix ? localMatrix : BABYLON.Matrix.Identity();
+            _this._localMatrix = localMatrix ? localMatrix.clone() : BABYLON.Matrix.Identity();
             _this._restPose = restPose ? restPose : _this._localMatrix.clone();
             _this._baseMatrix = baseMatrix ? baseMatrix : _this._localMatrix.clone();
             _this._index = index;
@@ -76674,13 +76748,8 @@ var BABYLON;
             get: function () {
                 return this._localMatrix;
             },
-            set: function (val) {
-                if (this._localMatrix) {
-                    this._localMatrix.copyFrom(val);
-                }
-                else {
-                    this._localMatrix = val;
-                }
+            set: function (value) {
+                this._localMatrix.copyFrom(value);
             },
             enumerable: true,
             configurable: true
@@ -76710,6 +76779,7 @@ var BABYLON;
             if (updateDifferenceMatrix) {
                 this._updateDifferenceMatrix();
             }
+            this.markAsDirty();
         };
         Bone.prototype.getLocalMatrix = function () {
             return this._localMatrix;
@@ -76765,10 +76835,14 @@ var BABYLON;
         });
         Object.defineProperty(Bone.prototype, "scaling", {
             get: function () {
-                return this.getScale();
+                var value = BABYLON.Vector3.One();
+                this._localMatrix.decompose(value, undefined, undefined);
+                return value;
             },
             set: function (newScaling) {
-                this.setScale(newScaling.x, newScaling.y, newScaling.z);
+                this._localMatrix.decompose(undefined, Bone._tmpQuat, Bone._tmpVecs[0]);
+                BABYLON.Matrix.ComposeToRef(newScaling, Bone._tmpQuat, Bone._tmpVecs[0], this._localMatrix);
+                this.markAsDirty();
             },
             enumerable: true,
             configurable: true
@@ -76786,12 +76860,12 @@ var BABYLON;
         // Methods
         Bone.prototype.updateMatrix = function (matrix, updateDifferenceMatrix) {
             if (updateDifferenceMatrix === void 0) { updateDifferenceMatrix = true; }
-            this._baseMatrix = matrix.clone();
-            this._localMatrix = matrix.clone();
-            this._skeleton._markAsDirty();
+            this._baseMatrix.copyFrom(matrix);
+            this._localMatrix.copyFrom(matrix);
             if (updateDifferenceMatrix) {
                 this._updateDifferenceMatrix();
             }
+            this.markAsDirty();
         };
         Bone.prototype._updateDifferenceMatrix = function (rootMatrix) {
             if (!rootMatrix) {
@@ -76963,13 +77037,13 @@ var BABYLON;
             this.setPosition(position, BABYLON.Space.WORLD, mesh);
         };
         /**
-         * Set the scale of the bone on the x, y and z axes.
-         * @param x The scale of the bone on the x axis.
-         * @param x The scale of the bone on the y axis.
-         * @param z The scale of the bone on the z axis.
+         * Adds an additional scale to the bone on the x, y and z axes.
+         * @param x The additional scale of the bone on the x axis.
+         * @param y The additional scale of the bone on the y axis.
+         * @param z The additional scale of the bone on the z axis.
          * @param scaleChildren Set this to true if children of the bone should be scaled.
          */
-        Bone.prototype.setScale = function (x, y, z, scaleChildren) {
+        Bone.prototype.setAdditionalScale = function (x, y, z, scaleChildren) {
             if (scaleChildren === void 0) { scaleChildren = false; }
             if (this.animations[0] && !this.animations[0].hasRunningRuntimeAnimations) {
                 if (!scaleChildren) {
@@ -76997,7 +77071,7 @@ var BABYLON;
             origLocMatInv.copyFrom(origLocMat);
             origLocMatInv.invert();
             var scaleMat = Bone._tmpMats[2];
-            BABYLON.Matrix.FromValuesToRef(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1, scaleMat);
+            BABYLON.Matrix.ScalingToRef(x, y, z, scaleMat);
             this._scaleMatrix.multiplyToRef(scaleMat, this._scaleMatrix);
             this._scaleVector.x *= x;
             this._scaleVector.y *= y;
@@ -77041,10 +77115,12 @@ var BABYLON;
          */
         Bone.prototype.setYawPitchRoll = function (yaw, pitch, roll, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
-            var rotMat = Bone._tmpMats[0];
+            var rotMatInv = Bone._tmpMats[0];
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
+            var rotMat = Bone._tmpMats[1];
             BABYLON.Matrix.RotationYawPitchRollToRef(yaw, pitch, roll, rotMat);
-            var rotMatInv = Bone._tmpMats[1];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
             rotMatInv.multiplyToRef(rotMat, rotMat);
             this._rotateWithMatrix(rotMat, space, mesh);
         };
@@ -77073,10 +77149,12 @@ var BABYLON;
          */
         Bone.prototype.setAxisAngle = function (axis, angle, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
-            var rotMat = Bone._tmpMats[0];
+            var rotMatInv = Bone._tmpMats[0];
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
+            var rotMat = Bone._tmpMats[1];
             BABYLON.Matrix.RotationAxisToRef(axis, angle, rotMat);
-            var rotMatInv = Bone._tmpMats[1];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
             rotMatInv.multiplyToRef(rotMat, rotMat);
             this._rotateWithMatrix(rotMat, space, mesh);
         };
@@ -77099,7 +77177,9 @@ var BABYLON;
         Bone.prototype.setRotationQuaternion = function (quat, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
             var rotMatInv = Bone._tmpMats[0];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
             var rotMat = Bone._tmpMats[1];
             BABYLON.Matrix.FromQuaternionToRef(quat, rotMat);
             rotMatInv.multiplyToRef(rotMat, rotMat);
@@ -77114,7 +77194,9 @@ var BABYLON;
         Bone.prototype.setRotationMatrix = function (rotMat, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
             var rotMatInv = Bone._tmpMats[0];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
             var rotMat2 = Bone._tmpMats[1];
             rotMat2.copyFrom(rotMat);
             rotMatInv.multiplyToRef(rotMat, rotMat2);
@@ -77180,12 +77262,22 @@ var BABYLON;
                     scaleMatrix.multiplyToRef(meshScale, scaleMatrix);
                 }
                 rotMatInv.invert();
+                if (isNaN(rotMatInv.m[0])) {
+                    // Matrix failed to invert.
+                    // This can happen if scale is zero for example.
+                    return false;
+                }
                 scaleMatrix.m[0] *= this._scalingDeterminant;
                 rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);
             }
             else {
                 rotMatInv.copyFrom(this.getLocalMatrix());
                 rotMatInv.invert();
+                if (isNaN(rotMatInv.m[0])) {
+                    // Matrix failed to invert.
+                    // This can happen if scale is zero for example.
+                    return false;
+                }
                 var scaleMatrix = Bone._tmpMats[2];
                 scaleMatrix.copyFrom(this._scaleMatrix);
                 if (this._parent) {
@@ -77199,19 +77291,20 @@ var BABYLON;
                 }
                 rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);
             }
+            return true;
         };
         /**
-         * Get the scale of the bone
-         * @returns the scale of the bone
+         * Get the additional scale of the bone
+         * @returns the additional scale of the bone
          */
-        Bone.prototype.getScale = function () {
+        Bone.prototype.getAdditionalScale = function () {
             return this._scaleVector.clone();
         };
         /**
-         * Copy the scale of the bone to a vector3.
-         * @param result The vector3 to copy the scale to
+         * Copy the additional scale of the bone to a vector3.
+         * @param result The vector3 to copy the additional scale to
          */
-        Bone.prototype.getScaleToRef = function (result) {
+        Bone.prototype.getAdditionalScaleToRef = function (result) {
             result.copyFrom(this._scaleVector);
         };
         /**
@@ -77401,7 +77494,7 @@ var BABYLON;
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
             if (mesh === void 0) { mesh = null; }
             if (space == BABYLON.Space.LOCAL) {
-                this.getLocalMatrix().decompose(Bone._tmpVecs[0], result, Bone._tmpVecs[1]);
+                this.getLocalMatrix().decompose(undefined, result, undefined);
             }
             else {
                 var mat = Bone._tmpMats[0];
@@ -77415,7 +77508,7 @@ var BABYLON;
                 mat.m[0] *= this._scalingDeterminant;
                 mat.m[1] *= this._scalingDeterminant;
                 mat.m[2] *= this._scalingDeterminant;
-                mat.decompose(Bone._tmpVecs[0], result, Bone._tmpVecs[1]);
+                mat.decompose(undefined, result, undefined);
             }
         };
         /**
@@ -77572,8 +77665,8 @@ var BABYLON;
                 }
             }
             if (this._bone1.length) {
-                var boneScale1 = this._bone1.getScale();
-                var boneScale2 = this._bone2.getScale();
+                var boneScale1 = this._bone1.getAdditionalScale();
+                var boneScale2 = this._bone2.getAdditionalScale();
                 this._bone1Length = this._bone1.length * boneScale1.y * this.mesh.scaling.y;
                 this._bone2Length = this._bone2.length * boneScale2.y * this.mesh.scaling.y;
             }

+ 177 - 84
dist/preview release/babylon.no-module.max.js

@@ -4400,6 +4400,18 @@ var BABYLON;
             return this;
         };
         /**
+         * Multiplies in place the current quaternion by a scale factor
+         * @param value defines the scale factor
+         * @returns the current modified quaternion
+         */
+        Quaternion.prototype.scaleInPlace = function (value) {
+            this.x *= value;
+            this.y *= value;
+            this.z *= value;
+            this.w *= value;
+            return this;
+        };
+        /**
          * Scale the current quaternion values by a factor and add the result to a given quaternion
          * @param scale defines the scale factor
          * @param result defines the Quaternion object where to store the result
@@ -5260,20 +5272,23 @@ var BABYLON;
                 translation.y = this.m[13];
                 translation.z = this.m[14];
             }
+            scale = scale || MathTmp.Vector3[0];
             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.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) {
                 scale.y *= -1;
             }
-            if (rotation) {
-                if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+            if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+                if (rotation) {
                     rotation.x = 0;
                     rotation.y = 0;
                     rotation.z = 0;
                     rotation.w = 1;
-                    return false;
                 }
+                return false;
+            }
+            if (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);
             }
@@ -5408,13 +5423,18 @@ var BABYLON;
          */
         Matrix.prototype.getRotationMatrixToRef = function (result) {
             var m = this.m;
-            var xs = m[0] * m[1] * m[2] * m[3] < 0 ? -1 : 1;
-            var ys = m[4] * m[5] * m[6] * m[7] < 0 ? -1 : 1;
-            var zs = m[8] * m[9] * m[10] * m[11] < 0 ? -1 : 1;
-            var sx = xs * Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
-            var sy = ys * Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);
-            var sz = zs * Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);
-            Matrix.FromValuesToRef(m[0] / sx, m[1] / sx, m[2] / sx, 0, m[4] / sy, m[5] / sy, m[6] / sy, 0, m[8] / sz, m[9] / sz, m[10] / sz, 0, 0, 0, 0, 1, result);
+            var sx = Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
+            var sy = Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);
+            var sz = Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);
+            if (this.determinant() <= 0) {
+                sy *= -1;
+            }
+            if (sx === 0 || sy === 0 || sz === 0) {
+                Matrix.IdentityToRef(result);
+            }
+            else {
+                Matrix.FromValuesToRef(m[0] / sx, m[1] / sx, m[2] / sx, 0, m[4] / sy, m[5] / sy, m[6] / sy, 0, m[8] / sz, m[9] / sz, m[10] / sz, 0, 0, 0, 0, 1, result);
+            }
             return this;
         };
         // Statics
@@ -25405,6 +25425,46 @@ var BABYLON;
             target._lateAnimationHolders[runtimeAnimation.targetPath].animations.push(runtimeAnimation);
             target._lateAnimationHolders[runtimeAnimation.targetPath].totalWeight += runtimeAnimation.weight;
         };
+        Scene.prototype._processLateAnimationBindingsForMatrices = function (holder, originalValue) {
+            var normalizer = 1.0;
+            var finalPosition = BABYLON.Tmp.Vector3[0];
+            var finalScaling = BABYLON.Tmp.Vector3[1];
+            var finalQuaternion = BABYLON.Tmp.Quaternion[0];
+            var startIndex = 0;
+            var originalAnimation = holder.animations[0];
+            var scale = 1;
+            if (holder.totalWeight < 1.0) {
+                // We need to mix the original value in                     
+                originalValue.decompose(finalScaling, finalQuaternion, finalPosition);
+                scale = 1.0 - holder.totalWeight;
+            }
+            else {
+                startIndex = 1;
+                // We need to normalize the weights
+                normalizer = holder.totalWeight;
+                originalAnimation.currentValue.decompose(finalScaling, finalQuaternion, finalPosition);
+                scale = originalAnimation.weight / normalizer;
+                if (scale == 1) {
+                    return originalAnimation.currentValue;
+                }
+            }
+            finalScaling.scaleInPlace(scale);
+            finalPosition.scaleInPlace(scale);
+            finalQuaternion.scaleInPlace(scale);
+            for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
+                var runtimeAnimation = holder.animations[animIndex];
+                var scale = runtimeAnimation.weight / normalizer;
+                var currentPosition = BABYLON.Tmp.Vector3[2];
+                var currentScaling = BABYLON.Tmp.Vector3[3];
+                var currentQuaternion = BABYLON.Tmp.Quaternion[1];
+                runtimeAnimation.currentValue.decompose(currentScaling, currentQuaternion, currentPosition);
+                currentScaling.scaleAndAddToRef(scale, finalScaling);
+                currentQuaternion.scaleAndAddToRef(scale, finalQuaternion);
+                currentPosition.scaleAndAddToRef(scale, finalPosition);
+            }
+            BABYLON.Matrix.ComposeToRef(finalScaling, finalQuaternion, finalPosition, originalAnimation._workValue);
+            return originalAnimation._workValue;
+        };
         Scene.prototype._processLateAnimationBindings = function () {
             if (!this._registeredForLateAnimationBindings.length) {
                 return;
@@ -25413,53 +25473,55 @@ var BABYLON;
                 var target = this._registeredForLateAnimationBindings.data[index];
                 for (var path in target._lateAnimationHolders) {
                     var holder = target._lateAnimationHolders[path];
-                    var originalValue = holder.animations[0].originalValue;
-                    // Sanity check
-                    if (!originalValue.scaleAndAddToRef) {
-                        continue;
-                    }
+                    var originalAnimation = holder.animations[0];
+                    var originalValue = originalAnimation.originalValue;
+                    var finalTarget = originalAnimation.target;
                     var matrixDecomposeMode = BABYLON.Animation.AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix
-                    var normalizer = 1.0;
                     var finalValue = void 0;
-                    if (holder.totalWeight < 1.0) {
-                        // We need to mix the original value in     
-                        if (matrixDecomposeMode) {
-                            finalValue = originalValue.clone();
-                        }
-                        else {
-                            finalValue = originalValue.scale(1.0 - holder.totalWeight);
-                        }
+                    if (matrixDecomposeMode) {
+                        finalValue = this._processLateAnimationBindingsForMatrices(holder, originalValue);
                     }
                     else {
-                        // We need to normalize the weights
-                        normalizer = holder.totalWeight;
-                    }
-                    for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
-                        var runtimeAnimation = holder.animations[animIndex];
-                        var scale = runtimeAnimation.weight / normalizer;
-                        if (finalValue) {
-                            if (matrixDecomposeMode) {
-                                BABYLON.Matrix.DecomposeLerpToRef(finalValue, runtimeAnimation.currentValue, scale, finalValue);
+                        var startIndex = 0;
+                        var normalizer = 1.0;
+                        if (holder.totalWeight < 1.0) {
+                            // We need to mix the original value in     
+                            if (originalValue.scale) {
+                                finalValue = originalValue.scale(1.0 - holder.totalWeight);
                             }
                             else {
-                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                                finalValue = originalValue * (1.0 - holder.totalWeight);
                             }
                         }
                         else {
-                            if (scale !== 1) {
-                                if (matrixDecomposeMode) {
-                                    finalValue = runtimeAnimation.currentValue.clone();
+                            // We need to normalize the weights
+                            normalizer = holder.totalWeight;
+                            var scale_1 = originalAnimation.weight / normalizer;
+                            if (scale_1 !== 1) {
+                                if (originalAnimation.currentValue.scale) {
+                                    finalValue = originalAnimation.currentValue.scale(scale_1);
                                 }
                                 else {
-                                    finalValue = runtimeAnimation.currentValue.scale(scale);
+                                    finalValue = originalAnimation.currentValue * scale_1;
                                 }
                             }
                             else {
-                                finalValue = runtimeAnimation.currentValue;
+                                finalValue = originalAnimation.currentValue;
+                            }
+                            startIndex = 1;
+                        }
+                        for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
+                            var runtimeAnimation = holder.animations[animIndex];
+                            var scale = runtimeAnimation.weight / normalizer;
+                            if (runtimeAnimation.currentValue.scaleAndAddToRef) {
+                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                            }
+                            else {
+                                finalValue += runtimeAnimation.currentValue * scale;
                             }
                         }
                     }
-                    runtimeAnimation.target[path] = finalValue;
+                    finalTarget[path] = finalValue;
                 }
                 target._lateAnimationHolders = {};
             }
@@ -51022,12 +51084,24 @@ var BABYLON;
          */
         RuntimeAnimation.prototype.setValue = function (currentValue, weight) {
             if (weight === void 0) { weight = 1.0; }
+            if (this._target instanceof Array) {
+                for (var _i = 0, _a = this._target; _i < _a.length; _i++) {
+                    var target = _a[_i];
+                    this._setValue(target, currentValue, weight);
+                }
+            }
+            else {
+                this._setValue(this._target, currentValue, weight);
+            }
+        };
+        RuntimeAnimation.prototype._setValue = function (target, currentValue, weight) {
+            if (weight === void 0) { weight = 1.0; }
             // Set value
             var path;
             var destination;
             var targetPropertyPath = this._animation.targetPropertyPath;
             if (targetPropertyPath.length > 1) {
-                var property = this._target[targetPropertyPath[0]];
+                var property = target[targetPropertyPath[0]];
                 for (var index = 1; index < targetPropertyPath.length - 1; index++) {
                     property = property[targetPropertyPath[index]];
                 }
@@ -51036,14 +51110,14 @@ var BABYLON;
             }
             else {
                 path = targetPropertyPath[0];
-                destination = this._target;
+                destination = target;
             }
             this._targetPath = path;
             this._activeTarget = destination;
             this._weight = weight;
             // Blending
-            var enableBlending = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;
-            var blendingSpeed = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
+            var enableBlending = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;
+            var blendingSpeed = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
             if (enableBlending && this._blendingFactor <= 1.0) {
                 if (!this._originalBlendValue) {
                     var originalValue = destination[path];
@@ -51113,8 +51187,8 @@ var BABYLON;
             else {
                 destination[path] = this._currentValue;
             }
-            if (this._target.markAsDirty) {
-                this._target.markAsDirty(this._animation.targetProperty);
+            if (target.markAsDirty) {
+                target.markAsDirty(this._animation.targetProperty);
             }
         };
         RuntimeAnimation.prototype._getCorrectLoopMode = function () {
@@ -51326,11 +51400,11 @@ var BABYLON;
             this._speedRatio = 1;
             this._weight = -1.0;
             this.animationStarted = false;
+            this._scene = scene;
             if (animations) {
                 this.appendAnimations(target, animations);
             }
             this._speedRatio = speedRatio;
-            this._scene = scene;
             scene._activeAnimatables.push(this);
         }
         Object.defineProperty(Animatable.prototype, "syncRoot", {
@@ -76628,7 +76702,7 @@ var BABYLON;
             _this._negateScaleChildren = BABYLON.Vector3.One();
             _this._scalingDeterminant = 1;
             _this._skeleton = skeleton;
-            _this._localMatrix = localMatrix ? localMatrix : BABYLON.Matrix.Identity();
+            _this._localMatrix = localMatrix ? localMatrix.clone() : BABYLON.Matrix.Identity();
             _this._restPose = restPose ? restPose : _this._localMatrix.clone();
             _this._baseMatrix = baseMatrix ? baseMatrix : _this._localMatrix.clone();
             _this._index = index;
@@ -76641,13 +76715,8 @@ var BABYLON;
             get: function () {
                 return this._localMatrix;
             },
-            set: function (val) {
-                if (this._localMatrix) {
-                    this._localMatrix.copyFrom(val);
-                }
-                else {
-                    this._localMatrix = val;
-                }
+            set: function (value) {
+                this._localMatrix.copyFrom(value);
             },
             enumerable: true,
             configurable: true
@@ -76677,6 +76746,7 @@ var BABYLON;
             if (updateDifferenceMatrix) {
                 this._updateDifferenceMatrix();
             }
+            this.markAsDirty();
         };
         Bone.prototype.getLocalMatrix = function () {
             return this._localMatrix;
@@ -76732,10 +76802,14 @@ var BABYLON;
         });
         Object.defineProperty(Bone.prototype, "scaling", {
             get: function () {
-                return this.getScale();
+                var value = BABYLON.Vector3.One();
+                this._localMatrix.decompose(value, undefined, undefined);
+                return value;
             },
             set: function (newScaling) {
-                this.setScale(newScaling.x, newScaling.y, newScaling.z);
+                this._localMatrix.decompose(undefined, Bone._tmpQuat, Bone._tmpVecs[0]);
+                BABYLON.Matrix.ComposeToRef(newScaling, Bone._tmpQuat, Bone._tmpVecs[0], this._localMatrix);
+                this.markAsDirty();
             },
             enumerable: true,
             configurable: true
@@ -76753,12 +76827,12 @@ var BABYLON;
         // Methods
         Bone.prototype.updateMatrix = function (matrix, updateDifferenceMatrix) {
             if (updateDifferenceMatrix === void 0) { updateDifferenceMatrix = true; }
-            this._baseMatrix = matrix.clone();
-            this._localMatrix = matrix.clone();
-            this._skeleton._markAsDirty();
+            this._baseMatrix.copyFrom(matrix);
+            this._localMatrix.copyFrom(matrix);
             if (updateDifferenceMatrix) {
                 this._updateDifferenceMatrix();
             }
+            this.markAsDirty();
         };
         Bone.prototype._updateDifferenceMatrix = function (rootMatrix) {
             if (!rootMatrix) {
@@ -76930,13 +77004,13 @@ var BABYLON;
             this.setPosition(position, BABYLON.Space.WORLD, mesh);
         };
         /**
-         * Set the scale of the bone on the x, y and z axes.
-         * @param x The scale of the bone on the x axis.
-         * @param x The scale of the bone on the y axis.
-         * @param z The scale of the bone on the z axis.
+         * Adds an additional scale to the bone on the x, y and z axes.
+         * @param x The additional scale of the bone on the x axis.
+         * @param y The additional scale of the bone on the y axis.
+         * @param z The additional scale of the bone on the z axis.
          * @param scaleChildren Set this to true if children of the bone should be scaled.
          */
-        Bone.prototype.setScale = function (x, y, z, scaleChildren) {
+        Bone.prototype.setAdditionalScale = function (x, y, z, scaleChildren) {
             if (scaleChildren === void 0) { scaleChildren = false; }
             if (this.animations[0] && !this.animations[0].hasRunningRuntimeAnimations) {
                 if (!scaleChildren) {
@@ -76964,7 +77038,7 @@ var BABYLON;
             origLocMatInv.copyFrom(origLocMat);
             origLocMatInv.invert();
             var scaleMat = Bone._tmpMats[2];
-            BABYLON.Matrix.FromValuesToRef(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1, scaleMat);
+            BABYLON.Matrix.ScalingToRef(x, y, z, scaleMat);
             this._scaleMatrix.multiplyToRef(scaleMat, this._scaleMatrix);
             this._scaleVector.x *= x;
             this._scaleVector.y *= y;
@@ -77008,10 +77082,12 @@ var BABYLON;
          */
         Bone.prototype.setYawPitchRoll = function (yaw, pitch, roll, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
-            var rotMat = Bone._tmpMats[0];
+            var rotMatInv = Bone._tmpMats[0];
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
+            var rotMat = Bone._tmpMats[1];
             BABYLON.Matrix.RotationYawPitchRollToRef(yaw, pitch, roll, rotMat);
-            var rotMatInv = Bone._tmpMats[1];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
             rotMatInv.multiplyToRef(rotMat, rotMat);
             this._rotateWithMatrix(rotMat, space, mesh);
         };
@@ -77040,10 +77116,12 @@ var BABYLON;
          */
         Bone.prototype.setAxisAngle = function (axis, angle, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
-            var rotMat = Bone._tmpMats[0];
+            var rotMatInv = Bone._tmpMats[0];
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
+            var rotMat = Bone._tmpMats[1];
             BABYLON.Matrix.RotationAxisToRef(axis, angle, rotMat);
-            var rotMatInv = Bone._tmpMats[1];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
             rotMatInv.multiplyToRef(rotMat, rotMat);
             this._rotateWithMatrix(rotMat, space, mesh);
         };
@@ -77066,7 +77144,9 @@ var BABYLON;
         Bone.prototype.setRotationQuaternion = function (quat, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
             var rotMatInv = Bone._tmpMats[0];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
             var rotMat = Bone._tmpMats[1];
             BABYLON.Matrix.FromQuaternionToRef(quat, rotMat);
             rotMatInv.multiplyToRef(rotMat, rotMat);
@@ -77081,7 +77161,9 @@ var BABYLON;
         Bone.prototype.setRotationMatrix = function (rotMat, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
             var rotMatInv = Bone._tmpMats[0];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
             var rotMat2 = Bone._tmpMats[1];
             rotMat2.copyFrom(rotMat);
             rotMatInv.multiplyToRef(rotMat, rotMat2);
@@ -77147,12 +77229,22 @@ var BABYLON;
                     scaleMatrix.multiplyToRef(meshScale, scaleMatrix);
                 }
                 rotMatInv.invert();
+                if (isNaN(rotMatInv.m[0])) {
+                    // Matrix failed to invert.
+                    // This can happen if scale is zero for example.
+                    return false;
+                }
                 scaleMatrix.m[0] *= this._scalingDeterminant;
                 rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);
             }
             else {
                 rotMatInv.copyFrom(this.getLocalMatrix());
                 rotMatInv.invert();
+                if (isNaN(rotMatInv.m[0])) {
+                    // Matrix failed to invert.
+                    // This can happen if scale is zero for example.
+                    return false;
+                }
                 var scaleMatrix = Bone._tmpMats[2];
                 scaleMatrix.copyFrom(this._scaleMatrix);
                 if (this._parent) {
@@ -77166,19 +77258,20 @@ var BABYLON;
                 }
                 rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);
             }
+            return true;
         };
         /**
-         * Get the scale of the bone
-         * @returns the scale of the bone
+         * Get the additional scale of the bone
+         * @returns the additional scale of the bone
          */
-        Bone.prototype.getScale = function () {
+        Bone.prototype.getAdditionalScale = function () {
             return this._scaleVector.clone();
         };
         /**
-         * Copy the scale of the bone to a vector3.
-         * @param result The vector3 to copy the scale to
+         * Copy the additional scale of the bone to a vector3.
+         * @param result The vector3 to copy the additional scale to
          */
-        Bone.prototype.getScaleToRef = function (result) {
+        Bone.prototype.getAdditionalScaleToRef = function (result) {
             result.copyFrom(this._scaleVector);
         };
         /**
@@ -77368,7 +77461,7 @@ var BABYLON;
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
             if (mesh === void 0) { mesh = null; }
             if (space == BABYLON.Space.LOCAL) {
-                this.getLocalMatrix().decompose(Bone._tmpVecs[0], result, Bone._tmpVecs[1]);
+                this.getLocalMatrix().decompose(undefined, result, undefined);
             }
             else {
                 var mat = Bone._tmpMats[0];
@@ -77382,7 +77475,7 @@ var BABYLON;
                 mat.m[0] *= this._scalingDeterminant;
                 mat.m[1] *= this._scalingDeterminant;
                 mat.m[2] *= this._scalingDeterminant;
-                mat.decompose(Bone._tmpVecs[0], result, Bone._tmpVecs[1]);
+                mat.decompose(undefined, result, undefined);
             }
         };
         /**
@@ -77539,8 +77632,8 @@ var BABYLON;
                 }
             }
             if (this._bone1.length) {
-                var boneScale1 = this._bone1.getScale();
-                var boneScale2 = this._bone2.getScale();
+                var boneScale1 = this._bone1.getAdditionalScale();
+                var boneScale2 = this._bone2.getAdditionalScale();
                 this._bone1Length = this._bone1.length * boneScale1.y * this.mesh.scaling.y;
                 this._bone2Length = this._bone2.length * boneScale2.y * this.mesh.scaling.y;
             }

文件差異過大導致無法顯示
+ 39 - 39
dist/preview release/babylon.worker.js


+ 177 - 84
dist/preview release/es6.js

@@ -4400,6 +4400,18 @@ var BABYLON;
             return this;
         };
         /**
+         * Multiplies in place the current quaternion by a scale factor
+         * @param value defines the scale factor
+         * @returns the current modified quaternion
+         */
+        Quaternion.prototype.scaleInPlace = function (value) {
+            this.x *= value;
+            this.y *= value;
+            this.z *= value;
+            this.w *= value;
+            return this;
+        };
+        /**
          * Scale the current quaternion values by a factor and add the result to a given quaternion
          * @param scale defines the scale factor
          * @param result defines the Quaternion object where to store the result
@@ -5260,20 +5272,23 @@ var BABYLON;
                 translation.y = this.m[13];
                 translation.z = this.m[14];
             }
+            scale = scale || MathTmp.Vector3[0];
             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.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) {
                 scale.y *= -1;
             }
-            if (rotation) {
-                if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+            if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+                if (rotation) {
                     rotation.x = 0;
                     rotation.y = 0;
                     rotation.z = 0;
                     rotation.w = 1;
-                    return false;
                 }
+                return false;
+            }
+            if (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);
             }
@@ -5408,13 +5423,18 @@ var BABYLON;
          */
         Matrix.prototype.getRotationMatrixToRef = function (result) {
             var m = this.m;
-            var xs = m[0] * m[1] * m[2] * m[3] < 0 ? -1 : 1;
-            var ys = m[4] * m[5] * m[6] * m[7] < 0 ? -1 : 1;
-            var zs = m[8] * m[9] * m[10] * m[11] < 0 ? -1 : 1;
-            var sx = xs * Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
-            var sy = ys * Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);
-            var sz = zs * Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);
-            Matrix.FromValuesToRef(m[0] / sx, m[1] / sx, m[2] / sx, 0, m[4] / sy, m[5] / sy, m[6] / sy, 0, m[8] / sz, m[9] / sz, m[10] / sz, 0, 0, 0, 0, 1, result);
+            var sx = Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
+            var sy = Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);
+            var sz = Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);
+            if (this.determinant() <= 0) {
+                sy *= -1;
+            }
+            if (sx === 0 || sy === 0 || sz === 0) {
+                Matrix.IdentityToRef(result);
+            }
+            else {
+                Matrix.FromValuesToRef(m[0] / sx, m[1] / sx, m[2] / sx, 0, m[4] / sy, m[5] / sy, m[6] / sy, 0, m[8] / sz, m[9] / sz, m[10] / sz, 0, 0, 0, 0, 1, result);
+            }
             return this;
         };
         // Statics
@@ -25405,6 +25425,46 @@ var BABYLON;
             target._lateAnimationHolders[runtimeAnimation.targetPath].animations.push(runtimeAnimation);
             target._lateAnimationHolders[runtimeAnimation.targetPath].totalWeight += runtimeAnimation.weight;
         };
+        Scene.prototype._processLateAnimationBindingsForMatrices = function (holder, originalValue) {
+            var normalizer = 1.0;
+            var finalPosition = BABYLON.Tmp.Vector3[0];
+            var finalScaling = BABYLON.Tmp.Vector3[1];
+            var finalQuaternion = BABYLON.Tmp.Quaternion[0];
+            var startIndex = 0;
+            var originalAnimation = holder.animations[0];
+            var scale = 1;
+            if (holder.totalWeight < 1.0) {
+                // We need to mix the original value in                     
+                originalValue.decompose(finalScaling, finalQuaternion, finalPosition);
+                scale = 1.0 - holder.totalWeight;
+            }
+            else {
+                startIndex = 1;
+                // We need to normalize the weights
+                normalizer = holder.totalWeight;
+                originalAnimation.currentValue.decompose(finalScaling, finalQuaternion, finalPosition);
+                scale = originalAnimation.weight / normalizer;
+                if (scale == 1) {
+                    return originalAnimation.currentValue;
+                }
+            }
+            finalScaling.scaleInPlace(scale);
+            finalPosition.scaleInPlace(scale);
+            finalQuaternion.scaleInPlace(scale);
+            for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
+                var runtimeAnimation = holder.animations[animIndex];
+                var scale = runtimeAnimation.weight / normalizer;
+                var currentPosition = BABYLON.Tmp.Vector3[2];
+                var currentScaling = BABYLON.Tmp.Vector3[3];
+                var currentQuaternion = BABYLON.Tmp.Quaternion[1];
+                runtimeAnimation.currentValue.decompose(currentScaling, currentQuaternion, currentPosition);
+                currentScaling.scaleAndAddToRef(scale, finalScaling);
+                currentQuaternion.scaleAndAddToRef(scale, finalQuaternion);
+                currentPosition.scaleAndAddToRef(scale, finalPosition);
+            }
+            BABYLON.Matrix.ComposeToRef(finalScaling, finalQuaternion, finalPosition, originalAnimation._workValue);
+            return originalAnimation._workValue;
+        };
         Scene.prototype._processLateAnimationBindings = function () {
             if (!this._registeredForLateAnimationBindings.length) {
                 return;
@@ -25413,53 +25473,55 @@ var BABYLON;
                 var target = this._registeredForLateAnimationBindings.data[index];
                 for (var path in target._lateAnimationHolders) {
                     var holder = target._lateAnimationHolders[path];
-                    var originalValue = holder.animations[0].originalValue;
-                    // Sanity check
-                    if (!originalValue.scaleAndAddToRef) {
-                        continue;
-                    }
+                    var originalAnimation = holder.animations[0];
+                    var originalValue = originalAnimation.originalValue;
+                    var finalTarget = originalAnimation.target;
                     var matrixDecomposeMode = BABYLON.Animation.AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix
-                    var normalizer = 1.0;
                     var finalValue = void 0;
-                    if (holder.totalWeight < 1.0) {
-                        // We need to mix the original value in     
-                        if (matrixDecomposeMode) {
-                            finalValue = originalValue.clone();
-                        }
-                        else {
-                            finalValue = originalValue.scale(1.0 - holder.totalWeight);
-                        }
+                    if (matrixDecomposeMode) {
+                        finalValue = this._processLateAnimationBindingsForMatrices(holder, originalValue);
                     }
                     else {
-                        // We need to normalize the weights
-                        normalizer = holder.totalWeight;
-                    }
-                    for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
-                        var runtimeAnimation = holder.animations[animIndex];
-                        var scale = runtimeAnimation.weight / normalizer;
-                        if (finalValue) {
-                            if (matrixDecomposeMode) {
-                                BABYLON.Matrix.DecomposeLerpToRef(finalValue, runtimeAnimation.currentValue, scale, finalValue);
+                        var startIndex = 0;
+                        var normalizer = 1.0;
+                        if (holder.totalWeight < 1.0) {
+                            // We need to mix the original value in     
+                            if (originalValue.scale) {
+                                finalValue = originalValue.scale(1.0 - holder.totalWeight);
                             }
                             else {
-                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                                finalValue = originalValue * (1.0 - holder.totalWeight);
                             }
                         }
                         else {
-                            if (scale !== 1) {
-                                if (matrixDecomposeMode) {
-                                    finalValue = runtimeAnimation.currentValue.clone();
+                            // We need to normalize the weights
+                            normalizer = holder.totalWeight;
+                            var scale_1 = originalAnimation.weight / normalizer;
+                            if (scale_1 !== 1) {
+                                if (originalAnimation.currentValue.scale) {
+                                    finalValue = originalAnimation.currentValue.scale(scale_1);
                                 }
                                 else {
-                                    finalValue = runtimeAnimation.currentValue.scale(scale);
+                                    finalValue = originalAnimation.currentValue * scale_1;
                                 }
                             }
                             else {
-                                finalValue = runtimeAnimation.currentValue;
+                                finalValue = originalAnimation.currentValue;
+                            }
+                            startIndex = 1;
+                        }
+                        for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
+                            var runtimeAnimation = holder.animations[animIndex];
+                            var scale = runtimeAnimation.weight / normalizer;
+                            if (runtimeAnimation.currentValue.scaleAndAddToRef) {
+                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                            }
+                            else {
+                                finalValue += runtimeAnimation.currentValue * scale;
                             }
                         }
                     }
-                    runtimeAnimation.target[path] = finalValue;
+                    finalTarget[path] = finalValue;
                 }
                 target._lateAnimationHolders = {};
             }
@@ -51022,12 +51084,24 @@ var BABYLON;
          */
         RuntimeAnimation.prototype.setValue = function (currentValue, weight) {
             if (weight === void 0) { weight = 1.0; }
+            if (this._target instanceof Array) {
+                for (var _i = 0, _a = this._target; _i < _a.length; _i++) {
+                    var target = _a[_i];
+                    this._setValue(target, currentValue, weight);
+                }
+            }
+            else {
+                this._setValue(this._target, currentValue, weight);
+            }
+        };
+        RuntimeAnimation.prototype._setValue = function (target, currentValue, weight) {
+            if (weight === void 0) { weight = 1.0; }
             // Set value
             var path;
             var destination;
             var targetPropertyPath = this._animation.targetPropertyPath;
             if (targetPropertyPath.length > 1) {
-                var property = this._target[targetPropertyPath[0]];
+                var property = target[targetPropertyPath[0]];
                 for (var index = 1; index < targetPropertyPath.length - 1; index++) {
                     property = property[targetPropertyPath[index]];
                 }
@@ -51036,14 +51110,14 @@ var BABYLON;
             }
             else {
                 path = targetPropertyPath[0];
-                destination = this._target;
+                destination = target;
             }
             this._targetPath = path;
             this._activeTarget = destination;
             this._weight = weight;
             // Blending
-            var enableBlending = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;
-            var blendingSpeed = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
+            var enableBlending = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;
+            var blendingSpeed = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
             if (enableBlending && this._blendingFactor <= 1.0) {
                 if (!this._originalBlendValue) {
                     var originalValue = destination[path];
@@ -51113,8 +51187,8 @@ var BABYLON;
             else {
                 destination[path] = this._currentValue;
             }
-            if (this._target.markAsDirty) {
-                this._target.markAsDirty(this._animation.targetProperty);
+            if (target.markAsDirty) {
+                target.markAsDirty(this._animation.targetProperty);
             }
         };
         RuntimeAnimation.prototype._getCorrectLoopMode = function () {
@@ -51326,11 +51400,11 @@ var BABYLON;
             this._speedRatio = 1;
             this._weight = -1.0;
             this.animationStarted = false;
+            this._scene = scene;
             if (animations) {
                 this.appendAnimations(target, animations);
             }
             this._speedRatio = speedRatio;
-            this._scene = scene;
             scene._activeAnimatables.push(this);
         }
         Object.defineProperty(Animatable.prototype, "syncRoot", {
@@ -76628,7 +76702,7 @@ var BABYLON;
             _this._negateScaleChildren = BABYLON.Vector3.One();
             _this._scalingDeterminant = 1;
             _this._skeleton = skeleton;
-            _this._localMatrix = localMatrix ? localMatrix : BABYLON.Matrix.Identity();
+            _this._localMatrix = localMatrix ? localMatrix.clone() : BABYLON.Matrix.Identity();
             _this._restPose = restPose ? restPose : _this._localMatrix.clone();
             _this._baseMatrix = baseMatrix ? baseMatrix : _this._localMatrix.clone();
             _this._index = index;
@@ -76641,13 +76715,8 @@ var BABYLON;
             get: function () {
                 return this._localMatrix;
             },
-            set: function (val) {
-                if (this._localMatrix) {
-                    this._localMatrix.copyFrom(val);
-                }
-                else {
-                    this._localMatrix = val;
-                }
+            set: function (value) {
+                this._localMatrix.copyFrom(value);
             },
             enumerable: true,
             configurable: true
@@ -76677,6 +76746,7 @@ var BABYLON;
             if (updateDifferenceMatrix) {
                 this._updateDifferenceMatrix();
             }
+            this.markAsDirty();
         };
         Bone.prototype.getLocalMatrix = function () {
             return this._localMatrix;
@@ -76732,10 +76802,14 @@ var BABYLON;
         });
         Object.defineProperty(Bone.prototype, "scaling", {
             get: function () {
-                return this.getScale();
+                var value = BABYLON.Vector3.One();
+                this._localMatrix.decompose(value, undefined, undefined);
+                return value;
             },
             set: function (newScaling) {
-                this.setScale(newScaling.x, newScaling.y, newScaling.z);
+                this._localMatrix.decompose(undefined, Bone._tmpQuat, Bone._tmpVecs[0]);
+                BABYLON.Matrix.ComposeToRef(newScaling, Bone._tmpQuat, Bone._tmpVecs[0], this._localMatrix);
+                this.markAsDirty();
             },
             enumerable: true,
             configurable: true
@@ -76753,12 +76827,12 @@ var BABYLON;
         // Methods
         Bone.prototype.updateMatrix = function (matrix, updateDifferenceMatrix) {
             if (updateDifferenceMatrix === void 0) { updateDifferenceMatrix = true; }
-            this._baseMatrix = matrix.clone();
-            this._localMatrix = matrix.clone();
-            this._skeleton._markAsDirty();
+            this._baseMatrix.copyFrom(matrix);
+            this._localMatrix.copyFrom(matrix);
             if (updateDifferenceMatrix) {
                 this._updateDifferenceMatrix();
             }
+            this.markAsDirty();
         };
         Bone.prototype._updateDifferenceMatrix = function (rootMatrix) {
             if (!rootMatrix) {
@@ -76930,13 +77004,13 @@ var BABYLON;
             this.setPosition(position, BABYLON.Space.WORLD, mesh);
         };
         /**
-         * Set the scale of the bone on the x, y and z axes.
-         * @param x The scale of the bone on the x axis.
-         * @param x The scale of the bone on the y axis.
-         * @param z The scale of the bone on the z axis.
+         * Adds an additional scale to the bone on the x, y and z axes.
+         * @param x The additional scale of the bone on the x axis.
+         * @param y The additional scale of the bone on the y axis.
+         * @param z The additional scale of the bone on the z axis.
          * @param scaleChildren Set this to true if children of the bone should be scaled.
          */
-        Bone.prototype.setScale = function (x, y, z, scaleChildren) {
+        Bone.prototype.setAdditionalScale = function (x, y, z, scaleChildren) {
             if (scaleChildren === void 0) { scaleChildren = false; }
             if (this.animations[0] && !this.animations[0].hasRunningRuntimeAnimations) {
                 if (!scaleChildren) {
@@ -76964,7 +77038,7 @@ var BABYLON;
             origLocMatInv.copyFrom(origLocMat);
             origLocMatInv.invert();
             var scaleMat = Bone._tmpMats[2];
-            BABYLON.Matrix.FromValuesToRef(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1, scaleMat);
+            BABYLON.Matrix.ScalingToRef(x, y, z, scaleMat);
             this._scaleMatrix.multiplyToRef(scaleMat, this._scaleMatrix);
             this._scaleVector.x *= x;
             this._scaleVector.y *= y;
@@ -77008,10 +77082,12 @@ var BABYLON;
          */
         Bone.prototype.setYawPitchRoll = function (yaw, pitch, roll, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
-            var rotMat = Bone._tmpMats[0];
+            var rotMatInv = Bone._tmpMats[0];
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
+            var rotMat = Bone._tmpMats[1];
             BABYLON.Matrix.RotationYawPitchRollToRef(yaw, pitch, roll, rotMat);
-            var rotMatInv = Bone._tmpMats[1];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
             rotMatInv.multiplyToRef(rotMat, rotMat);
             this._rotateWithMatrix(rotMat, space, mesh);
         };
@@ -77040,10 +77116,12 @@ var BABYLON;
          */
         Bone.prototype.setAxisAngle = function (axis, angle, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
-            var rotMat = Bone._tmpMats[0];
+            var rotMatInv = Bone._tmpMats[0];
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
+            var rotMat = Bone._tmpMats[1];
             BABYLON.Matrix.RotationAxisToRef(axis, angle, rotMat);
-            var rotMatInv = Bone._tmpMats[1];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
             rotMatInv.multiplyToRef(rotMat, rotMat);
             this._rotateWithMatrix(rotMat, space, mesh);
         };
@@ -77066,7 +77144,9 @@ var BABYLON;
         Bone.prototype.setRotationQuaternion = function (quat, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
             var rotMatInv = Bone._tmpMats[0];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
             var rotMat = Bone._tmpMats[1];
             BABYLON.Matrix.FromQuaternionToRef(quat, rotMat);
             rotMatInv.multiplyToRef(rotMat, rotMat);
@@ -77081,7 +77161,9 @@ var BABYLON;
         Bone.prototype.setRotationMatrix = function (rotMat, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
             var rotMatInv = Bone._tmpMats[0];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
             var rotMat2 = Bone._tmpMats[1];
             rotMat2.copyFrom(rotMat);
             rotMatInv.multiplyToRef(rotMat, rotMat2);
@@ -77147,12 +77229,22 @@ var BABYLON;
                     scaleMatrix.multiplyToRef(meshScale, scaleMatrix);
                 }
                 rotMatInv.invert();
+                if (isNaN(rotMatInv.m[0])) {
+                    // Matrix failed to invert.
+                    // This can happen if scale is zero for example.
+                    return false;
+                }
                 scaleMatrix.m[0] *= this._scalingDeterminant;
                 rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);
             }
             else {
                 rotMatInv.copyFrom(this.getLocalMatrix());
                 rotMatInv.invert();
+                if (isNaN(rotMatInv.m[0])) {
+                    // Matrix failed to invert.
+                    // This can happen if scale is zero for example.
+                    return false;
+                }
                 var scaleMatrix = Bone._tmpMats[2];
                 scaleMatrix.copyFrom(this._scaleMatrix);
                 if (this._parent) {
@@ -77166,19 +77258,20 @@ var BABYLON;
                 }
                 rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);
             }
+            return true;
         };
         /**
-         * Get the scale of the bone
-         * @returns the scale of the bone
+         * Get the additional scale of the bone
+         * @returns the additional scale of the bone
          */
-        Bone.prototype.getScale = function () {
+        Bone.prototype.getAdditionalScale = function () {
             return this._scaleVector.clone();
         };
         /**
-         * Copy the scale of the bone to a vector3.
-         * @param result The vector3 to copy the scale to
+         * Copy the additional scale of the bone to a vector3.
+         * @param result The vector3 to copy the additional scale to
          */
-        Bone.prototype.getScaleToRef = function (result) {
+        Bone.prototype.getAdditionalScaleToRef = function (result) {
             result.copyFrom(this._scaleVector);
         };
         /**
@@ -77368,7 +77461,7 @@ var BABYLON;
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
             if (mesh === void 0) { mesh = null; }
             if (space == BABYLON.Space.LOCAL) {
-                this.getLocalMatrix().decompose(Bone._tmpVecs[0], result, Bone._tmpVecs[1]);
+                this.getLocalMatrix().decompose(undefined, result, undefined);
             }
             else {
                 var mat = Bone._tmpMats[0];
@@ -77382,7 +77475,7 @@ var BABYLON;
                 mat.m[0] *= this._scalingDeterminant;
                 mat.m[1] *= this._scalingDeterminant;
                 mat.m[2] *= this._scalingDeterminant;
-                mat.decompose(Bone._tmpVecs[0], result, Bone._tmpVecs[1]);
+                mat.decompose(undefined, result, undefined);
             }
         };
         /**
@@ -77539,8 +77632,8 @@ var BABYLON;
                 }
             }
             if (this._bone1.length) {
-                var boneScale1 = this._bone1.getScale();
-                var boneScale2 = this._bone2.getScale();
+                var boneScale1 = this._bone1.getAdditionalScale();
+                var boneScale2 = this._bone2.getAdditionalScale();
                 this._bone1Length = this._bone1.length * boneScale1.y * this.mesh.scaling.y;
                 this._bone2Length = this._bone2.length * boneScale2.y * this.mesh.scaling.y;
             }

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

@@ -191,13 +191,6 @@ declare module BABYLON.GLTF2 {
     class ArrayItem {
         static Assign(values?: IArrayItem[]): void;
     }
-    class AnimationMultiTarget {
-        subTargets: any[];
-        position: Vector3;
-        rotationQuaternion: Quaternion;
-        scaling: Vector3;
-        influence: number;
-    }
 }
 
 

+ 4 - 57
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -491,53 +491,6 @@ var BABYLON;
             return ArrayItem;
         }());
         GLTF2.ArrayItem = ArrayItem;
-        var AnimationMultiTarget = /** @class */ (function () {
-            function AnimationMultiTarget() {
-                this.subTargets = new Array();
-            }
-            Object.defineProperty(AnimationMultiTarget.prototype, "position", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.position = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "rotationQuaternion", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.rotationQuaternion = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "scaling", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.scaling = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "influence", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.influence = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            return AnimationMultiTarget;
-        }());
-        GLTF2.AnimationMultiTarget = AnimationMultiTarget;
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 
@@ -1339,12 +1292,11 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
-                            var multiTarget = new GLTF2.AnimationMultiTarget();
+                            var morphTargets = new Array();
                             _this._forEachPrimitive(targetNode, function (babylonMesh) {
-                                var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
-                                multiTarget.subTargets.push(morphTarget);
+                                morphTargets.push(babylonMesh.morphTargetManager.getTarget(targetIndex));
                             });
-                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTargets);
                         };
                         for (var targetIndex = 0; targetIndex < targetNode._numMorphTargets; targetIndex++) {
                             _loop_1(targetIndex);
@@ -1355,12 +1307,7 @@ var BABYLON;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         if (targetNode._babylonAnimationTargets) {
-                            var multiTarget = new GLTF2.AnimationMultiTarget();
-                            for (var _i = 0, _a = targetNode._babylonAnimationTargets; _i < _a.length; _i++) {
-                                var target = _a[_i];
-                                multiTarget.subTargets.push(target);
-                            }
-                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, targetNode._babylonAnimationTargets);
                         }
                     }
                 });

文件差異過大導致無法顯示
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


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

@@ -747,13 +747,6 @@ declare module BABYLON.GLTF2 {
     class ArrayItem {
         static Assign(values?: IArrayItem[]): void;
     }
-    class AnimationMultiTarget {
-        subTargets: any[];
-        position: Vector3;
-        rotationQuaternion: Quaternion;
-        scaling: Vector3;
-        influence: number;
-    }
 }
 
 

+ 4 - 57
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -2689,53 +2689,6 @@ var BABYLON;
             return ArrayItem;
         }());
         GLTF2.ArrayItem = ArrayItem;
-        var AnimationMultiTarget = /** @class */ (function () {
-            function AnimationMultiTarget() {
-                this.subTargets = new Array();
-            }
-            Object.defineProperty(AnimationMultiTarget.prototype, "position", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.position = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "rotationQuaternion", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.rotationQuaternion = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "scaling", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.scaling = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "influence", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.influence = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            return AnimationMultiTarget;
-        }());
-        GLTF2.AnimationMultiTarget = AnimationMultiTarget;
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 
@@ -3537,12 +3490,11 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
-                            var multiTarget = new GLTF2.AnimationMultiTarget();
+                            var morphTargets = new Array();
                             _this._forEachPrimitive(targetNode, function (babylonMesh) {
-                                var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
-                                multiTarget.subTargets.push(morphTarget);
+                                morphTargets.push(babylonMesh.morphTargetManager.getTarget(targetIndex));
                             });
-                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTargets);
                         };
                         for (var targetIndex = 0; targetIndex < targetNode._numMorphTargets; targetIndex++) {
                             _loop_1(targetIndex);
@@ -3553,12 +3505,7 @@ var BABYLON;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         if (targetNode._babylonAnimationTargets) {
-                            var multiTarget = new GLTF2.AnimationMultiTarget();
-                            for (var _i = 0, _a = targetNode._babylonAnimationTargets; _i < _a.length; _i++) {
-                                var target = _a[_i];
-                                multiTarget.subTargets.push(target);
-                            }
-                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, targetNode._babylonAnimationTargets);
                         }
                     }
                 });

文件差異過大導致無法顯示
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 0 - 7
dist/preview release/loaders/babylonjs.loaders.d.ts

@@ -842,13 +842,6 @@ declare module BABYLON.GLTF2 {
     class ArrayItem {
         static Assign(values?: IArrayItem[]): void;
     }
-    class AnimationMultiTarget {
-        subTargets: any[];
-        position: Vector3;
-        rotationQuaternion: Quaternion;
-        scaling: Vector3;
-        influence: number;
-    }
 }
 
 

+ 4 - 57
dist/preview release/loaders/babylonjs.loaders.js

@@ -3668,53 +3668,6 @@ var BABYLON;
             return ArrayItem;
         }());
         GLTF2.ArrayItem = ArrayItem;
-        var AnimationMultiTarget = /** @class */ (function () {
-            function AnimationMultiTarget() {
-                this.subTargets = new Array();
-            }
-            Object.defineProperty(AnimationMultiTarget.prototype, "position", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.position = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "rotationQuaternion", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.rotationQuaternion = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "scaling", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.scaling = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            Object.defineProperty(AnimationMultiTarget.prototype, "influence", {
-                set: function (value) {
-                    for (var _i = 0, _a = this.subTargets; _i < _a.length; _i++) {
-                        var subTarget = _a[_i];
-                        subTarget.influence = value;
-                    }
-                },
-                enumerable: true,
-                configurable: true
-            });
-            return AnimationMultiTarget;
-        }());
-        GLTF2.AnimationMultiTarget = AnimationMultiTarget;
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 
@@ -4516,12 +4469,11 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
-                            var multiTarget = new GLTF2.AnimationMultiTarget();
+                            var morphTargets = new Array();
                             _this._forEachPrimitive(targetNode, function (babylonMesh) {
-                                var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
-                                multiTarget.subTargets.push(morphTarget);
+                                morphTargets.push(babylonMesh.morphTargetManager.getTarget(targetIndex));
                             });
-                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTargets);
                         };
                         for (var targetIndex = 0; targetIndex < targetNode._numMorphTargets; targetIndex++) {
                             _loop_1(targetIndex);
@@ -4532,12 +4484,7 @@ var BABYLON;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         if (targetNode._babylonAnimationTargets) {
-                            var multiTarget = new GLTF2.AnimationMultiTarget();
-                            for (var _i = 0, _a = targetNode._babylonAnimationTargets; _i < _a.length; _i++) {
-                                var target = _a[_i];
-                                multiTarget.subTargets.push(target);
-                            }
-                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, multiTarget);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimation, targetNode._babylonAnimationTargets);
                         }
                     }
                 });

文件差異過大導致無法顯示
+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.min.js


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

@@ -849,13 +849,6 @@ declare module BABYLON.GLTF2 {
     class ArrayItem {
         static Assign(values?: IArrayItem[]): void;
     }
-    class AnimationMultiTarget {
-        subTargets: any[];
-        position: Vector3;
-        rotationQuaternion: Quaternion;
-        scaling: Vector3;
-        influence: number;
-    }
 }
 
 

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

@@ -1,7 +1,7 @@
 {
-  "errors": 5237,
+  "errors": 5236,
   "babylon.typedoc.json": {
-    "errors": 5237,
+    "errors": 5236,
     "AnimationKeyInterpolation": {
       "Enumeration": {
         "Comments": {
@@ -4700,15 +4700,6 @@
             }
           }
         },
-        "setScale": {
-          "Parameter": {
-            "y": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
         "updateMatrix": {
           "Comments": {
             "MissingText": true

文件差異過大導致無法顯示
+ 42 - 42
dist/preview release/viewer/babylon.viewer.js


+ 177 - 84
dist/preview release/viewer/babylon.viewer.max.js

@@ -4521,6 +4521,18 @@ var BABYLON;
             return this;
         };
         /**
+         * Multiplies in place the current quaternion by a scale factor
+         * @param value defines the scale factor
+         * @returns the current modified quaternion
+         */
+        Quaternion.prototype.scaleInPlace = function (value) {
+            this.x *= value;
+            this.y *= value;
+            this.z *= value;
+            this.w *= value;
+            return this;
+        };
+        /**
          * Scale the current quaternion values by a factor and add the result to a given quaternion
          * @param scale defines the scale factor
          * @param result defines the Quaternion object where to store the result
@@ -5381,20 +5393,23 @@ var BABYLON;
                 translation.y = this.m[13];
                 translation.z = this.m[14];
             }
+            scale = scale || MathTmp.Vector3[0];
             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.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) {
                 scale.y *= -1;
             }
-            if (rotation) {
-                if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+            if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+                if (rotation) {
                     rotation.x = 0;
                     rotation.y = 0;
                     rotation.z = 0;
                     rotation.w = 1;
-                    return false;
                 }
+                return false;
+            }
+            if (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);
             }
@@ -5529,13 +5544,18 @@ var BABYLON;
          */
         Matrix.prototype.getRotationMatrixToRef = function (result) {
             var m = this.m;
-            var xs = m[0] * m[1] * m[2] * m[3] < 0 ? -1 : 1;
-            var ys = m[4] * m[5] * m[6] * m[7] < 0 ? -1 : 1;
-            var zs = m[8] * m[9] * m[10] * m[11] < 0 ? -1 : 1;
-            var sx = xs * Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
-            var sy = ys * Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);
-            var sz = zs * Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);
-            Matrix.FromValuesToRef(m[0] / sx, m[1] / sx, m[2] / sx, 0, m[4] / sy, m[5] / sy, m[6] / sy, 0, m[8] / sz, m[9] / sz, m[10] / sz, 0, 0, 0, 0, 1, result);
+            var sx = Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
+            var sy = Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);
+            var sz = Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);
+            if (this.determinant() <= 0) {
+                sy *= -1;
+            }
+            if (sx === 0 || sy === 0 || sz === 0) {
+                Matrix.IdentityToRef(result);
+            }
+            else {
+                Matrix.FromValuesToRef(m[0] / sx, m[1] / sx, m[2] / sx, 0, m[4] / sy, m[5] / sy, m[6] / sy, 0, m[8] / sz, m[9] / sz, m[10] / sz, 0, 0, 0, 0, 1, result);
+            }
             return this;
         };
         // Statics
@@ -25526,6 +25546,46 @@ var BABYLON;
             target._lateAnimationHolders[runtimeAnimation.targetPath].animations.push(runtimeAnimation);
             target._lateAnimationHolders[runtimeAnimation.targetPath].totalWeight += runtimeAnimation.weight;
         };
+        Scene.prototype._processLateAnimationBindingsForMatrices = function (holder, originalValue) {
+            var normalizer = 1.0;
+            var finalPosition = BABYLON.Tmp.Vector3[0];
+            var finalScaling = BABYLON.Tmp.Vector3[1];
+            var finalQuaternion = BABYLON.Tmp.Quaternion[0];
+            var startIndex = 0;
+            var originalAnimation = holder.animations[0];
+            var scale = 1;
+            if (holder.totalWeight < 1.0) {
+                // We need to mix the original value in                     
+                originalValue.decompose(finalScaling, finalQuaternion, finalPosition);
+                scale = 1.0 - holder.totalWeight;
+            }
+            else {
+                startIndex = 1;
+                // We need to normalize the weights
+                normalizer = holder.totalWeight;
+                originalAnimation.currentValue.decompose(finalScaling, finalQuaternion, finalPosition);
+                scale = originalAnimation.weight / normalizer;
+                if (scale == 1) {
+                    return originalAnimation.currentValue;
+                }
+            }
+            finalScaling.scaleInPlace(scale);
+            finalPosition.scaleInPlace(scale);
+            finalQuaternion.scaleInPlace(scale);
+            for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
+                var runtimeAnimation = holder.animations[animIndex];
+                var scale = runtimeAnimation.weight / normalizer;
+                var currentPosition = BABYLON.Tmp.Vector3[2];
+                var currentScaling = BABYLON.Tmp.Vector3[3];
+                var currentQuaternion = BABYLON.Tmp.Quaternion[1];
+                runtimeAnimation.currentValue.decompose(currentScaling, currentQuaternion, currentPosition);
+                currentScaling.scaleAndAddToRef(scale, finalScaling);
+                currentQuaternion.scaleAndAddToRef(scale, finalQuaternion);
+                currentPosition.scaleAndAddToRef(scale, finalPosition);
+            }
+            BABYLON.Matrix.ComposeToRef(finalScaling, finalQuaternion, finalPosition, originalAnimation._workValue);
+            return originalAnimation._workValue;
+        };
         Scene.prototype._processLateAnimationBindings = function () {
             if (!this._registeredForLateAnimationBindings.length) {
                 return;
@@ -25534,53 +25594,55 @@ var BABYLON;
                 var target = this._registeredForLateAnimationBindings.data[index];
                 for (var path in target._lateAnimationHolders) {
                     var holder = target._lateAnimationHolders[path];
-                    var originalValue = holder.animations[0].originalValue;
-                    // Sanity check
-                    if (!originalValue.scaleAndAddToRef) {
-                        continue;
-                    }
+                    var originalAnimation = holder.animations[0];
+                    var originalValue = originalAnimation.originalValue;
+                    var finalTarget = originalAnimation.target;
                     var matrixDecomposeMode = BABYLON.Animation.AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix
-                    var normalizer = 1.0;
                     var finalValue = void 0;
-                    if (holder.totalWeight < 1.0) {
-                        // We need to mix the original value in     
-                        if (matrixDecomposeMode) {
-                            finalValue = originalValue.clone();
-                        }
-                        else {
-                            finalValue = originalValue.scale(1.0 - holder.totalWeight);
-                        }
+                    if (matrixDecomposeMode) {
+                        finalValue = this._processLateAnimationBindingsForMatrices(holder, originalValue);
                     }
                     else {
-                        // We need to normalize the weights
-                        normalizer = holder.totalWeight;
-                    }
-                    for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
-                        var runtimeAnimation = holder.animations[animIndex];
-                        var scale = runtimeAnimation.weight / normalizer;
-                        if (finalValue) {
-                            if (matrixDecomposeMode) {
-                                BABYLON.Matrix.DecomposeLerpToRef(finalValue, runtimeAnimation.currentValue, scale, finalValue);
+                        var startIndex = 0;
+                        var normalizer = 1.0;
+                        if (holder.totalWeight < 1.0) {
+                            // We need to mix the original value in     
+                            if (originalValue.scale) {
+                                finalValue = originalValue.scale(1.0 - holder.totalWeight);
                             }
                             else {
-                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                                finalValue = originalValue * (1.0 - holder.totalWeight);
                             }
                         }
                         else {
-                            if (scale !== 1) {
-                                if (matrixDecomposeMode) {
-                                    finalValue = runtimeAnimation.currentValue.clone();
+                            // We need to normalize the weights
+                            normalizer = holder.totalWeight;
+                            var scale_1 = originalAnimation.weight / normalizer;
+                            if (scale_1 !== 1) {
+                                if (originalAnimation.currentValue.scale) {
+                                    finalValue = originalAnimation.currentValue.scale(scale_1);
                                 }
                                 else {
-                                    finalValue = runtimeAnimation.currentValue.scale(scale);
+                                    finalValue = originalAnimation.currentValue * scale_1;
                                 }
                             }
                             else {
-                                finalValue = runtimeAnimation.currentValue;
+                                finalValue = originalAnimation.currentValue;
+                            }
+                            startIndex = 1;
+                        }
+                        for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
+                            var runtimeAnimation = holder.animations[animIndex];
+                            var scale = runtimeAnimation.weight / normalizer;
+                            if (runtimeAnimation.currentValue.scaleAndAddToRef) {
+                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                            }
+                            else {
+                                finalValue += runtimeAnimation.currentValue * scale;
                             }
                         }
                     }
-                    runtimeAnimation.target[path] = finalValue;
+                    finalTarget[path] = finalValue;
                 }
                 target._lateAnimationHolders = {};
             }
@@ -51143,12 +51205,24 @@ var BABYLON;
          */
         RuntimeAnimation.prototype.setValue = function (currentValue, weight) {
             if (weight === void 0) { weight = 1.0; }
+            if (this._target instanceof Array) {
+                for (var _i = 0, _a = this._target; _i < _a.length; _i++) {
+                    var target = _a[_i];
+                    this._setValue(target, currentValue, weight);
+                }
+            }
+            else {
+                this._setValue(this._target, currentValue, weight);
+            }
+        };
+        RuntimeAnimation.prototype._setValue = function (target, currentValue, weight) {
+            if (weight === void 0) { weight = 1.0; }
             // Set value
             var path;
             var destination;
             var targetPropertyPath = this._animation.targetPropertyPath;
             if (targetPropertyPath.length > 1) {
-                var property = this._target[targetPropertyPath[0]];
+                var property = target[targetPropertyPath[0]];
                 for (var index = 1; index < targetPropertyPath.length - 1; index++) {
                     property = property[targetPropertyPath[index]];
                 }
@@ -51157,14 +51231,14 @@ var BABYLON;
             }
             else {
                 path = targetPropertyPath[0];
-                destination = this._target;
+                destination = target;
             }
             this._targetPath = path;
             this._activeTarget = destination;
             this._weight = weight;
             // Blending
-            var enableBlending = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;
-            var blendingSpeed = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
+            var enableBlending = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;
+            var blendingSpeed = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
             if (enableBlending && this._blendingFactor <= 1.0) {
                 if (!this._originalBlendValue) {
                     var originalValue = destination[path];
@@ -51234,8 +51308,8 @@ var BABYLON;
             else {
                 destination[path] = this._currentValue;
             }
-            if (this._target.markAsDirty) {
-                this._target.markAsDirty(this._animation.targetProperty);
+            if (target.markAsDirty) {
+                target.markAsDirty(this._animation.targetProperty);
             }
         };
         RuntimeAnimation.prototype._getCorrectLoopMode = function () {
@@ -51447,11 +51521,11 @@ var BABYLON;
             this._speedRatio = 1;
             this._weight = -1.0;
             this.animationStarted = false;
+            this._scene = scene;
             if (animations) {
                 this.appendAnimations(target, animations);
             }
             this._speedRatio = speedRatio;
-            this._scene = scene;
             scene._activeAnimatables.push(this);
         }
         Object.defineProperty(Animatable.prototype, "syncRoot", {
@@ -76749,7 +76823,7 @@ var BABYLON;
             _this._negateScaleChildren = BABYLON.Vector3.One();
             _this._scalingDeterminant = 1;
             _this._skeleton = skeleton;
-            _this._localMatrix = localMatrix ? localMatrix : BABYLON.Matrix.Identity();
+            _this._localMatrix = localMatrix ? localMatrix.clone() : BABYLON.Matrix.Identity();
             _this._restPose = restPose ? restPose : _this._localMatrix.clone();
             _this._baseMatrix = baseMatrix ? baseMatrix : _this._localMatrix.clone();
             _this._index = index;
@@ -76762,13 +76836,8 @@ var BABYLON;
             get: function () {
                 return this._localMatrix;
             },
-            set: function (val) {
-                if (this._localMatrix) {
-                    this._localMatrix.copyFrom(val);
-                }
-                else {
-                    this._localMatrix = val;
-                }
+            set: function (value) {
+                this._localMatrix.copyFrom(value);
             },
             enumerable: true,
             configurable: true
@@ -76798,6 +76867,7 @@ var BABYLON;
             if (updateDifferenceMatrix) {
                 this._updateDifferenceMatrix();
             }
+            this.markAsDirty();
         };
         Bone.prototype.getLocalMatrix = function () {
             return this._localMatrix;
@@ -76853,10 +76923,14 @@ var BABYLON;
         });
         Object.defineProperty(Bone.prototype, "scaling", {
             get: function () {
-                return this.getScale();
+                var value = BABYLON.Vector3.One();
+                this._localMatrix.decompose(value, undefined, undefined);
+                return value;
             },
             set: function (newScaling) {
-                this.setScale(newScaling.x, newScaling.y, newScaling.z);
+                this._localMatrix.decompose(undefined, Bone._tmpQuat, Bone._tmpVecs[0]);
+                BABYLON.Matrix.ComposeToRef(newScaling, Bone._tmpQuat, Bone._tmpVecs[0], this._localMatrix);
+                this.markAsDirty();
             },
             enumerable: true,
             configurable: true
@@ -76874,12 +76948,12 @@ var BABYLON;
         // Methods
         Bone.prototype.updateMatrix = function (matrix, updateDifferenceMatrix) {
             if (updateDifferenceMatrix === void 0) { updateDifferenceMatrix = true; }
-            this._baseMatrix = matrix.clone();
-            this._localMatrix = matrix.clone();
-            this._skeleton._markAsDirty();
+            this._baseMatrix.copyFrom(matrix);
+            this._localMatrix.copyFrom(matrix);
             if (updateDifferenceMatrix) {
                 this._updateDifferenceMatrix();
             }
+            this.markAsDirty();
         };
         Bone.prototype._updateDifferenceMatrix = function (rootMatrix) {
             if (!rootMatrix) {
@@ -77051,13 +77125,13 @@ var BABYLON;
             this.setPosition(position, BABYLON.Space.WORLD, mesh);
         };
         /**
-         * Set the scale of the bone on the x, y and z axes.
-         * @param x The scale of the bone on the x axis.
-         * @param x The scale of the bone on the y axis.
-         * @param z The scale of the bone on the z axis.
+         * Adds an additional scale to the bone on the x, y and z axes.
+         * @param x The additional scale of the bone on the x axis.
+         * @param y The additional scale of the bone on the y axis.
+         * @param z The additional scale of the bone on the z axis.
          * @param scaleChildren Set this to true if children of the bone should be scaled.
          */
-        Bone.prototype.setScale = function (x, y, z, scaleChildren) {
+        Bone.prototype.setAdditionalScale = function (x, y, z, scaleChildren) {
             if (scaleChildren === void 0) { scaleChildren = false; }
             if (this.animations[0] && !this.animations[0].hasRunningRuntimeAnimations) {
                 if (!scaleChildren) {
@@ -77085,7 +77159,7 @@ var BABYLON;
             origLocMatInv.copyFrom(origLocMat);
             origLocMatInv.invert();
             var scaleMat = Bone._tmpMats[2];
-            BABYLON.Matrix.FromValuesToRef(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1, scaleMat);
+            BABYLON.Matrix.ScalingToRef(x, y, z, scaleMat);
             this._scaleMatrix.multiplyToRef(scaleMat, this._scaleMatrix);
             this._scaleVector.x *= x;
             this._scaleVector.y *= y;
@@ -77129,10 +77203,12 @@ var BABYLON;
          */
         Bone.prototype.setYawPitchRoll = function (yaw, pitch, roll, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
-            var rotMat = Bone._tmpMats[0];
+            var rotMatInv = Bone._tmpMats[0];
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
+            var rotMat = Bone._tmpMats[1];
             BABYLON.Matrix.RotationYawPitchRollToRef(yaw, pitch, roll, rotMat);
-            var rotMatInv = Bone._tmpMats[1];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
             rotMatInv.multiplyToRef(rotMat, rotMat);
             this._rotateWithMatrix(rotMat, space, mesh);
         };
@@ -77161,10 +77237,12 @@ var BABYLON;
          */
         Bone.prototype.setAxisAngle = function (axis, angle, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
-            var rotMat = Bone._tmpMats[0];
+            var rotMatInv = Bone._tmpMats[0];
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
+            var rotMat = Bone._tmpMats[1];
             BABYLON.Matrix.RotationAxisToRef(axis, angle, rotMat);
-            var rotMatInv = Bone._tmpMats[1];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
             rotMatInv.multiplyToRef(rotMat, rotMat);
             this._rotateWithMatrix(rotMat, space, mesh);
         };
@@ -77187,7 +77265,9 @@ var BABYLON;
         Bone.prototype.setRotationQuaternion = function (quat, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
             var rotMatInv = Bone._tmpMats[0];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
             var rotMat = Bone._tmpMats[1];
             BABYLON.Matrix.FromQuaternionToRef(quat, rotMat);
             rotMatInv.multiplyToRef(rotMat, rotMat);
@@ -77202,7 +77282,9 @@ var BABYLON;
         Bone.prototype.setRotationMatrix = function (rotMat, space, mesh) {
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
             var rotMatInv = Bone._tmpMats[0];
-            this._getNegativeRotationToRef(rotMatInv, space, mesh);
+            if (!this._getNegativeRotationToRef(rotMatInv, space, mesh)) {
+                return;
+            }
             var rotMat2 = Bone._tmpMats[1];
             rotMat2.copyFrom(rotMat);
             rotMatInv.multiplyToRef(rotMat, rotMat2);
@@ -77268,12 +77350,22 @@ var BABYLON;
                     scaleMatrix.multiplyToRef(meshScale, scaleMatrix);
                 }
                 rotMatInv.invert();
+                if (isNaN(rotMatInv.m[0])) {
+                    // Matrix failed to invert.
+                    // This can happen if scale is zero for example.
+                    return false;
+                }
                 scaleMatrix.m[0] *= this._scalingDeterminant;
                 rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);
             }
             else {
                 rotMatInv.copyFrom(this.getLocalMatrix());
                 rotMatInv.invert();
+                if (isNaN(rotMatInv.m[0])) {
+                    // Matrix failed to invert.
+                    // This can happen if scale is zero for example.
+                    return false;
+                }
                 var scaleMatrix = Bone._tmpMats[2];
                 scaleMatrix.copyFrom(this._scaleMatrix);
                 if (this._parent) {
@@ -77287,19 +77379,20 @@ var BABYLON;
                 }
                 rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);
             }
+            return true;
         };
         /**
-         * Get the scale of the bone
-         * @returns the scale of the bone
+         * Get the additional scale of the bone
+         * @returns the additional scale of the bone
          */
-        Bone.prototype.getScale = function () {
+        Bone.prototype.getAdditionalScale = function () {
             return this._scaleVector.clone();
         };
         /**
-         * Copy the scale of the bone to a vector3.
-         * @param result The vector3 to copy the scale to
+         * Copy the additional scale of the bone to a vector3.
+         * @param result The vector3 to copy the additional scale to
          */
-        Bone.prototype.getScaleToRef = function (result) {
+        Bone.prototype.getAdditionalScaleToRef = function (result) {
             result.copyFrom(this._scaleVector);
         };
         /**
@@ -77489,7 +77582,7 @@ var BABYLON;
             if (space === void 0) { space = BABYLON.Space.LOCAL; }
             if (mesh === void 0) { mesh = null; }
             if (space == BABYLON.Space.LOCAL) {
-                this.getLocalMatrix().decompose(Bone._tmpVecs[0], result, Bone._tmpVecs[1]);
+                this.getLocalMatrix().decompose(undefined, result, undefined);
             }
             else {
                 var mat = Bone._tmpMats[0];
@@ -77503,7 +77596,7 @@ var BABYLON;
                 mat.m[0] *= this._scalingDeterminant;
                 mat.m[1] *= this._scalingDeterminant;
                 mat.m[2] *= this._scalingDeterminant;
-                mat.decompose(Bone._tmpVecs[0], result, Bone._tmpVecs[1]);
+                mat.decompose(undefined, result, undefined);
             }
         };
         /**
@@ -77660,8 +77753,8 @@ var BABYLON;
                 }
             }
             if (this._bone1.length) {
-                var boneScale1 = this._bone1.getScale();
-                var boneScale2 = this._bone2.getScale();
+                var boneScale1 = this._bone1.getAdditionalScale();
+                var boneScale2 = this._bone2.getAdditionalScale();
                 this._bone1Length = this._bone1.length * boneScale1.y * this.mesh.scaling.y;
                 this._bone2Length = this._bone2.length * boneScale2.y * this.mesh.scaling.y;
             }

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

@@ -65,12 +65,12 @@
 
 
         constructor(scene: Scene, public target: any, public fromFrame: number = 0, public toFrame: number = 100, public loopAnimation: boolean = false, speedRatio: number = 1.0, public onAnimationEnd?: Nullable<() => void>, animations?: any) {
+            this._scene = scene;
             if (animations) {
                 this.appendAnimations(target, animations);
             }
 
             this._speedRatio = speedRatio;
-            this._scene = scene;
             scene._activeAnimatables.push(this);
         }
 

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

@@ -15,7 +15,8 @@
         private _scene: Scene;
 
         private _currentValue: any;
-        private _workValue: any;
+        /** @ignore */
+        public _workValue: any;
         private _activeTarget: any;
         private _targetPath: string = "";
         private _weight = 1.0;

+ 0 - 4
src/Bones/babylon.bone.ts

@@ -678,9 +678,7 @@
          * @returns the additional scale of the bone
          */
         public getAdditionalScale(): Vector3 {
-
             return this._scaleVector.clone();
-
         }
 
         /**
@@ -688,9 +686,7 @@
          * @param result The vector3 to copy the additional scale to
          */
         public getAdditionalScaleToRef(result: Vector3): void {
-
             result.copyFrom(this._scaleVector);
-
         }
 
         /**

+ 2 - 2
src/Bones/babylon.boneIKController.ts

@@ -83,8 +83,8 @@ module BABYLON {
             
             if (this._bone1.length) {
 
-                var boneScale1 = this._bone1.getScale();
-                var boneScale2 = this._bone2.getScale();
+                var boneScale1 = this._bone1.getAdditionalScale();
+                var boneScale2 = this._bone2.getAdditionalScale();
                 
                 this._bone1Length = this._bone1.length * boneScale1.y * this.mesh.scaling.y;
                 this._bone2Length = this._bone2.length * boneScale2.y * this.mesh.scaling.y;

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

@@ -3244,7 +3244,21 @@
             result.z = this.z * scale;
             result.w = this.w * scale;
             return this;
-        }         
+        }    
+        
+        /**
+         * Multiplies in place the current quaternion by a scale factor
+         * @param value defines the scale factor
+         * @returns the current modified quaternion
+         */
+        public scaleInPlace(value: number): Quaternion {
+            this.x *= value;
+            this.y *= value;
+            this.z *= value;
+            this.w *= value;
+            
+            return this;
+        }
 
         /**
          * Scale the current quaternion values by a factor and add the result to a given quaternion  

+ 81 - 30
src/babylon.scene.ts

@@ -2685,6 +2685,54 @@
             target._lateAnimationHolders[runtimeAnimation.targetPath].totalWeight += runtimeAnimation.weight;
         }
 
+        private _processLateAnimationBindingsForMatrices(holder: {
+            totalWeight: number,
+            animations: RuntimeAnimation[]
+        }, originalValue: Matrix): any {
+            let normalizer = 1.0;
+            let finalPosition = Tmp.Vector3[0];
+            let finalScaling = Tmp.Vector3[1];
+            let finalQuaternion = Tmp.Quaternion[0];
+            let startIndex = 0;            
+            let originalAnimation = holder.animations[0];
+
+            var scale = 1;
+            if (holder.totalWeight < 1.0) {
+                // We need to mix the original value in                     
+                originalValue.decompose(finalScaling, finalQuaternion, finalPosition);
+                scale = 1.0 - holder.totalWeight;
+            } else {
+                startIndex = 1;            
+                // We need to normalize the weights
+                normalizer = holder.totalWeight;
+                originalAnimation.currentValue.decompose(finalScaling, finalQuaternion, finalPosition);
+                scale = originalAnimation.weight / normalizer;
+                if (scale == 1) {
+                    return originalAnimation.currentValue;
+                }
+            }
+
+            finalScaling.scaleInPlace(scale);
+            finalPosition.scaleInPlace(scale);
+            finalQuaternion.scaleInPlace(scale);
+
+            for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
+                var runtimeAnimation = holder.animations[animIndex];   
+                var scale = runtimeAnimation.weight / normalizer;
+                let currentPosition = Tmp.Vector3[2];
+                let currentScaling = Tmp.Vector3[3];
+                let currentQuaternion = Tmp.Quaternion[1];
+
+                runtimeAnimation.currentValue.decompose(currentScaling, currentQuaternion, currentPosition);
+                currentScaling.scaleAndAddToRef(scale, finalScaling);
+                currentQuaternion.scaleAndAddToRef(scale, finalQuaternion);
+                currentPosition.scaleAndAddToRef(scale, finalPosition);
+            }  
+            
+            Matrix.ComposeToRef(finalScaling, finalQuaternion, finalPosition, originalAnimation._workValue);
+            return originalAnimation._workValue;
+        }
+
         private _processLateAnimationBindings(): void {
             if (!this._registeredForLateAnimationBindings.length) {
                 return;
@@ -2694,52 +2742,55 @@
 
                 for (var path in target._lateAnimationHolders) {
                     var holder = target._lateAnimationHolders[path];                     
-                    let originalValue = holder.animations[0].originalValue;      
+                    let originalAnimation = holder.animations[0];
+                    let originalValue = originalAnimation.originalValue;
+                    let finalTarget = originalAnimation.target;   
                     
-                    // Sanity check
-                    if (!originalValue.scaleAndAddToRef) {
-                        continue;
-                    }
-
                     let matrixDecomposeMode = Animation.AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix
-                    let normalizer = 1.0;
-                    let finalValue: any;
 
-                    if (holder.totalWeight < 1.0) {
-                        // We need to mix the original value in     
-                        if (matrixDecomposeMode) {
-                            finalValue = originalValue.clone();
-                        } else {            
-                            finalValue = originalValue.scale(1.0 - holder.totalWeight)
-                        }
+                    let finalValue: any;
+                    if (matrixDecomposeMode) {
+                        finalValue = this._processLateAnimationBindingsForMatrices(holder, originalValue);
                     } else {
-                        // We need to normalize the weights
-                        normalizer = holder.totalWeight;
-                    }
+                        let startIndex = 0;
+                        let normalizer = 1.0;
 
-                    for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
-                        var runtimeAnimation = holder.animations[animIndex];   
-                        var scale = runtimeAnimation.weight / normalizer;
-                        if (finalValue) {
-                            if (matrixDecomposeMode) {
-                                Matrix.DecomposeLerpToRef(finalValue, runtimeAnimation.currentValue, scale, finalValue);
+                        if (holder.totalWeight < 1.0) {
+                            // We need to mix the original value in     
+                            if (originalValue.scale) {
+                                finalValue = originalValue.scale(1.0 - holder.totalWeight);
                             } else {
-                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                                finalValue = originalValue * (1.0 - holder.totalWeight);
                             }
                         } else {
+                            // We need to normalize the weights
+                            normalizer = holder.totalWeight;
+                            let scale = originalAnimation.weight / normalizer;
                             if (scale !== 1) {
-                                if (matrixDecomposeMode) {
-                                    finalValue = runtimeAnimation.currentValue.clone();
+                                if (originalAnimation.currentValue.scale) {
+                                    finalValue = originalAnimation.currentValue.scale(scale);
                                 } else {
-                                    finalValue = runtimeAnimation.currentValue.scale(scale);
+                                    finalValue = originalAnimation.currentValue * scale;
                                 }
                             } else {
-                                finalValue = runtimeAnimation.currentValue;
+                                finalValue = originalAnimation.currentValue;
+                            }
+
+                            startIndex = 1;
+                        }
+
+                        for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
+                            var runtimeAnimation = holder.animations[animIndex];   
+                            var scale = runtimeAnimation.weight / normalizer;
+                            if (runtimeAnimation.currentValue.scaleAndAddToRef) {
+                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                            } else {
+                                finalValue += runtimeAnimation.currentValue * scale;
                             }
                         }
                     }
 
-                    runtimeAnimation.target[path] = finalValue;
+                    finalTarget[path] = finalValue;
                 }
 
                 target._lateAnimationHolders = {};