|
@@ -25955,36 +25955,41 @@ var BABYLON;
|
|
|
return BABYLON.Quaternion.Slerp(originalValue, originalAnimation.currentValue, Math.min(1.0, holder.totalWeight));
|
|
|
}
|
|
|
var normalizer = 1.0;
|
|
|
- var cumulativeQuaternion = null;
|
|
|
+ var quaternions;
|
|
|
+ var weights;
|
|
|
if (holder.totalWeight < 1.0) {
|
|
|
- // We need to mix the original value in
|
|
|
- //originalValue.decompose(finalScaling, finalQuaternion, finalPosition);
|
|
|
var scale = 1.0 - holder.totalWeight;
|
|
|
- cumulativeQuaternion = originalValue.scaleInPlace(scale);
|
|
|
- cumulativeQuaternion.normalize();
|
|
|
+ quaternions = [];
|
|
|
+ weights = [];
|
|
|
+ quaternions.push(originalValue);
|
|
|
+ weights.push(scale);
|
|
|
}
|
|
|
else {
|
|
|
if (holder.animations.length === 2) { // Slerp as soon as we can
|
|
|
return BABYLON.Quaternion.Slerp(holder.animations[0].currentValue, holder.animations[1].currentValue, holder.animations[1].weight / holder.totalWeight);
|
|
|
}
|
|
|
+ quaternions = [];
|
|
|
+ weights = [];
|
|
|
normalizer = holder.totalWeight;
|
|
|
}
|
|
|
- // There is no simple way to cumulate and weight quaternions so doing approximations here
|
|
|
for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
|
|
|
var runtimeAnimation = holder.animations[animIndex];
|
|
|
- var scale = runtimeAnimation.weight / normalizer;
|
|
|
- var current = runtimeAnimation.currentValue;
|
|
|
- current.scaleInPlace(scale);
|
|
|
- current.normalize();
|
|
|
+ quaternions.push(runtimeAnimation.currentValue);
|
|
|
+ weights.push(runtimeAnimation.weight / normalizer);
|
|
|
+ }
|
|
|
+ // https://gamedev.stackexchange.com/questions/62354/method-for-interpolation-between-3-quaternions
|
|
|
+ var cumulativeAmount = 0;
|
|
|
+ var cumulativeQuaternion = null;
|
|
|
+ for (var index = 0; index < quaternions.length;) {
|
|
|
if (!cumulativeQuaternion) {
|
|
|
- cumulativeQuaternion = current;
|
|
|
+ cumulativeQuaternion = BABYLON.Quaternion.Slerp(quaternions[index], quaternions[index + 1], weights[index + 1] / (weights[index] + weights[index + 1]));
|
|
|
+ cumulativeAmount = weights[index] + weights[index + 1];
|
|
|
+ index += 2;
|
|
|
continue;
|
|
|
}
|
|
|
- if (!BABYLON.Quaternion.AreClose(current, cumulativeQuaternion)) {
|
|
|
- current.conjugateInPlace();
|
|
|
- }
|
|
|
- cumulativeQuaternion.addInPlace(current);
|
|
|
- cumulativeQuaternion.normalize();
|
|
|
+ cumulativeAmount += weights[index];
|
|
|
+ cumulativeQuaternion = BABYLON.Quaternion.Slerp(cumulativeQuaternion, quaternions[index], weights[index] / cumulativeAmount);
|
|
|
+ index++;
|
|
|
}
|
|
|
return cumulativeQuaternion;
|
|
|
};
|
|
@@ -51333,6 +51338,22 @@ var BABYLON;
|
|
|
enumerable: true,
|
|
|
configurable: true
|
|
|
});
|
|
|
+ /** @ignore */
|
|
|
+ Animation._UniversalLerp = function (left, right, amount) {
|
|
|
+ var constructor = left.constructor;
|
|
|
+ if (constructor.Lerp) { // Lerp supported
|
|
|
+ return constructor.Lerp(left, right, amount);
|
|
|
+ }
|
|
|
+ else if (constructor.Slerp) { // Slerp supported
|
|
|
+ return constructor.Slerp(left, right, amount);
|
|
|
+ }
|
|
|
+ else if (left.toFixed) { // Number
|
|
|
+ return left * (1.0 - amount) + amount * right;
|
|
|
+ }
|
|
|
+ else { // Blending not supported
|
|
|
+ return right;
|
|
|
+ }
|
|
|
+ };
|
|
|
/**
|
|
|
* Parses an animation object and creates an animation
|
|
|
* @param parsedAnimation Parsed animation object
|
|
@@ -52076,19 +52097,7 @@ var BABYLON;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
- var constructor = this._originalBlendValue.constructor;
|
|
|
- if (constructor.Lerp) { // Lerp supported
|
|
|
- this._currentValue = constructor.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
|
|
|
- }
|
|
|
- else if (constructor.Slerp) { // Slerp supported
|
|
|
- this._currentValue = constructor.Slerp(this._originalBlendValue, currentValue, this._blendingFactor);
|
|
|
- }
|
|
|
- else if (this._originalBlendValue.toFixed) { // Number
|
|
|
- this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
|
|
|
- }
|
|
|
- else { // Blending not supported
|
|
|
- this._currentValue = currentValue;
|
|
|
- }
|
|
|
+ this._currentValue = BABYLON.Animation._UniversalLerp(this._originalBlendValue, currentValue, this._blendingFactor);
|
|
|
}
|
|
|
var blendingSpeed = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
|
|
|
this._blendingFactor += blendingSpeed;
|