David Catuhe 6 gadi atpakaļ
vecāks
revīzija
c693d79fec

+ 1 - 1
src/Animations/animation.ts

@@ -576,7 +576,7 @@ export class Animation {
             return highLimitValue.clone ? highLimitValue.clone() : highLimitValue;
         }
 
-        const keys = this.getKeys();
+        const keys = this._keys;
         if (keys.length === 1) {
             return this._getKeyValue(keys[0].value);
         }

+ 95 - 82
src/Animations/runtimeAnimation.ts

@@ -6,6 +6,7 @@ import { AnimationEvent } from "./animationEvent";
 declare type Animatable = import("./animatable").Animatable;
 
 import { Scene } from "../scene";
+import { IAnimationKey } from './animationKey';
 
 // Static values to help the garbage collector
 
@@ -98,6 +99,7 @@ export class RuntimeAnimation {
      */
     private _activeTargets: any[];
     private _currentActiveTarget: any;
+    private _directTarget: any;
 
     /**
      * The target path of the runtime animation
@@ -127,6 +129,12 @@ export class RuntimeAnimation {
     private _enableBlending: boolean;
     private _correctLoopMode: number | undefined;
 
+    private _keys: IAnimationKey[];
+    private _minFrame: number;
+    private _maxFrame: number;
+    private _minValue: any;
+    private _maxValue: any;
+
     /**
      * Gets the current frame of the runtime animation
      */
@@ -178,6 +186,24 @@ export class RuntimeAnimation {
 
         animation._runtimeAnimations.push(this);
 
+        // Normalization
+        if (this._host && this._host.syncRoot) {
+            this._normalizationProcessor = this._defaultNormalizationProcessor;
+        }
+
+        // Limits
+        this._keys = this._animation.getKeys();
+        this._minFrame = this._keys[0].frame;
+        this._maxFrame = this._keys[this._keys.length - 1].frame;
+        this._minValue = this._keys[0].value;
+        this._maxValue = this._keys[this._keys.length - 1].value;
+
+        // Add a start key at frame 0 if missing
+        if (this._minFrame !== 0) {
+            const newKey = { frame: 0, value: this._minValue };
+            this._keys.splice(0, 0, newKey);
+        }
+
         // Check data
         if (this._target instanceof Array) {
             var index = 0;
@@ -186,10 +212,13 @@ export class RuntimeAnimation {
                 this._getOriginalValues(index);
                 index++;
             }
+            this.setValue = this._setValueForArray;
         }
         else {
             this._preparePath(this._target);
             this._getOriginalValues();
+            this.setValue = this._setValueForDirect;
+            this._directTarget = this._activeTargets[0];
         }
 
         // Cloning events locally
@@ -210,6 +239,15 @@ export class RuntimeAnimation {
         }
     }
 
+    private _normalizationProcessor = (returnValue: boolean, range: number, ratio: number, from: number, to: number) => {
+        return (returnValue && range !== 0) ? from + ratio % range : to;;
+    };
+    private _defaultNormalizationProcessor = (returnValue: boolean, range: number, ratio: number, from: number, to: number) => {
+        const syncRoot = this._host.syncRoot;
+        const hostNormalizedFrame = (syncRoot.masterFrame - syncRoot.fromFrame) / (syncRoot.toFrame - syncRoot.fromFrame);
+        return from + (to - from) * hostNormalizedFrame;
+    }
+
     private _preparePath(target: any, targetIndex = 0) {
         let targetPropertyPath = this._animation.targetPropertyPath;
 
@@ -245,14 +283,14 @@ export class RuntimeAnimation {
                 var index = 0;
                 for (const target of this._target) {
                     if (this._originalValue[index] !== undefined) {
-                        this._setValue(target, this._originalValue[index], -1);
+                        this._setValue(target, this._activeTargets[index], this._originalValue[index], -1, index);
                     }
                     index++;
                 }
             }
             else {
                 if (this._originalValue[0] !== undefined) {
-                    this._setValue(this._target, this._originalValue[0], -1);
+                    this._setValue(this._target, this._directTarget, this._originalValue[0], -1, 0);
                 }
             }
         }
@@ -261,7 +299,6 @@ export class RuntimeAnimation {
         this._highLimitsCache = {};
         this._currentFrame = 0;
         this._blendingFactor = 0;
-        this._originalValue = new Array<any>();
 
         // Events
         for (var index = 0; index < this._events.length; index++) {
@@ -312,19 +349,19 @@ export class RuntimeAnimation {
      * @param currentValue defines the value computed by the animation
      * @param weight defines the weight to apply to this value (Defaults to 1.0)
      */
-    public setValue(currentValue: any, weight = 1.0): void {
-        if (this._target instanceof Array) {
-            var index = 0;
-            for (const target of this._target) {
-                this._setValue(target, currentValue, weight, index);
-                index++;
-            }
-        }
-        else {
-            this._setValue(this._target, currentValue, weight);
+    public setValue: (currentValue: any, weight: number) => void;
+
+    private _setValueForArray = (currentValue: any, weight = 1.0) => {
+        for (var index = 0; index < this._target.length; index++) {
+            const target = this._target[index];
+            this._setValue(target, this._activeTargets[index], currentValue, weight, index);
         }
     }
 
+    private _setValueForDirect = (currentValue: any, weight = 1.0) => {
+        this._setValue(this._target, this._directTarget, currentValue, weight, 0);
+    }
+
     private _getOriginalValues(targetIndex = 0) {
         let originalValue: any;
         let target = this._activeTargets[targetIndex];
@@ -385,10 +422,8 @@ export class RuntimeAnimation {
         }
     }
 
-    private _setValue(target: any, currentValue: any, weight: number, targetIndex = 0): void {
+    private _setValue(target: any, destination: any, currentValue: any, weight: number, targetIndex: number): void {
         // Set value
-        var path = this._targetPath;
-        var destination = this._activeTargets[targetIndex];
         this._currentActiveTarget = destination;
 
         this._weight = weight;
@@ -398,8 +433,8 @@ export class RuntimeAnimation {
         if (weight !== -1.0) {
             this._scene._registerTargetForLateAnimationBinding(this, this._originalValue[targetIndex]);
         } else {
-            destination[path] = this._currentValue;
-        }
+            destination[this._targetPath] = this._currentValue;
+       }
 
         if (target.markAsDirty) {
             target.markAsDirty(this._animation.targetProperty);
@@ -465,22 +500,12 @@ export class RuntimeAnimation {
 
         let returnValue = true;
 
-        let keys = this._animation.getKeys();
-        let min = keys[0].frame;
-        let max = keys[keys.length - 1].frame;
-
-        // Add a start key at frame 0 if missing
-        if (min !== 0) {
-            const newKey = { frame: 0, value: keys[0].value };
-            keys.splice(0, 0, newKey);
-        }
-
         // Check limits
-        if (from < min || from > max) {
-            from = min;
+        if (from < this._minFrame || from > this._maxFrame) {
+            from = this._minFrame;
         }
-        if (to < min || to > max) {
-            to = max;
+        if (to < this._minFrame || to > this._maxFrame) {
+            to = this._maxFrame;
         }
 
         const range = to - from;
@@ -493,52 +518,47 @@ export class RuntimeAnimation {
         this._previousDelay = delay;
         this._previousRatio = ratio;
 
-        if ((to > from && ratio >= range) && !loop) { // If we are out of range and not looping get back to caller
+        if (!loop && (to > from && ratio >= range)) { // If we are out of range and not looping get back to caller
             returnValue = false;
-            highLimitValue = this._animation._getKeyValue(keys[keys.length - 1].value);
-        } else if ((from > to && ratio <= range) && !loop) {
+            highLimitValue = this._animation._getKeyValue(this._maxValue);
+        } else if (!loop && (from > to && ratio <= range)) {
             returnValue = false;
-            highLimitValue = this._animation._getKeyValue(keys[0].value);
-        } else {
-            // Get max value if required
-
-            if (this._correctLoopMode !== Animation.ANIMATIONLOOPMODE_CYCLE) {
-
-                var keyOffset = to.toString() + from.toString();
-                if (!this._offsetsCache[keyOffset]) {
-                    var fromValue = this._interpolate(from, 0, Animation.ANIMATIONLOOPMODE_CYCLE);
-                    var toValue = this._interpolate(to, 0, Animation.ANIMATIONLOOPMODE_CYCLE);
-                    switch (this._animation.dataType) {
-                        // Float
-                        case Animation.ANIMATIONTYPE_FLOAT:
-                            this._offsetsCache[keyOffset] = toValue - fromValue;
-                            break;
-                        // Quaternion
-                        case Animation.ANIMATIONTYPE_QUATERNION:
-                            this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
-                            break;
-                        // Vector3
-                        case Animation.ANIMATIONTYPE_VECTOR3:
-                            this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
-                        // Vector2
-                        case Animation.ANIMATIONTYPE_VECTOR2:
-                            this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
-                        // Size
-                        case Animation.ANIMATIONTYPE_SIZE:
-                            this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
-                        // Color3
-                        case Animation.ANIMATIONTYPE_COLOR3:
-                            this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
-                        default:
-                            break;
-                    }
-
-                    this._highLimitsCache[keyOffset] = toValue;
+            highLimitValue = this._animation._getKeyValue(this._minValue);
+        } else if (this._correctLoopMode !== Animation.ANIMATIONLOOPMODE_CYCLE) {
+            var keyOffset = to.toString() + from.toString();
+            if (!this._offsetsCache[keyOffset]) {
+                var fromValue = this._interpolate(from, 0, Animation.ANIMATIONLOOPMODE_CYCLE);
+                var toValue = this._interpolate(to, 0, Animation.ANIMATIONLOOPMODE_CYCLE);
+                switch (this._animation.dataType) {
+                    // Float
+                    case Animation.ANIMATIONTYPE_FLOAT:
+                        this._offsetsCache[keyOffset] = toValue - fromValue;
+                        break;
+                    // Quaternion
+                    case Animation.ANIMATIONTYPE_QUATERNION:
+                        this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
+                        break;
+                    // Vector3
+                    case Animation.ANIMATIONTYPE_VECTOR3:
+                        this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
+                    // Vector2
+                    case Animation.ANIMATIONTYPE_VECTOR2:
+                        this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
+                    // Size
+                    case Animation.ANIMATIONTYPE_SIZE:
+                        this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
+                    // Color3
+                    case Animation.ANIMATIONTYPE_COLOR3:
+                        this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
+                    default:
+                        break;
                 }
 
-                highLimitValue = this._highLimitsCache[keyOffset];
-                offsetValue = this._offsetsCache[keyOffset];
+                this._highLimitsCache[keyOffset] = toValue;
             }
+
+            highLimitValue = this._highLimitsCache[keyOffset];
+            offsetValue = this._offsetsCache[keyOffset];
         }
 
         if (offsetValue === undefined) {
@@ -570,14 +590,7 @@ export class RuntimeAnimation {
         }
 
         // Compute value
-        let currentFrame = (returnValue && range !== 0) ? from + ratio % range : to;
-
-        // Need to normalize?
-        if (this._host && this._host.syncRoot) {
-            const syncRoot = this._host.syncRoot;
-            const hostNormalizedFrame = (syncRoot.masterFrame - syncRoot.fromFrame) / (syncRoot.toFrame - syncRoot.fromFrame);
-            currentFrame = from + (to - from) * hostNormalizedFrame;
-        }
+        let currentFrame = this._normalizationProcessor(returnValue, range, ratio, from, to);
 
         // Reset events if looping
         const events = this._events;
@@ -596,7 +609,7 @@ export class RuntimeAnimation {
                     }
                 }
             }
-        }
+       }
 
         const repeatCount = range === 0 ? 0 : (ratio / range) >> 0;
         const currentValue = this._interpolate(currentFrame, repeatCount, this._correctLoopMode, offsetValue, highLimitValue);

+ 5 - 6
src/Engines/engine.ts

@@ -6357,7 +6357,6 @@ export class Engine {
      */
     public bindSamplers(effect: Effect): void {
         this.setProgram(effect.getProgram());
-
         var samplers = effect.getSamplers();
         for (var index = 0; index < samplers.length; index++) {
             var uniform = effect.getUniform(samplers[index]);
@@ -6365,7 +6364,7 @@ export class Engine {
             if (uniform) {
                 this._boundUniforms[index] = uniform;
             }
-        }
+        }        
         this._currentEffect = null;
     }
 
@@ -6414,7 +6413,7 @@ export class Engine {
 
     /** @hidden */
     public _bindTexture(channel: number, texture: Nullable<InternalTexture>): void {
-        if (channel < 0) {
+        if (channel === undefined) {
             return;
         }
 
@@ -6465,7 +6464,7 @@ export class Engine {
      * @param texture The texture to apply
      */
     public setTexture(channel: number, uniform: Nullable<WebGLUniformLocation>, texture: Nullable<BaseTexture>): void {
-        if (channel < 0) {
+        if (channel === undefined) {
             return;
         }
 
@@ -6483,7 +6482,7 @@ export class Engine {
      * @param texture The render target texture containing the depth stencil texture to apply
      */
     public setDepthStencilTexture(channel: number, uniform: Nullable<WebGLUniformLocation>, texture: Nullable<RenderTargetTexture>): void {
-        if (channel < 0) {
+        if (channel === undefined) {
             return;
         }
 
@@ -6642,7 +6641,7 @@ export class Engine {
      * @param textures defines the array of textures to bind
      */
     public setTextureArray(channel: number, uniform: Nullable<WebGLUniformLocation>, textures: BaseTexture[]): void {
-        if (channel < 0 || !uniform) {
+        if (channel === undefined || !uniform) {
             return;
         }
 

+ 43 - 42
src/Materials/effect.ts

@@ -242,12 +242,12 @@ export class Effect {
     private _uniformBuffersNames: { [key: string]: number } = {};
     private _uniformsNames: string[];
     private _samplerList: string[];
-    private _samplers: { [key: string]: number } = {}
+    private _samplers: {[key: string]: number} = {};
     private _isReady = false;
     private _compilationError = "";
     private _attributesNames: string[];
     private _attributes: number[];
-    private _uniforms: { [key: string]: Nullable<WebGLUniformLocation> } = {};
+    private _uniforms: {[key: string] :Nullable<WebGLUniformLocation>} = {};
     /**
      * Key for the effect.
      * @hidden
@@ -836,15 +836,14 @@ export class Effect {
                 }
 
                 let uniforms = engine.getUniforms(this._program, this._uniformsNames);
-
-                this._uniformsNames.forEach((name, index) => {
-                    this._uniforms[name] = uniforms[index];
+                uniforms.forEach((uniform, index) => {
+                    this._uniforms[this._uniformsNames[index]] = uniform;
                 });
 
                 this._attributes = engine.getAttributes(this._program, attributesNames);
 
                 var index: number;
-                for (index = 0; index < this._samplers.length; index++) {
+                for (index = 0; index < this._samplerList.length; index++) {
                     var sampler = this.getUniform(this._samplerList[index]);
 
                     if (sampler == null) {
@@ -853,11 +852,11 @@ export class Effect {
                     }
                 }
 
-                engine.bindSamplers(this);
+                this._samplerList.forEach((name, index) => {
+                    this._samplers[name] = index;
+                })
 
-                this._samplerList.forEach((name, i) => {
-                    this._samplers[name] = i;
-                });
+                engine.bindSamplers(this);
 
                 this._compilationError = "";
                 this._isReady = true;
@@ -963,10 +962,12 @@ export class Effect {
      * @param textures Textures to set.
      */
     public setTextureArray(channel: string, textures: BaseTexture[]): void {
-        if (this._samplers.indexOf(channel + "Ex") === -1) {
-            var initialPos = this._samplers.indexOf(channel);
+        let exName = channel + "Ex";
+        if (this._samplerList.indexOf(exName) === -1) {
+            var initialPos = this._samplers[channel];
             for (var index = 1; index < textures.length; index++) {
-                this._samplers.splice(initialPos + index, 0, channel + "Ex");
+                this._samplerList.splice(initialPos + index, 0, exName);
+                this._samplers[exName] = initialPos + index;
             }
         }
 
@@ -1120,7 +1121,7 @@ export class Effect {
 
         this._valueCache[uniformName] = value;
 
-        this._engine.setInt(this.getUniform(uniformName), value);
+        this._engine.setInt(this._uniforms[uniformName], value);
 
         return this;
     }
@@ -1133,7 +1134,7 @@ export class Effect {
      */
     public setIntArray(uniformName: string, array: Int32Array): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setIntArray(this.getUniform(uniformName), array);
+        this._engine.setIntArray(this._uniforms[uniformName], array);
 
         return this;
     }
@@ -1146,7 +1147,7 @@ export class Effect {
      */
     public setIntArray2(uniformName: string, array: Int32Array): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setIntArray2(this.getUniform(uniformName), array);
+        this._engine.setIntArray2(this._uniforms[uniformName], array);
 
         return this;
     }
@@ -1159,7 +1160,7 @@ export class Effect {
      */
     public setIntArray3(uniformName: string, array: Int32Array): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setIntArray3(this.getUniform(uniformName), array);
+        this._engine.setIntArray3(this._uniforms[uniformName], array);
 
         return this;
     }
@@ -1172,7 +1173,7 @@ export class Effect {
      */
     public setIntArray4(uniformName: string, array: Int32Array): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setIntArray4(this.getUniform(uniformName), array);
+        this._engine.setIntArray4(this._uniforms[uniformName], array);
 
         return this;
     }
@@ -1185,7 +1186,7 @@ export class Effect {
      */
     public setFloatArray(uniformName: string, array: Float32Array): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setFloatArray(this.getUniform(uniformName), array);
+        this._engine.setFloatArray(this._uniforms[uniformName], array);
 
         return this;
     }
@@ -1198,7 +1199,7 @@ export class Effect {
      */
     public setFloatArray2(uniformName: string, array: Float32Array): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setFloatArray2(this.getUniform(uniformName), array);
+        this._engine.setFloatArray2(this._uniforms[uniformName], array);
 
         return this;
     }
@@ -1211,7 +1212,7 @@ export class Effect {
      */
     public setFloatArray3(uniformName: string, array: Float32Array): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setFloatArray3(this.getUniform(uniformName), array);
+        this._engine.setFloatArray3(this._uniforms[uniformName], array);
 
         return this;
     }
@@ -1224,7 +1225,7 @@ export class Effect {
      */
     public setFloatArray4(uniformName: string, array: Float32Array): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setFloatArray4(this.getUniform(uniformName), array);
+        this._engine.setFloatArray4(this._uniforms[uniformName], array);
 
         return this;
     }
@@ -1237,7 +1238,7 @@ export class Effect {
      */
     public setArray(uniformName: string, array: number[]): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setArray(this.getUniform(uniformName), array);
+        this._engine.setArray(this._uniforms[uniformName], array);
 
         return this;
     }
@@ -1250,7 +1251,7 @@ export class Effect {
      */
     public setArray2(uniformName: string, array: number[]): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setArray2(this.getUniform(uniformName), array);
+        this._engine.setArray2(this._uniforms[uniformName], array);
 
         return this;
     }
@@ -1263,7 +1264,7 @@ export class Effect {
      */
     public setArray3(uniformName: string, array: number[]): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setArray3(this.getUniform(uniformName), array);
+        this._engine.setArray3(this._uniforms[uniformName], array);
 
         return this;
     }
@@ -1276,7 +1277,7 @@ export class Effect {
      */
     public setArray4(uniformName: string, array: number[]): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setArray4(this.getUniform(uniformName), array);
+        this._engine.setArray4(this._uniforms[uniformName], array);
 
         return this;
     }
@@ -1293,7 +1294,7 @@ export class Effect {
         }
 
         this._valueCache[uniformName] = null;
-        this._engine.setMatrices(this.getUniform(uniformName), matrices);
+        this._engine.setMatrices(this._uniforms[uniformName], matrices);
 
         return this;
     }
@@ -1306,7 +1307,7 @@ export class Effect {
      */
     public setMatrix(uniformName: string, matrix: Matrix): Effect {
         if (this._cacheMatrix(uniformName, matrix)) {
-            this._engine.setMatrix(this.getUniform(uniformName), matrix);
+            this._engine.setMatrix(this._uniforms[uniformName], matrix);
         }
         return this;
     }
@@ -1319,7 +1320,7 @@ export class Effect {
      */
     public setMatrix3x3(uniformName: string, matrix: Float32Array): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setMatrix3x3(this.getUniform(uniformName), matrix);
+        this._engine.setMatrix3x3(this._uniforms[uniformName], matrix);
 
         return this;
     }
@@ -1332,7 +1333,7 @@ export class Effect {
      */
     public setMatrix2x2(uniformName: string, matrix: Float32Array): Effect {
         this._valueCache[uniformName] = null;
-        this._engine.setMatrix2x2(this.getUniform(uniformName), matrix);
+        this._engine.setMatrix2x2(this._uniforms[uniformName], matrix);
 
         return this;
     }
@@ -1351,7 +1352,7 @@ export class Effect {
 
         this._valueCache[uniformName] = value;
 
-        this._engine.setFloat(this.getUniform(uniformName), value);
+        this._engine.setFloat(this._uniforms[uniformName], value);
 
         return this;
     }
@@ -1370,7 +1371,7 @@ export class Effect {
 
         this._valueCache[uniformName] = bool;
 
-        this._engine.setBool(this.getUniform(uniformName), bool ? 1 : 0);
+        this._engine.setBool(this._uniforms[uniformName], bool ? 1 : 0);
 
         return this;
     }
@@ -1383,7 +1384,7 @@ export class Effect {
      */
     public setVector2(uniformName: string, vector2: Vector2): Effect {
         if (this._cacheFloat2(uniformName, vector2.x, vector2.y)) {
-            this._engine.setFloat2(this.getUniform(uniformName), vector2.x, vector2.y);
+            this._engine.setFloat2(this._uniforms[uniformName], vector2.x, vector2.y);
         }
         return this;
     }
@@ -1397,7 +1398,7 @@ export class Effect {
      */
     public setFloat2(uniformName: string, x: number, y: number): Effect {
         if (this._cacheFloat2(uniformName, x, y)) {
-            this._engine.setFloat2(this.getUniform(uniformName), x, y);
+            this._engine.setFloat2(this._uniforms[uniformName], x, y);
         }
         return this;
     }
@@ -1410,7 +1411,7 @@ export class Effect {
      */
     public setVector3(uniformName: string, vector3: Vector3): Effect {
         if (this._cacheFloat3(uniformName, vector3.x, vector3.y, vector3.z)) {
-            this._engine.setFloat3(this.getUniform(uniformName), vector3.x, vector3.y, vector3.z);
+            this._engine.setFloat3(this._uniforms[uniformName], vector3.x, vector3.y, vector3.z);
         }
         return this;
     }
@@ -1425,7 +1426,7 @@ export class Effect {
      */
     public setFloat3(uniformName: string, x: number, y: number, z: number): Effect {
         if (this._cacheFloat3(uniformName, x, y, z)) {
-            this._engine.setFloat3(this.getUniform(uniformName), x, y, z);
+            this._engine.setFloat3(this._uniforms[uniformName], x, y, z);
         }
         return this;
     }
@@ -1438,7 +1439,7 @@ export class Effect {
      */
     public setVector4(uniformName: string, vector4: Vector4): Effect {
         if (this._cacheFloat4(uniformName, vector4.x, vector4.y, vector4.z, vector4.w)) {
-            this._engine.setFloat4(this.getUniform(uniformName), vector4.x, vector4.y, vector4.z, vector4.w);
+            this._engine.setFloat4(this._uniforms[uniformName], vector4.x, vector4.y, vector4.z, vector4.w);
         }
         return this;
     }
@@ -1454,7 +1455,7 @@ export class Effect {
      */
     public setFloat4(uniformName: string, x: number, y: number, z: number, w: number): Effect {
         if (this._cacheFloat4(uniformName, x, y, z, w)) {
-            this._engine.setFloat4(this.getUniform(uniformName), x, y, z, w);
+            this._engine.setFloat4(this._uniforms[uniformName], x, y, z, w);
         }
         return this;
     }
@@ -1468,7 +1469,7 @@ export class Effect {
     public setColor3(uniformName: string, color3: Color3): Effect {
 
         if (this._cacheFloat3(uniformName, color3.r, color3.g, color3.b)) {
-            this._engine.setColor3(this.getUniform(uniformName), color3);
+            this._engine.setColor3(this._uniforms[uniformName], color3);
         }
         return this;
     }
@@ -1482,7 +1483,7 @@ export class Effect {
      */
     public setColor4(uniformName: string, color3: Color3, alpha: number): Effect {
         if (this._cacheFloat4(uniformName, color3.r, color3.g, color3.b, alpha)) {
-            this._engine.setColor4(this.getUniform(uniformName), color3, alpha);
+            this._engine.setColor4(this._uniforms[uniformName], color3, alpha);
         }
         return this;
     }
@@ -1495,7 +1496,7 @@ export class Effect {
      */
     public setDirectColor4(uniformName: string, color4: Color4): Effect {
         if (this._cacheFloat4(uniformName, color4.r, color4.g, color4.b, color4.a)) {
-            this._engine.setDirectColor4(this.getUniform(uniformName), color4);
+            this._engine.setDirectColor4(this._uniforms[uniformName], color4);
         }
         return this;
     }
@@ -1531,4 +1532,4 @@ export class Effect {
     public static ResetCache() {
         Effect._baseCache = {};
     }
-}
+}

+ 50 - 19
src/Meshes/transformNode.ts

@@ -108,11 +108,30 @@ export class TransformNode extends Node {
     @serialize()
     public scalingDeterminant = 1;
 
+
+    @serialize("infiniteDistance")
+    private _infiniteDistance = false;
+
     /**
-     * Sets the distance of the object to max, often used by skybox
+     * Gets or sets the distance of the object to max, often used by skybox
      */
-    @serialize()
-    public infiniteDistance = false;
+    public get infiniteDistance() {
+        return this._infiniteDistance;
+    }
+
+    public set infiniteDistance(value: boolean) {
+        if (this._infiniteDistance === value) {
+            return;
+        }
+
+        this._infiniteDistance = value;
+
+        if (value) {
+            this._translationProcessor = this._infiniteDistanceTranslationProcessor;
+        } else {
+            this._translationProcessor = this._defaultTranslationProcessor;
+        }
+    }
 
     /**
      * Gets or sets a boolean indicating that non uniform scaling (when at least one component is different from others) should be ignored.
@@ -166,7 +185,8 @@ export class TransformNode extends Node {
         }
 
         this._activeParentProcessor = this._defaultParentProcessor;
-        this._activeCompositionProcess = this._defaultCompositionProcessor;
+        this._activeCompositionProcessor = this._defaultCompositionProcessor;
+        this._translationProcessor = this._defaultTranslationProcessor;
     }
 
     /**
@@ -363,9 +383,9 @@ export class TransformNode extends Node {
     public setPivotMatrix(matrix: DeepImmutable<Matrix>, postMultiplyPivotMatrix = true): TransformNode {
         this._pivotMatrix.copyFrom(matrix);
         if (this._pivotMatrix.isIdentity()) {
-            this._activeCompositionProcess = this._defaultCompositionProcessor;
+            this._activeCompositionProcessor = this._defaultCompositionProcessor;
         } else {
-            this._activeCompositionProcess = this._pivotCompositionProcessor;
+            this._activeCompositionProcessor = this._pivotCompositionProcessor;
         }
         this._cache.pivotMatrixUpdated = true;
         this._postMultiplyPivotMatrix = postMultiplyPivotMatrix;
@@ -903,7 +923,7 @@ export class TransformNode extends Node {
         return this.parent;
     }
 
-    private _activeCompositionProcess: (scaling: Vector3, rotation: Quaternion, translation: Vector3) => void;
+    private _activeCompositionProcessor: (scaling: Vector3, rotation: Quaternion, translation: Vector3) => void;
 
     private _defaultCompositionProcessor = (scaling: Vector3, rotation: Quaternion, translation: Vector3) => {
         Matrix.ComposeToRef(scaling, rotation, translation, this._localMatrix);
@@ -929,6 +949,26 @@ export class TransformNode extends Node {
         this._localMatrix.addTranslationFromFloats(translation.x, translation.y, translation.z);
     }
 
+    // Infinite distance
+    private _translationProcessor: (translation: Vector3) => void;
+
+    private _defaultTranslationProcessor = (translation: Vector3) => {
+        translation.copyFrom(this._position);
+    }
+
+    private _infiniteDistanceTranslationProcessor = (translation: Vector3) => {
+        let camera = (<Camera>this.getScene().activeCamera);
+
+        if (!this.parent && camera) {
+            var cameraWorldMatrix = camera.getWorldMatrix();
+            var cameraGlobalPosition = new Vector3(cameraWorldMatrix.m[12], cameraWorldMatrix.m[13], cameraWorldMatrix.m[14]);
+
+            translation.copyFromFloats(this._position.x + cameraGlobalPosition.x, this._position.y + cameraGlobalPosition.y, this._position.z + cameraGlobalPosition.z);
+        } else {
+            translation.copyFrom(this._position);
+        }
+    }
+
     // Billboards
     private _activeParentProcessor: (parent: Node) => void;
     private _activeBillboardPostProcessor = () => { };
@@ -1006,7 +1046,7 @@ export class TransformNode extends Node {
     public computeWorldMatrix(force?: boolean): Matrix {
         let currentRenderId = this.getScene().getRenderId();
 
-        if (this._isWorldMatrixFrozen) {
+        if (this._isWorldMatrixFrozen && !this._isDirty) {
             return this._worldMatrix;
         }
 
@@ -1030,16 +1070,7 @@ export class TransformNode extends Node {
         let translation: Vector3 = this._cache.position;
 
         // Translation
-        let camera = (<Camera>this.getScene().activeCamera);
-
-        if (this.infiniteDistance && !this.parent && camera) {
-            var cameraWorldMatrix = camera.getWorldMatrix();
-            var cameraGlobalPosition = new Vector3(cameraWorldMatrix.m[12], cameraWorldMatrix.m[13], cameraWorldMatrix.m[14]);
-
-            translation.copyFromFloats(this._position.x + cameraGlobalPosition.x, this._position.y + cameraGlobalPosition.y, this._position.z + cameraGlobalPosition.z);
-        } else {
-            translation.copyFrom(this._position);
-        }
+        this._translationProcessor(translation);
 
         // Scaling
         scaling.copyFromFloats(this._scaling.x * this.scalingDeterminant, this._scaling.y * this.scalingDeterminant, this._scaling.z * this.scalingDeterminant);
@@ -1061,7 +1092,7 @@ export class TransformNode extends Node {
         }
 
         // Compose
-        this._activeCompositionProcess(scaling, rotation, translation);
+        this._activeCompositionProcessor(scaling, rotation, translation);
 
         // Parent
         if (parent && parent.getWorldMatrix) {

BIN
tests/validation/ReferenceImages/weighted animations.png


+ 6 - 0
tests/validation/config.json

@@ -2,6 +2,12 @@
   "root": "https://rawgit.com/BabylonJS/Website/master",
   "tests": [
     {
+      "title": "Weighted animations",
+      "playgroundId": "#LL5BIQ#72",
+      "renderCount": 50,
+      "referenceImage": "weighted animations.png"
+    },
+    {
       "title": "Anisotropic",
       "playgroundId": "#MAXCNU#1",
       "referenceImage": "anisotropic.png"