Przeglądaj źródła

Merge pull request #6129 from BabylonJS/master

Nightly
David Catuhe 6 lat temu
rodzic
commit
2d068e1041

+ 30 - 9
Playground/babylon.d.txt

@@ -7428,8 +7428,9 @@ declare module BABYLON {
          * Multiplication factor on scale x/y/z when computing the world matrix. Eg. for a 1x1x1 cube setting this to 2 will make it a 2x2x2 cube
          */
         scalingDeterminant: number;
+        private _infiniteDistance;
         /**
-         * 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
          */
         infiniteDistance: boolean;
         /**
@@ -7720,9 +7721,12 @@ declare module BABYLON {
          * @hidden
          */
         protected _getEffectiveParent(): Nullable<Node>;
-        private _activeCompositionProcess;
+        private _activeCompositionProcessor;
         private _defaultCompositionProcessor;
         private _pivotCompositionProcessor;
+        private _translationProcessor;
+        private _defaultTranslationProcessor;
+        private _infiniteDistanceTranslationProcessor;
         private _activeParentProcessor;
         private _activeBillboardPostProcessor;
         private _defaultParentProcessor;
@@ -16354,7 +16358,7 @@ declare module BABYLON {
          */
         refreshBoundingInfo(applySkeleton?: boolean): InstancedMesh;
         /** @hidden */
preActivate(): InstancedMesh;
-        /** @hidden */
activate(renderId: number): InstancedMesh;
+        /** @hidden */
activate(renderId: number): boolean;
         /**
          * Returns the current associated LOD AbstractMesh.
          */
@@ -16958,7 +16962,7 @@ declare module BABYLON {
         private _renderOpaque;
         private _renderAlphaTest;
         private _renderTransparent;
-        private _edgesRenderers;
+        /** @hidden */
edgesRenderers: SmartArray<IEdgesRenderer>;
         onBeforeTransparentRendering: () => void;
         /**
          * Set the opaque sort comparison function.
@@ -18054,6 +18058,7 @@ declare module BABYLON {
          */
         private _activeTargets;
         private _currentActiveTarget;
+        private _directTarget;
         /**
          * The target path of the runtime animation
          */
@@ -18076,6 +18081,11 @@ declare module BABYLON {
         private _previousRatio;
         private _enableBlending;
         private _correctLoopMode;
+        private _keys;
+        private _minFrame;
+        private _maxFrame;
+        private _minValue;
+        private _maxValue;
         /**
          * Gets the current frame of the runtime animation
          */
@@ -18104,6 +18114,8 @@ declare module BABYLON {
          * @param host defines the initiating Animatable
          */
         constructor(target: any, animation: Animation, scene: Scene, host: Animatable);
+        private _normalizationProcessor;
+        private _defaultNormalizationProcessor;
         private _preparePath;
         /**
          * Gets the animation from the runtime animation
@@ -18135,10 +18147,10 @@ declare module BABYLON {
         private _interpolate;
         /**
          * Apply the interpolated value to the target
-         * @param currentValue defines the value computed by the animation
-         * @param weight defines the weight to apply to this value (Defaults to 1.0)
          */
-        setValue(currentValue: any, weight?: number): void;
+        setValue: (currentValue: any, weight: number) => void;
+        private _setValueForArray;
+        private _setValueForDirect;
         private _getOriginalValues;
         private _activeBlendingProcessor;
         private _noBlendingProcessor;
@@ -20123,12 +20135,13 @@ declare module BABYLON {
      * @hidden
      **/
private class _InstanceDataStorage {
         visibleInstances: any;
-        renderIdForInstances: number[];
         batchCache: _InstancesBatch;
         instancesBufferSize: number;
         instancesBuffer: Nullable<Buffer>;
         instancesData: Float32Array;
         overridenInstanceCount: number;
+        isFrozen: boolean;
previousBatch: _InstancesBatch;
+        hardwareInstancedRendering: boolean;
     }
     /**
      * @hidden
@@ -20137,6 +20150,7 @@ declare module BABYLON {
         mustReturn: boolean;
         visibleInstances: Nullable<InstancedMesh[]>[];
         renderSelf: boolean[];
+        hardwareInstancedRendering: boolean[];
     }
     /**
      * Class used to represent renderable models
@@ -20609,6 +20623,8 @@ declare module BABYLON {
         /** @hidden */
getInstancesRenderList(subMeshId: number): _InstancesBatch;
         /** @hidden */
renderWithInstances(subMesh: SubMesh, fillMode: number, batch: _InstancesBatch, effect: Effect, engine: Engine): Mesh;
         /** @hidden */
processRendering(subMesh: SubMesh, effect: Effect, fillMode: number, batch: _InstancesBatch, hardwareInstancedRendering: boolean, onBeforeDraw: (isInstance: boolean, world: Matrix, effectiveMaterial?: Material) => void, effectiveMaterial?: Material): Mesh;
+        /** @hidden */
freeze(): void;
+        /** @hidden */
unFreeze(): void;
         /**
          * Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager
          * @param subMesh defines the subMesh to render
@@ -23562,6 +23578,8 @@ declare module BABYLON {
         definedFacingForward: boolean;
         /** @hidden */
occlusionQuery: Nullable<WebGLQuery>;
         private _visibility;
+        /** @hidden */
isActive: boolean;
+        /** @hidden */
renderingGroup: RenderingGroup;
         /**
          * Gets or sets mesh visibility between 0 and 1 (default is 1)
          */
@@ -23865,7 +23883,9 @@ declare module BABYLON {
         readonly useBones: boolean;
         /** @hidden */
preActivate(): void;
         /** @hidden */
preActivateForIntermediateRendering(renderId: number): void;
-        /** @hidden */
activate(renderId: number): void;
+        /** @hidden */
activate(renderId: number): boolean;
+        /** @hidden */
freeze(): void;
+        /** @hidden */
unFreeze(): void;
         /**
          * Gets the current world matrix
          * @returns a Matrix
@@ -28498,6 +28518,7 @@ declare module BABYLON {
         private _engine;
         private _uniformBuffersNames;
         private _uniformsNames;
+        private _samplerList;
         private _samplers;
         private _isReady;
         private _compilationError;

+ 38 - 9
dist/preview release/babylon.d.ts

@@ -7510,8 +7510,9 @@ declare module BABYLON {
          * Multiplication factor on scale x/y/z when computing the world matrix. Eg. for a 1x1x1 cube setting this to 2 will make it a 2x2x2 cube
          */
         scalingDeterminant: number;
+        private _infiniteDistance;
         /**
-         * 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
          */
         infiniteDistance: boolean;
         /**
@@ -7808,9 +7809,12 @@ declare module BABYLON {
          * @hidden
          */
         protected _getEffectiveParent(): Nullable<Node>;
-        private _activeCompositionProcess;
+        private _activeCompositionProcessor;
         private _defaultCompositionProcessor;
         private _pivotCompositionProcessor;
+        private _translationProcessor;
+        private _defaultTranslationProcessor;
+        private _infiniteDistanceTranslationProcessor;
         private _activeParentProcessor;
         private _activeBillboardPostProcessor;
         private _defaultParentProcessor;
@@ -16610,7 +16614,7 @@ declare module BABYLON {
         /** @hidden */
         _preActivate(): InstancedMesh;
         /** @hidden */
-        _activate(renderId: number): InstancedMesh;
+        _activate(renderId: number): boolean;
         /**
          * Returns the current associated LOD AbstractMesh.
          */
@@ -17221,7 +17225,8 @@ declare module BABYLON {
         private _renderOpaque;
         private _renderAlphaTest;
         private _renderTransparent;
-        private _edgesRenderers;
+        /** @hidden */
+        _edgesRenderers: SmartArray<IEdgesRenderer>;
         onBeforeTransparentRendering: () => void;
         /**
          * Set the opaque sort comparison function.
@@ -18329,6 +18334,7 @@ declare module BABYLON {
          */
         private _activeTargets;
         private _currentActiveTarget;
+        private _directTarget;
         /**
          * The target path of the runtime animation
          */
@@ -18351,6 +18357,11 @@ declare module BABYLON {
         private _previousRatio;
         private _enableBlending;
         private _correctLoopMode;
+        private _keys;
+        private _minFrame;
+        private _maxFrame;
+        private _minValue;
+        private _maxValue;
         /**
          * Gets the current frame of the runtime animation
          */
@@ -18379,6 +18390,8 @@ declare module BABYLON {
          * @param host defines the initiating Animatable
          */
         constructor(target: any, animation: Animation, scene: Scene, host: Animatable);
+        private _normalizationProcessor;
+        private _defaultNormalizationProcessor;
         private _preparePath;
         /**
          * Gets the animation from the runtime animation
@@ -18410,10 +18423,10 @@ declare module BABYLON {
         private _interpolate;
         /**
          * Apply the interpolated value to the target
-         * @param currentValue defines the value computed by the animation
-         * @param weight defines the weight to apply to this value (Defaults to 1.0)
          */
-        setValue(currentValue: any, weight?: number): void;
+        setValue: (currentValue: any, weight: number) => void;
+        private _setValueForArray;
+        private _setValueForDirect;
         private _getOriginalValues;
         private _activeBlendingProcessor;
         private _noBlendingProcessor;
@@ -20423,12 +20436,14 @@ declare module BABYLON {
      **/
     class _InstanceDataStorage {
         visibleInstances: any;
-        renderIdForInstances: number[];
         batchCache: _InstancesBatch;
         instancesBufferSize: number;
         instancesBuffer: Nullable<Buffer>;
         instancesData: Float32Array;
         overridenInstanceCount: number;
+        isFrozen: boolean;
+        _previousBatch: _InstancesBatch;
+        hardwareInstancedRendering: boolean;
     }
     /**
      * @hidden
@@ -20437,6 +20452,7 @@ declare module BABYLON {
         mustReturn: boolean;
         visibleInstances: Nullable<InstancedMesh[]>[];
         renderSelf: boolean[];
+        hardwareInstancedRendering: boolean[];
     }
     /**
      * Class used to represent renderable models
@@ -20929,6 +20945,10 @@ declare module BABYLON {
         _renderWithInstances(subMesh: SubMesh, fillMode: number, batch: _InstancesBatch, effect: Effect, engine: Engine): Mesh;
         /** @hidden */
         _processRendering(subMesh: SubMesh, effect: Effect, fillMode: number, batch: _InstancesBatch, hardwareInstancedRendering: boolean, onBeforeDraw: (isInstance: boolean, world: Matrix, effectiveMaterial?: Material) => void, effectiveMaterial?: Material): Mesh;
+        /** @hidden */
+        _freeze(): void;
+        /** @hidden */
+        _unFreeze(): void;
         /**
          * Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager
          * @param subMesh defines the subMesh to render
@@ -23940,6 +23960,10 @@ declare module BABYLON {
         /** @hidden */
         _occlusionQuery: Nullable<WebGLQuery>;
         private _visibility;
+        /** @hidden */
+        _isActive: boolean;
+        /** @hidden */
+        _renderingGroup: RenderingGroup;
         /**
          * Gets or sets mesh visibility between 0 and 1 (default is 1)
          */
@@ -24266,7 +24290,11 @@ declare module BABYLON {
         /** @hidden */
         _preActivateForIntermediateRendering(renderId: number): void;
         /** @hidden */
-        _activate(renderId: number): void;
+        _activate(renderId: number): boolean;
+        /** @hidden */
+        _freeze(): void;
+        /** @hidden */
+        _unFreeze(): void;
         /**
          * Gets the current world matrix
          * @returns a Matrix
@@ -28979,6 +29007,7 @@ declare module BABYLON {
         private _engine;
         private _uniformBuffersNames;
         private _uniformsNames;
+        private _samplerList;
         private _samplers;
         private _isReady;
         private _compilationError;

Plik diff jest za duży
+ 1 - 1
dist/preview release/babylon.js


Plik diff jest za duży
+ 280 - 204
dist/preview release/babylon.max.js


Plik diff jest za duży
+ 1 - 1
dist/preview release/babylon.max.js.map


+ 78 - 18
dist/preview release/babylon.module.d.ts

@@ -7565,8 +7565,9 @@ declare module "babylonjs/Meshes/transformNode" {
          * Multiplication factor on scale x/y/z when computing the world matrix. Eg. for a 1x1x1 cube setting this to 2 will make it a 2x2x2 cube
          */
         scalingDeterminant: number;
+        private _infiniteDistance;
         /**
-         * 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
          */
         infiniteDistance: boolean;
         /**
@@ -7863,9 +7864,12 @@ declare module "babylonjs/Meshes/transformNode" {
          * @hidden
          */
         protected _getEffectiveParent(): Nullable<Node>;
-        private _activeCompositionProcess;
+        private _activeCompositionProcessor;
         private _defaultCompositionProcessor;
         private _pivotCompositionProcessor;
+        private _translationProcessor;
+        private _defaultTranslationProcessor;
+        private _infiniteDistanceTranslationProcessor;
         private _activeParentProcessor;
         private _activeBillboardPostProcessor;
         private _defaultParentProcessor;
@@ -17007,7 +17011,7 @@ declare module "babylonjs/Meshes/instancedMesh" {
         /** @hidden */
         _preActivate(): InstancedMesh;
         /** @hidden */
-        _activate(renderId: number): InstancedMesh;
+        _activate(renderId: number): boolean;
         /**
          * Returns the current associated LOD AbstractMesh.
          */
@@ -17643,6 +17647,7 @@ declare module "babylonjs/Rendering/renderingGroup" {
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Nullable } from "babylonjs/types";
     import { IParticleSystem } from "babylonjs/Particles/IParticleSystem";
+    import { IEdgesRenderer } from "babylonjs/Rendering/edgesRenderer";
     import { ISpriteManager } from "babylonjs/Sprites/spriteManager";
     import { Material } from "babylonjs/Materials/material";
     import { Scene } from "babylonjs/scene";
@@ -17667,7 +17672,8 @@ declare module "babylonjs/Rendering/renderingGroup" {
         private _renderOpaque;
         private _renderAlphaTest;
         private _renderTransparent;
-        private _edgesRenderers;
+        /** @hidden */
+        _edgesRenderers: SmartArray<IEdgesRenderer>;
         onBeforeTransparentRendering: () => void;
         /**
          * Set the opaque sort comparison function.
@@ -18812,6 +18818,7 @@ declare module "babylonjs/Animations/runtimeAnimation" {
          */
         private _activeTargets;
         private _currentActiveTarget;
+        private _directTarget;
         /**
          * The target path of the runtime animation
          */
@@ -18834,6 +18841,11 @@ declare module "babylonjs/Animations/runtimeAnimation" {
         private _previousRatio;
         private _enableBlending;
         private _correctLoopMode;
+        private _keys;
+        private _minFrame;
+        private _maxFrame;
+        private _minValue;
+        private _maxValue;
         /**
          * Gets the current frame of the runtime animation
          */
@@ -18862,6 +18874,8 @@ declare module "babylonjs/Animations/runtimeAnimation" {
          * @param host defines the initiating Animatable
          */
         constructor(target: any, animation: Animation, scene: Scene, host: Animatable);
+        private _normalizationProcessor;
+        private _defaultNormalizationProcessor;
         private _preparePath;
         /**
          * Gets the animation from the runtime animation
@@ -18893,10 +18907,10 @@ declare module "babylonjs/Animations/runtimeAnimation" {
         private _interpolate;
         /**
          * Apply the interpolated value to the target
-         * @param currentValue defines the value computed by the animation
-         * @param weight defines the weight to apply to this value (Defaults to 1.0)
          */
-        setValue(currentValue: any, weight?: number): void;
+        setValue: (currentValue: any, weight: number) => void;
+        private _setValueForArray;
+        private _setValueForDirect;
         private _getOriginalValues;
         private _activeBlendingProcessor;
         private _noBlendingProcessor;
@@ -20983,12 +20997,14 @@ declare module "babylonjs/Meshes/mesh" {
      **/
     class _InstanceDataStorage {
         visibleInstances: any;
-        renderIdForInstances: number[];
         batchCache: _InstancesBatch;
         instancesBufferSize: number;
         instancesBuffer: Nullable<Buffer>;
         instancesData: Float32Array;
         overridenInstanceCount: number;
+        isFrozen: boolean;
+        _previousBatch: _InstancesBatch;
+        hardwareInstancedRendering: boolean;
     }
     /**
      * @hidden
@@ -20997,6 +21013,7 @@ declare module "babylonjs/Meshes/mesh" {
         mustReturn: boolean;
         visibleInstances: Nullable<import("babylonjs/Meshes/instancedMesh").InstancedMesh[]>[];
         renderSelf: boolean[];
+        hardwareInstancedRendering: boolean[];
     }
     /**
      * Class used to represent renderable models
@@ -21489,6 +21506,10 @@ declare module "babylonjs/Meshes/mesh" {
         _renderWithInstances(subMesh: SubMesh, fillMode: number, batch: _InstancesBatch, effect: Effect, engine: Engine): Mesh;
         /** @hidden */
         _processRendering(subMesh: SubMesh, effect: Effect, fillMode: number, batch: _InstancesBatch, hardwareInstancedRendering: boolean, onBeforeDraw: (isInstance: boolean, world: Matrix, effectiveMaterial?: Material) => void, effectiveMaterial?: Material): Mesh;
+        /** @hidden */
+        _freeze(): void;
+        /** @hidden */
+        _unFreeze(): void;
         /**
          * Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager
          * @param subMesh defines the subMesh to render
@@ -24442,6 +24463,7 @@ declare module "babylonjs/Meshes/abstractMesh" {
     import { Ray } from "babylonjs/Culling/ray";
     import { Collider } from "babylonjs/Collisions/collider";
     import { TrianglePickingPredicate } from "babylonjs/Culling/ray";
+    import { RenderingGroup } from "babylonjs/Rendering/renderingGroup";
     /**
      * Class used to store all common mesh properties
      */
@@ -24576,6 +24598,10 @@ declare module "babylonjs/Meshes/abstractMesh" {
         /** @hidden */
         _occlusionQuery: Nullable<WebGLQuery>;
         private _visibility;
+        /** @hidden */
+        _isActive: boolean;
+        /** @hidden */
+        _renderingGroup: RenderingGroup;
         /**
          * Gets or sets mesh visibility between 0 and 1 (default is 1)
          */
@@ -24902,7 +24928,11 @@ declare module "babylonjs/Meshes/abstractMesh" {
         /** @hidden */
         _preActivateForIntermediateRendering(renderId: number): void;
         /** @hidden */
-        _activate(renderId: number): void;
+        _activate(renderId: number): boolean;
+        /** @hidden */
+        _freeze(): void;
+        /** @hidden */
+        _unFreeze(): void;
         /**
          * Gets the current world matrix
          * @returns a Matrix
@@ -29708,6 +29738,7 @@ declare module "babylonjs/Materials/effect" {
         private _engine;
         private _uniformBuffersNames;
         private _uniformsNames;
+        private _samplerList;
         private _samplers;
         private _isReady;
         private _compilationError;
@@ -66966,8 +66997,9 @@ declare module BABYLON {
          * Multiplication factor on scale x/y/z when computing the world matrix. Eg. for a 1x1x1 cube setting this to 2 will make it a 2x2x2 cube
          */
         scalingDeterminant: number;
+        private _infiniteDistance;
         /**
-         * 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
          */
         infiniteDistance: boolean;
         /**
@@ -67264,9 +67296,12 @@ declare module BABYLON {
          * @hidden
          */
         protected _getEffectiveParent(): Nullable<Node>;
-        private _activeCompositionProcess;
+        private _activeCompositionProcessor;
         private _defaultCompositionProcessor;
         private _pivotCompositionProcessor;
+        private _translationProcessor;
+        private _defaultTranslationProcessor;
+        private _infiniteDistanceTranslationProcessor;
         private _activeParentProcessor;
         private _activeBillboardPostProcessor;
         private _defaultParentProcessor;
@@ -76066,7 +76101,7 @@ declare module BABYLON {
         /** @hidden */
         _preActivate(): InstancedMesh;
         /** @hidden */
-        _activate(renderId: number): InstancedMesh;
+        _activate(renderId: number): boolean;
         /**
          * Returns the current associated LOD AbstractMesh.
          */
@@ -76677,7 +76712,8 @@ declare module BABYLON {
         private _renderOpaque;
         private _renderAlphaTest;
         private _renderTransparent;
-        private _edgesRenderers;
+        /** @hidden */
+        _edgesRenderers: SmartArray<IEdgesRenderer>;
         onBeforeTransparentRendering: () => void;
         /**
          * Set the opaque sort comparison function.
@@ -77785,6 +77821,7 @@ declare module BABYLON {
          */
         private _activeTargets;
         private _currentActiveTarget;
+        private _directTarget;
         /**
          * The target path of the runtime animation
          */
@@ -77807,6 +77844,11 @@ declare module BABYLON {
         private _previousRatio;
         private _enableBlending;
         private _correctLoopMode;
+        private _keys;
+        private _minFrame;
+        private _maxFrame;
+        private _minValue;
+        private _maxValue;
         /**
          * Gets the current frame of the runtime animation
          */
@@ -77835,6 +77877,8 @@ declare module BABYLON {
          * @param host defines the initiating Animatable
          */
         constructor(target: any, animation: Animation, scene: Scene, host: Animatable);
+        private _normalizationProcessor;
+        private _defaultNormalizationProcessor;
         private _preparePath;
         /**
          * Gets the animation from the runtime animation
@@ -77866,10 +77910,10 @@ declare module BABYLON {
         private _interpolate;
         /**
          * Apply the interpolated value to the target
-         * @param currentValue defines the value computed by the animation
-         * @param weight defines the weight to apply to this value (Defaults to 1.0)
          */
-        setValue(currentValue: any, weight?: number): void;
+        setValue: (currentValue: any, weight: number) => void;
+        private _setValueForArray;
+        private _setValueForDirect;
         private _getOriginalValues;
         private _activeBlendingProcessor;
         private _noBlendingProcessor;
@@ -79879,12 +79923,14 @@ declare module BABYLON {
      **/
     class _InstanceDataStorage {
         visibleInstances: any;
-        renderIdForInstances: number[];
         batchCache: _InstancesBatch;
         instancesBufferSize: number;
         instancesBuffer: Nullable<Buffer>;
         instancesData: Float32Array;
         overridenInstanceCount: number;
+        isFrozen: boolean;
+        _previousBatch: _InstancesBatch;
+        hardwareInstancedRendering: boolean;
     }
     /**
      * @hidden
@@ -79893,6 +79939,7 @@ declare module BABYLON {
         mustReturn: boolean;
         visibleInstances: Nullable<InstancedMesh[]>[];
         renderSelf: boolean[];
+        hardwareInstancedRendering: boolean[];
     }
     /**
      * Class used to represent renderable models
@@ -80385,6 +80432,10 @@ declare module BABYLON {
         _renderWithInstances(subMesh: SubMesh, fillMode: number, batch: _InstancesBatch, effect: Effect, engine: Engine): Mesh;
         /** @hidden */
         _processRendering(subMesh: SubMesh, effect: Effect, fillMode: number, batch: _InstancesBatch, hardwareInstancedRendering: boolean, onBeforeDraw: (isInstance: boolean, world: Matrix, effectiveMaterial?: Material) => void, effectiveMaterial?: Material): Mesh;
+        /** @hidden */
+        _freeze(): void;
+        /** @hidden */
+        _unFreeze(): void;
         /**
          * Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager
          * @param subMesh defines the subMesh to render
@@ -83396,6 +83447,10 @@ declare module BABYLON {
         /** @hidden */
         _occlusionQuery: Nullable<WebGLQuery>;
         private _visibility;
+        /** @hidden */
+        _isActive: boolean;
+        /** @hidden */
+        _renderingGroup: RenderingGroup;
         /**
          * Gets or sets mesh visibility between 0 and 1 (default is 1)
          */
@@ -83722,7 +83777,11 @@ declare module BABYLON {
         /** @hidden */
         _preActivateForIntermediateRendering(renderId: number): void;
         /** @hidden */
-        _activate(renderId: number): void;
+        _activate(renderId: number): boolean;
+        /** @hidden */
+        _freeze(): void;
+        /** @hidden */
+        _unFreeze(): void;
         /**
          * Gets the current world matrix
          * @returns a Matrix
@@ -88435,6 +88494,7 @@ declare module BABYLON {
         private _engine;
         private _uniformBuffersNames;
         private _uniformsNames;
+        private _samplerList;
         private _samplers;
         private _isReady;
         private _compilationError;

+ 1 - 1
dist/preview release/packagesSizeBaseLine.json

@@ -1 +1 @@
-{"engineOnly":307307,"sceneOnly":510947,"minGridMaterial":634716,"minStandardMaterial":758535}
+{"engineOnly":307404,"sceneOnly":511972,"minGridMaterial":636046,"minStandardMaterial":759865}

+ 78 - 18
dist/preview release/viewer/babylon.module.d.ts

@@ -7565,8 +7565,9 @@ declare module "babylonjs/Meshes/transformNode" {
          * Multiplication factor on scale x/y/z when computing the world matrix. Eg. for a 1x1x1 cube setting this to 2 will make it a 2x2x2 cube
          */
         scalingDeterminant: number;
+        private _infiniteDistance;
         /**
-         * 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
          */
         infiniteDistance: boolean;
         /**
@@ -7863,9 +7864,12 @@ declare module "babylonjs/Meshes/transformNode" {
          * @hidden
          */
         protected _getEffectiveParent(): Nullable<Node>;
-        private _activeCompositionProcess;
+        private _activeCompositionProcessor;
         private _defaultCompositionProcessor;
         private _pivotCompositionProcessor;
+        private _translationProcessor;
+        private _defaultTranslationProcessor;
+        private _infiniteDistanceTranslationProcessor;
         private _activeParentProcessor;
         private _activeBillboardPostProcessor;
         private _defaultParentProcessor;
@@ -17007,7 +17011,7 @@ declare module "babylonjs/Meshes/instancedMesh" {
         /** @hidden */
         _preActivate(): InstancedMesh;
         /** @hidden */
-        _activate(renderId: number): InstancedMesh;
+        _activate(renderId: number): boolean;
         /**
          * Returns the current associated LOD AbstractMesh.
          */
@@ -17643,6 +17647,7 @@ declare module "babylonjs/Rendering/renderingGroup" {
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Nullable } from "babylonjs/types";
     import { IParticleSystem } from "babylonjs/Particles/IParticleSystem";
+    import { IEdgesRenderer } from "babylonjs/Rendering/edgesRenderer";
     import { ISpriteManager } from "babylonjs/Sprites/spriteManager";
     import { Material } from "babylonjs/Materials/material";
     import { Scene } from "babylonjs/scene";
@@ -17667,7 +17672,8 @@ declare module "babylonjs/Rendering/renderingGroup" {
         private _renderOpaque;
         private _renderAlphaTest;
         private _renderTransparent;
-        private _edgesRenderers;
+        /** @hidden */
+        _edgesRenderers: SmartArray<IEdgesRenderer>;
         onBeforeTransparentRendering: () => void;
         /**
          * Set the opaque sort comparison function.
@@ -18812,6 +18818,7 @@ declare module "babylonjs/Animations/runtimeAnimation" {
          */
         private _activeTargets;
         private _currentActiveTarget;
+        private _directTarget;
         /**
          * The target path of the runtime animation
          */
@@ -18834,6 +18841,11 @@ declare module "babylonjs/Animations/runtimeAnimation" {
         private _previousRatio;
         private _enableBlending;
         private _correctLoopMode;
+        private _keys;
+        private _minFrame;
+        private _maxFrame;
+        private _minValue;
+        private _maxValue;
         /**
          * Gets the current frame of the runtime animation
          */
@@ -18862,6 +18874,8 @@ declare module "babylonjs/Animations/runtimeAnimation" {
          * @param host defines the initiating Animatable
          */
         constructor(target: any, animation: Animation, scene: Scene, host: Animatable);
+        private _normalizationProcessor;
+        private _defaultNormalizationProcessor;
         private _preparePath;
         /**
          * Gets the animation from the runtime animation
@@ -18893,10 +18907,10 @@ declare module "babylonjs/Animations/runtimeAnimation" {
         private _interpolate;
         /**
          * Apply the interpolated value to the target
-         * @param currentValue defines the value computed by the animation
-         * @param weight defines the weight to apply to this value (Defaults to 1.0)
          */
-        setValue(currentValue: any, weight?: number): void;
+        setValue: (currentValue: any, weight: number) => void;
+        private _setValueForArray;
+        private _setValueForDirect;
         private _getOriginalValues;
         private _activeBlendingProcessor;
         private _noBlendingProcessor;
@@ -20983,12 +20997,14 @@ declare module "babylonjs/Meshes/mesh" {
      **/
     class _InstanceDataStorage {
         visibleInstances: any;
-        renderIdForInstances: number[];
         batchCache: _InstancesBatch;
         instancesBufferSize: number;
         instancesBuffer: Nullable<Buffer>;
         instancesData: Float32Array;
         overridenInstanceCount: number;
+        isFrozen: boolean;
+        _previousBatch: _InstancesBatch;
+        hardwareInstancedRendering: boolean;
     }
     /**
      * @hidden
@@ -20997,6 +21013,7 @@ declare module "babylonjs/Meshes/mesh" {
         mustReturn: boolean;
         visibleInstances: Nullable<import("babylonjs/Meshes/instancedMesh").InstancedMesh[]>[];
         renderSelf: boolean[];
+        hardwareInstancedRendering: boolean[];
     }
     /**
      * Class used to represent renderable models
@@ -21489,6 +21506,10 @@ declare module "babylonjs/Meshes/mesh" {
         _renderWithInstances(subMesh: SubMesh, fillMode: number, batch: _InstancesBatch, effect: Effect, engine: Engine): Mesh;
         /** @hidden */
         _processRendering(subMesh: SubMesh, effect: Effect, fillMode: number, batch: _InstancesBatch, hardwareInstancedRendering: boolean, onBeforeDraw: (isInstance: boolean, world: Matrix, effectiveMaterial?: Material) => void, effectiveMaterial?: Material): Mesh;
+        /** @hidden */
+        _freeze(): void;
+        /** @hidden */
+        _unFreeze(): void;
         /**
          * Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager
          * @param subMesh defines the subMesh to render
@@ -24442,6 +24463,7 @@ declare module "babylonjs/Meshes/abstractMesh" {
     import { Ray } from "babylonjs/Culling/ray";
     import { Collider } from "babylonjs/Collisions/collider";
     import { TrianglePickingPredicate } from "babylonjs/Culling/ray";
+    import { RenderingGroup } from "babylonjs/Rendering/renderingGroup";
     /**
      * Class used to store all common mesh properties
      */
@@ -24576,6 +24598,10 @@ declare module "babylonjs/Meshes/abstractMesh" {
         /** @hidden */
         _occlusionQuery: Nullable<WebGLQuery>;
         private _visibility;
+        /** @hidden */
+        _isActive: boolean;
+        /** @hidden */
+        _renderingGroup: RenderingGroup;
         /**
          * Gets or sets mesh visibility between 0 and 1 (default is 1)
          */
@@ -24902,7 +24928,11 @@ declare module "babylonjs/Meshes/abstractMesh" {
         /** @hidden */
         _preActivateForIntermediateRendering(renderId: number): void;
         /** @hidden */
-        _activate(renderId: number): void;
+        _activate(renderId: number): boolean;
+        /** @hidden */
+        _freeze(): void;
+        /** @hidden */
+        _unFreeze(): void;
         /**
          * Gets the current world matrix
          * @returns a Matrix
@@ -29708,6 +29738,7 @@ declare module "babylonjs/Materials/effect" {
         private _engine;
         private _uniformBuffersNames;
         private _uniformsNames;
+        private _samplerList;
         private _samplers;
         private _isReady;
         private _compilationError;
@@ -66966,8 +66997,9 @@ declare module BABYLON {
          * Multiplication factor on scale x/y/z when computing the world matrix. Eg. for a 1x1x1 cube setting this to 2 will make it a 2x2x2 cube
          */
         scalingDeterminant: number;
+        private _infiniteDistance;
         /**
-         * 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
          */
         infiniteDistance: boolean;
         /**
@@ -67264,9 +67296,12 @@ declare module BABYLON {
          * @hidden
          */
         protected _getEffectiveParent(): Nullable<Node>;
-        private _activeCompositionProcess;
+        private _activeCompositionProcessor;
         private _defaultCompositionProcessor;
         private _pivotCompositionProcessor;
+        private _translationProcessor;
+        private _defaultTranslationProcessor;
+        private _infiniteDistanceTranslationProcessor;
         private _activeParentProcessor;
         private _activeBillboardPostProcessor;
         private _defaultParentProcessor;
@@ -76066,7 +76101,7 @@ declare module BABYLON {
         /** @hidden */
         _preActivate(): InstancedMesh;
         /** @hidden */
-        _activate(renderId: number): InstancedMesh;
+        _activate(renderId: number): boolean;
         /**
          * Returns the current associated LOD AbstractMesh.
          */
@@ -76677,7 +76712,8 @@ declare module BABYLON {
         private _renderOpaque;
         private _renderAlphaTest;
         private _renderTransparent;
-        private _edgesRenderers;
+        /** @hidden */
+        _edgesRenderers: SmartArray<IEdgesRenderer>;
         onBeforeTransparentRendering: () => void;
         /**
          * Set the opaque sort comparison function.
@@ -77785,6 +77821,7 @@ declare module BABYLON {
          */
         private _activeTargets;
         private _currentActiveTarget;
+        private _directTarget;
         /**
          * The target path of the runtime animation
          */
@@ -77807,6 +77844,11 @@ declare module BABYLON {
         private _previousRatio;
         private _enableBlending;
         private _correctLoopMode;
+        private _keys;
+        private _minFrame;
+        private _maxFrame;
+        private _minValue;
+        private _maxValue;
         /**
          * Gets the current frame of the runtime animation
          */
@@ -77835,6 +77877,8 @@ declare module BABYLON {
          * @param host defines the initiating Animatable
          */
         constructor(target: any, animation: Animation, scene: Scene, host: Animatable);
+        private _normalizationProcessor;
+        private _defaultNormalizationProcessor;
         private _preparePath;
         /**
          * Gets the animation from the runtime animation
@@ -77866,10 +77910,10 @@ declare module BABYLON {
         private _interpolate;
         /**
          * Apply the interpolated value to the target
-         * @param currentValue defines the value computed by the animation
-         * @param weight defines the weight to apply to this value (Defaults to 1.0)
          */
-        setValue(currentValue: any, weight?: number): void;
+        setValue: (currentValue: any, weight: number) => void;
+        private _setValueForArray;
+        private _setValueForDirect;
         private _getOriginalValues;
         private _activeBlendingProcessor;
         private _noBlendingProcessor;
@@ -79879,12 +79923,14 @@ declare module BABYLON {
      **/
     class _InstanceDataStorage {
         visibleInstances: any;
-        renderIdForInstances: number[];
         batchCache: _InstancesBatch;
         instancesBufferSize: number;
         instancesBuffer: Nullable<Buffer>;
         instancesData: Float32Array;
         overridenInstanceCount: number;
+        isFrozen: boolean;
+        _previousBatch: _InstancesBatch;
+        hardwareInstancedRendering: boolean;
     }
     /**
      * @hidden
@@ -79893,6 +79939,7 @@ declare module BABYLON {
         mustReturn: boolean;
         visibleInstances: Nullable<InstancedMesh[]>[];
         renderSelf: boolean[];
+        hardwareInstancedRendering: boolean[];
     }
     /**
      * Class used to represent renderable models
@@ -80385,6 +80432,10 @@ declare module BABYLON {
         _renderWithInstances(subMesh: SubMesh, fillMode: number, batch: _InstancesBatch, effect: Effect, engine: Engine): Mesh;
         /** @hidden */
         _processRendering(subMesh: SubMesh, effect: Effect, fillMode: number, batch: _InstancesBatch, hardwareInstancedRendering: boolean, onBeforeDraw: (isInstance: boolean, world: Matrix, effectiveMaterial?: Material) => void, effectiveMaterial?: Material): Mesh;
+        /** @hidden */
+        _freeze(): void;
+        /** @hidden */
+        _unFreeze(): void;
         /**
          * Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager
          * @param subMesh defines the subMesh to render
@@ -83396,6 +83447,10 @@ declare module BABYLON {
         /** @hidden */
         _occlusionQuery: Nullable<WebGLQuery>;
         private _visibility;
+        /** @hidden */
+        _isActive: boolean;
+        /** @hidden */
+        _renderingGroup: RenderingGroup;
         /**
          * Gets or sets mesh visibility between 0 and 1 (default is 1)
          */
@@ -83722,7 +83777,11 @@ declare module BABYLON {
         /** @hidden */
         _preActivateForIntermediateRendering(renderId: number): void;
         /** @hidden */
-        _activate(renderId: number): void;
+        _activate(renderId: number): boolean;
+        /** @hidden */
+        _freeze(): void;
+        /** @hidden */
+        _unFreeze(): void;
         /**
          * Gets the current world matrix
          * @returns a Matrix
@@ -88435,6 +88494,7 @@ declare module BABYLON {
         private _engine;
         private _uniformBuffersNames;
         private _uniformsNames;
+        private _samplerList;
         private _samplers;
         private _isReady;
         private _compilationError;

+ 0 - 336
dist/preview release/viewer/babylon.viewer.d.ts

@@ -29,7 +29,6 @@
 //   ../../../../../Tools/Gulp/babylonjs/Lights/shadowLight
 //   ../../../../../Tools/Gulp/babylonjs-loaders/glTF/2.0/glTFLoaderExtension
 //   ../../../../../Tools/Gulp/babylonjs/PostProcesses/depthOfFieldEffect
-//   ../../../../../Tools/Gulp/babylonjs/Materials/Textures/cubeTexture
 declare module BabylonViewer {
     /**
         * BabylonJS Viewer
@@ -1657,54 +1656,6 @@ declare module BabylonViewer {
 }
 declare module BabylonViewer {
     /**
-        * The ViewerLabs class will hold functions that are not (!) backwards compatible.
-        * The APIs in all labs-related classes and configuration  might change.
-        * Once stable, lab features will be moved to the publis API and configuration object.
-        */
-    export class ViewerLabs {
-            constructor(_scene: BABYLON.Scene);
-            assetsRootURL: string;
-            environment: PBREnvironment;
-            /**
-                        * Loads an environment map from a given URL
-                        * @param url URL of environment map
-                        * @param onSuccess Callback fired after environment successfully applied to the scene
-                        * @param onProgress Callback fired at progress events while loading the environment map
-                        * @param onError Callback fired when the load fails
-                        */
-            loadEnvironment(url: string, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
-            /**
-                * Loads an environment map from a given URL
-                * @param buffer ArrayBuffer containing environment map
-                * @param onSuccess Callback fired after environment successfully applied to the scene
-                * @param onProgress Callback fired at progress events while loading the environment map
-                * @param onError Callback fired when the load fails
-                */
-            loadEnvironment(buffer: ArrayBuffer, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
-            /**
-                * Sets the environment to an already loaded environment
-                * @param env PBREnvironment instance
-                * @param onSuccess Callback fired after environment successfully applied to the scene
-                * @param onProgress Callback fired at progress events while loading the environment map
-                * @param onError Callback fired when the load fails
-                */
-            loadEnvironment(env: PBREnvironment, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
-            /**
-                * Applies an `EnvironmentMapConfiguration` to the scene
-                * @param environmentMapConfiguration Environment map configuration to apply
-                */
-            applyEnvironmentMapConfiguration(rotationY?: number): void;
-            /**
-                * Get an environment asset url by using the configuration if the path is not absolute.
-                * @param url Asset url
-                * @returns The Asset url using the `environmentAssetsRootURL` if the url is not an absolute path.
-                */
-            getAssetUrl(url: string): string;
-            rotateShadowLight(shadowLight: BABYLON.ShadowLight, amount: number, point?: BABYLON.Vector3, axis?: BABYLON.Vector3, target?: BABYLON.Vector3): void;
-    }
-}
-declare module BabylonViewer {
-    /**
         * Defines an animation to be applied to a model (translation, scale or rotation).
         */
     export interface IModelAnimationConfiguration {
@@ -2224,291 +2175,4 @@ declare module BabylonViewer {
             z: number;
         };
     }
-}
-declare module BabylonViewer {
-    /**
-        * Spherical polynomial coefficients (counter part to spherical harmonic coefficients used in shader irradiance calculation)
-        * @ignoreChildren
-        */
-    export interface SphericalPolynomalCoefficients {
-            x: BABYLON.Vector3;
-            y: BABYLON.Vector3;
-            z: BABYLON.Vector3;
-            xx: BABYLON.Vector3;
-            yy: BABYLON.Vector3;
-            zz: BABYLON.Vector3;
-            yz: BABYLON.Vector3;
-            zx: BABYLON.Vector3;
-            xy: BABYLON.Vector3;
-    }
-    /**
-        * Wraps data and maps required for environments with physically based rendering
-        */
-    export interface PBREnvironment {
-            /**
-                * Spherical Polynomial Coefficients representing an irradiance map
-                */
-            irradiancePolynomialCoefficients: SphericalPolynomalCoefficients;
-            /**
-                * Specular cubemap
-                */
-            specularTexture?: TextureCube;
-            /**
-                * A scale factor applied to RGB values after reading from environment maps
-                */
-            textureIntensityScale: number;
-    }
-    /**
-                        * Environment map representations: layouts, projections and approximations
-                        */
-    export type MapType = 'irradiance_sh_coefficients_9' | 'cubemap_faces';
-    /**
-        * Image type used for environment map
-        */
-    export type ImageType = 'png';
-    /**
-        * A generic field in JSON that report's its type
-        */
-    export interface TypedObject<T> {
-            type: T;
-    }
-    /**
-        * Describes a range of bytes starting at byte pos (inclusive) and finishing at byte pos + length - 1
-        */
-    export interface ByteRange {
-            pos: number;
-            length: number;
-    }
-    /**
-        * Complete Spectre Environment JSON Descriptor
-        */
-    export interface EnvJsonDescriptor {
-            radiance: TypedObject<MapType>;
-            irradiance: TypedObject<MapType>;
-            specular: TypedObject<MapType>;
-    }
-    /**
-        * Spherical harmonic coefficients to provide an irradiance map
-        */
-    export interface IrradianceSHCoefficients9 extends TypedObject<MapType> {
-            l00: Array<number>;
-            l1_1: Array<number>;
-            l10: Array<number>;
-            l11: Array<number>;
-            l2_2: Array<number>;
-            l2_1: Array<number>;
-            l20: Array<number>;
-            l21: Array<number>;
-            l22: Array<number>;
-    }
-    /**
-        * A generic set of images, where the image content is specified by byte ranges in the mipmaps field
-        */
-    export interface ImageSet<T> extends TypedObject<MapType> {
-            imageType: ImageType;
-            width: number;
-            height: number;
-            mipmaps: Array<T>;
-            multiplier: number;
-    }
-    /**
-        * A set of cubemap faces
-        */
-    export type CubemapFaces = ImageSet<Array<ByteRange>>;
-    /**
-        * A single image containing an atlas of equirectangular-projection maps across all mip levels
-        */
-    export type EquirectangularMipmapAtlas = ImageSet<ByteRange>;
-    /**
-        * A static class proving methods to aid parsing Spectre environment files
-        */
-    export class EnvironmentDeserializer {
-            /**
-                * Parses an arraybuffer into a new PBREnvironment object
-                * @param arrayBuffer The arraybuffer of the Spectre environment file
-                * @return a PBREnvironment object
-                */
-            static Parse(arrayBuffer: ArrayBuffer): PBREnvironment;
-    }
-}
-declare module BabylonViewer {
-    /**
-        * WebGL Pixel Formats
-        */
-    export const enum PixelFormat {
-            DEPTH_COMPONENT = 6402,
-            ALPHA = 6406,
-            RGB = 6407,
-            RGBA = 6408,
-            LUMINANCE = 6409,
-            LUMINANCE_ALPHA = 6410
-    }
-    /**
-        * WebGL Pixel Types
-        */
-    export const enum PixelType {
-            UNSIGNED_BYTE = 5121,
-            UNSIGNED_SHORT_4_4_4_4 = 32819,
-            UNSIGNED_SHORT_5_5_5_1 = 32820,
-            UNSIGNED_SHORT_5_6_5 = 33635
-    }
-    /**
-        * WebGL Texture Magnification Filter
-        */
-    export const enum TextureMagFilter {
-            NEAREST = 9728,
-            LINEAR = 9729
-    }
-    /**
-        * WebGL Texture Minification Filter
-        */
-    export const enum TextureMinFilter {
-            NEAREST = 9728,
-            LINEAR = 9729,
-            NEAREST_MIPMAP_NEAREST = 9984,
-            LINEAR_MIPMAP_NEAREST = 9985,
-            NEAREST_MIPMAP_LINEAR = 9986,
-            LINEAR_MIPMAP_LINEAR = 9987
-    }
-    /**
-        * WebGL Texture Wrap Modes
-        */
-    export const enum TextureWrapMode {
-            REPEAT = 10497,
-            CLAMP_TO_EDGE = 33071,
-            MIRRORED_REPEAT = 33648
-    }
-    /**
-        * Raw texture data and descriptor sufficient for WebGL texture upload
-        */
-    export interface TextureData {
-            /**
-                * Width of image
-                */
-            width: number;
-            /**
-                * Height of image
-                */
-            height: number;
-            /**
-                * Format of pixels in data
-                */
-            format: PixelFormat;
-            /**
-                * Row byte alignment of pixels in data
-                */
-            alignment: number;
-            /**
-                * Pixel data
-                */
-            data: ArrayBufferView;
-    }
-    /**
-        * Wraps sampling parameters for a WebGL texture
-        */
-    export interface SamplingParameters {
-            /**
-                * Magnification mode when upsampling from a WebGL texture
-                */
-            magFilter?: TextureMagFilter;
-            /**
-                * Minification mode when upsampling from a WebGL texture
-                */
-            minFilter?: TextureMinFilter;
-            /**
-                * X axis wrapping mode when sampling out of a WebGL texture bounds
-                */
-            wrapS?: TextureWrapMode;
-            /**
-                * Y axis wrapping mode when sampling out of a WebGL texture bounds
-                */
-            wrapT?: TextureWrapMode;
-            /**
-             * Anisotropic filtering samples
-             */
-            maxAnisotropy?: number;
-    }
-    /**
-        * Represents a valid WebGL texture source for use in texImage2D
-        */
-    export type TextureSource = TextureData | ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement;
-    /**
-        * A generic set of texture mipmaps (where index 0 has the largest dimension)
-        */
-    export type Mipmaps<T> = Array<T>;
-    /**
-        * A set of 6 cubemap arranged in the order [+x, -x, +y, -y, +z, -z]
-        */
-    export type Faces<T> = Array<T>;
-    /**
-        * A set of texture mipmaps specifically for 2D textures in WebGL (where index 0 has the largest dimension)
-        */
-    export type Mipmaps2D = Mipmaps<TextureSource>;
-    /**
-        * A set of texture mipmaps specifically for cubemap textures in WebGL (where index 0 has the largest dimension)
-        */
-    export type MipmapsCube = Mipmaps<Faces<TextureSource>>;
-    /**
-        * A minimal WebGL cubemap descriptor
-        */
-    export class TextureCube {
-            internalFormat: PixelFormat;
-            type: PixelType;
-            source: MipmapsCube;
-            /**
-                * Returns the width of a face of the texture or 0 if not available
-                */
-            readonly Width: number;
-            /**
-                * Returns the height of a face of the texture or 0 if not available
-                */
-            readonly Height: number;
-            /**
-                * constructor
-                * @param internalFormat WebGL pixel format for the texture on the GPU
-                * @param type WebGL pixel type of the supplied data and texture on the GPU
-                * @param source An array containing mipmap levels of faces, where each mipmap level is an array of faces and each face is a TextureSource object
-                */
-            constructor(internalFormat: PixelFormat, type: PixelType, source?: MipmapsCube);
-    }
-    /**
-                * A static class providing methods to aid working with Bablyon textures.
-                */
-    export class TextureUtils {
-            /**
-                * A prefix used when storing a babylon texture object reference on a Spectre texture object
-                */
-            static BabylonTextureKeyPrefix: string;
-            /**
-                * Controls anisotropic filtering for deserialized textures.
-                */
-            static MaxAnisotropy: number;
-            /**
-                * Returns a BabylonCubeTexture instance from a Spectre texture cube, subject to sampling parameters.
-                * If such a texture has already been requested in the past, this texture will be returned, otherwise a new one will be created.
-                * The advantage of this is to enable working with texture objects without the need to initialize on the GPU until desired.
-                * @param scene A Babylon BABYLON.Scene instance
-                * @param textureCube A Spectre TextureCube object
-                * @param parameters WebGL texture sampling parameters
-                * @param automaticMipmaps Pass true to enable automatic mipmap generation where possible (requires power of images)
-                * @param environment Specifies that the texture will be used as an environment
-                * @param singleLod Specifies that the texture will be a singleLod (for environment)
-                * @return Babylon cube texture
-                */
-            static GetBabylonCubeTexture(scene: BABYLON.Scene, textureCube: TextureCube, automaticMipmaps: boolean, environment?: boolean, singleLod?: boolean): BABYLON.CubeTexture;
-            /**
-                * Applies Spectre SamplingParameters to a Babylon texture by directly setting texture parameters on the internal WebGLTexture as well as setting Babylon fields
-                * @param babylonTexture Babylon texture to apply texture to (requires the Babylon texture has an initialize _texture field)
-                * @param parameters Spectre SamplingParameters to apply
-                */
-            static ApplySamplingParameters(babylonTexture: BABYLON.BaseTexture, parameters: SamplingParameters): void;
-            /**
-                * Environment preprocessing dedicated value (Internal Use or Advanced only).
-                */
-            static EnvironmentLODScale: number;
-            /**
-                * Environment preprocessing dedicated value (Internal Use or Advanced only)..
-                */
-            static EnvironmentLODOffset: number;
-    }
 }

Plik diff jest za duży
+ 126 - 126
dist/preview release/viewer/babylon.viewer.js


Plik diff jest za duży
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 1 - 345
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -30,7 +30,6 @@
 //   ../../../../../Tools/Gulp/babylonjs/Lights/shadowLight
 //   ../../../../../Tools/Gulp/babylonjs-loaders/glTF/2.0/glTFLoaderExtension
 //   ../../../../../Tools/Gulp/babylonjs/PostProcesses/depthOfFieldEffect
-//   ../../../../../Tools/Gulp/babylonjs/Materials/Textures/cubeTexture
 
 declare module 'babylonjs-viewer' {
     import { mapperManager } from 'babylonjs-viewer/configuration/mappers';
@@ -1823,56 +1822,7 @@ declare module 'babylonjs-viewer/configuration/loader' {
 }
 
 declare module 'babylonjs-viewer/labs/viewerLabs' {
-    import { PBREnvironment } from "babylonjs-viewer/labs/environmentSerializer";
-    import { Scene } from "babylonjs/scene";
-    import { Vector3 } from "babylonjs/Maths/math";
-    import { ShadowLight } from "babylonjs/Lights/shadowLight";
-    /**
-        * The ViewerLabs class will hold functions that are not (!) backwards compatible.
-        * The APIs in all labs-related classes and configuration  might change.
-        * Once stable, lab features will be moved to the publis API and configuration object.
-        */
-    export class ViewerLabs {
-            constructor(_scene: Scene);
-            assetsRootURL: string;
-            environment: PBREnvironment;
-            /**
-                        * Loads an environment map from a given URL
-                        * @param url URL of environment map
-                        * @param onSuccess Callback fired after environment successfully applied to the scene
-                        * @param onProgress Callback fired at progress events while loading the environment map
-                        * @param onError Callback fired when the load fails
-                        */
-            loadEnvironment(url: string, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
-            /**
-                * Loads an environment map from a given URL
-                * @param buffer ArrayBuffer containing environment map
-                * @param onSuccess Callback fired after environment successfully applied to the scene
-                * @param onProgress Callback fired at progress events while loading the environment map
-                * @param onError Callback fired when the load fails
-                */
-            loadEnvironment(buffer: ArrayBuffer, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
-            /**
-                * Sets the environment to an already loaded environment
-                * @param env PBREnvironment instance
-                * @param onSuccess Callback fired after environment successfully applied to the scene
-                * @param onProgress Callback fired at progress events while loading the environment map
-                * @param onError Callback fired when the load fails
-                */
-            loadEnvironment(env: PBREnvironment, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
-            /**
-                * Applies an `EnvironmentMapConfiguration` to the scene
-                * @param environmentMapConfiguration Environment map configuration to apply
-                */
-            applyEnvironmentMapConfiguration(rotationY?: number): void;
-            /**
-                * Get an environment asset url by using the configuration if the path is not absolute.
-                * @param url Asset url
-                * @returns The Asset url using the `environmentAssetsRootURL` if the url is not an absolute path.
-                */
-            getAssetUrl(url: string): string;
-            rotateShadowLight(shadowLight: ShadowLight, amount: number, point?: Vector3, axis?: Vector3, target?: Vector3): void;
-    }
+    
 }
 
 declare module 'babylonjs-viewer/configuration/interfaces/modelAnimationConfiguration' {
@@ -2433,297 +2383,3 @@ declare module 'babylonjs-viewer/configuration/interfaces/vrConfiguration' {
     }
 }
 
-declare module 'babylonjs-viewer/labs/environmentSerializer' {
-    import { Vector3 } from 'babylonjs/Maths/math';
-    import { TextureCube } from 'babylonjs-viewer/labs/texture';
-    /**
-        * Spherical polynomial coefficients (counter part to spherical harmonic coefficients used in shader irradiance calculation)
-        * @ignoreChildren
-        */
-    export interface SphericalPolynomalCoefficients {
-            x: Vector3;
-            y: Vector3;
-            z: Vector3;
-            xx: Vector3;
-            yy: Vector3;
-            zz: Vector3;
-            yz: Vector3;
-            zx: Vector3;
-            xy: Vector3;
-    }
-    /**
-        * Wraps data and maps required for environments with physically based rendering
-        */
-    export interface PBREnvironment {
-            /**
-                * Spherical Polynomial Coefficients representing an irradiance map
-                */
-            irradiancePolynomialCoefficients: SphericalPolynomalCoefficients;
-            /**
-                * Specular cubemap
-                */
-            specularTexture?: TextureCube;
-            /**
-                * A scale factor applied to RGB values after reading from environment maps
-                */
-            textureIntensityScale: number;
-    }
-    /**
-                        * Environment map representations: layouts, projections and approximations
-                        */
-    export type MapType = 'irradiance_sh_coefficients_9' | 'cubemap_faces';
-    /**
-        * Image type used for environment map
-        */
-    export type ImageType = 'png';
-    /**
-        * A generic field in JSON that report's its type
-        */
-    export interface TypedObject<T> {
-            type: T;
-    }
-    /**
-        * Describes a range of bytes starting at byte pos (inclusive) and finishing at byte pos + length - 1
-        */
-    export interface ByteRange {
-            pos: number;
-            length: number;
-    }
-    /**
-        * Complete Spectre Environment JSON Descriptor
-        */
-    export interface EnvJsonDescriptor {
-            radiance: TypedObject<MapType>;
-            irradiance: TypedObject<MapType>;
-            specular: TypedObject<MapType>;
-    }
-    /**
-        * Spherical harmonic coefficients to provide an irradiance map
-        */
-    export interface IrradianceSHCoefficients9 extends TypedObject<MapType> {
-            l00: Array<number>;
-            l1_1: Array<number>;
-            l10: Array<number>;
-            l11: Array<number>;
-            l2_2: Array<number>;
-            l2_1: Array<number>;
-            l20: Array<number>;
-            l21: Array<number>;
-            l22: Array<number>;
-    }
-    /**
-        * A generic set of images, where the image content is specified by byte ranges in the mipmaps field
-        */
-    export interface ImageSet<T> extends TypedObject<MapType> {
-            imageType: ImageType;
-            width: number;
-            height: number;
-            mipmaps: Array<T>;
-            multiplier: number;
-    }
-    /**
-        * A set of cubemap faces
-        */
-    export type CubemapFaces = ImageSet<Array<ByteRange>>;
-    /**
-        * A single image containing an atlas of equirectangular-projection maps across all mip levels
-        */
-    export type EquirectangularMipmapAtlas = ImageSet<ByteRange>;
-    /**
-        * A static class proving methods to aid parsing Spectre environment files
-        */
-    export class EnvironmentDeserializer {
-            /**
-                * Parses an arraybuffer into a new PBREnvironment object
-                * @param arrayBuffer The arraybuffer of the Spectre environment file
-                * @return a PBREnvironment object
-                */
-            static Parse(arrayBuffer: ArrayBuffer): PBREnvironment;
-    }
-}
-
-declare module 'babylonjs-viewer/labs/texture' {
-    import { Scene } from "babylonjs/scene";
-    import { CubeTexture } from "babylonjs/Materials/Textures/cubeTexture";
-    import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
-    /**
-        * WebGL Pixel Formats
-        */
-    export const enum PixelFormat {
-            DEPTH_COMPONENT = 6402,
-            ALPHA = 6406,
-            RGB = 6407,
-            RGBA = 6408,
-            LUMINANCE = 6409,
-            LUMINANCE_ALPHA = 6410
-    }
-    /**
-        * WebGL Pixel Types
-        */
-    export const enum PixelType {
-            UNSIGNED_BYTE = 5121,
-            UNSIGNED_SHORT_4_4_4_4 = 32819,
-            UNSIGNED_SHORT_5_5_5_1 = 32820,
-            UNSIGNED_SHORT_5_6_5 = 33635
-    }
-    /**
-        * WebGL Texture Magnification Filter
-        */
-    export const enum TextureMagFilter {
-            NEAREST = 9728,
-            LINEAR = 9729
-    }
-    /**
-        * WebGL Texture Minification Filter
-        */
-    export const enum TextureMinFilter {
-            NEAREST = 9728,
-            LINEAR = 9729,
-            NEAREST_MIPMAP_NEAREST = 9984,
-            LINEAR_MIPMAP_NEAREST = 9985,
-            NEAREST_MIPMAP_LINEAR = 9986,
-            LINEAR_MIPMAP_LINEAR = 9987
-    }
-    /**
-        * WebGL Texture Wrap Modes
-        */
-    export const enum TextureWrapMode {
-            REPEAT = 10497,
-            CLAMP_TO_EDGE = 33071,
-            MIRRORED_REPEAT = 33648
-    }
-    /**
-        * Raw texture data and descriptor sufficient for WebGL texture upload
-        */
-    export interface TextureData {
-            /**
-                * Width of image
-                */
-            width: number;
-            /**
-                * Height of image
-                */
-            height: number;
-            /**
-                * Format of pixels in data
-                */
-            format: PixelFormat;
-            /**
-                * Row byte alignment of pixels in data
-                */
-            alignment: number;
-            /**
-                * Pixel data
-                */
-            data: ArrayBufferView;
-    }
-    /**
-        * Wraps sampling parameters for a WebGL texture
-        */
-    export interface SamplingParameters {
-            /**
-                * Magnification mode when upsampling from a WebGL texture
-                */
-            magFilter?: TextureMagFilter;
-            /**
-                * Minification mode when upsampling from a WebGL texture
-                */
-            minFilter?: TextureMinFilter;
-            /**
-                * X axis wrapping mode when sampling out of a WebGL texture bounds
-                */
-            wrapS?: TextureWrapMode;
-            /**
-                * Y axis wrapping mode when sampling out of a WebGL texture bounds
-                */
-            wrapT?: TextureWrapMode;
-            /**
-             * Anisotropic filtering samples
-             */
-            maxAnisotropy?: number;
-    }
-    /**
-        * Represents a valid WebGL texture source for use in texImage2D
-        */
-    export type TextureSource = TextureData | ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement;
-    /**
-        * A generic set of texture mipmaps (where index 0 has the largest dimension)
-        */
-    export type Mipmaps<T> = Array<T>;
-    /**
-        * A set of 6 cubemap arranged in the order [+x, -x, +y, -y, +z, -z]
-        */
-    export type Faces<T> = Array<T>;
-    /**
-        * A set of texture mipmaps specifically for 2D textures in WebGL (where index 0 has the largest dimension)
-        */
-    export type Mipmaps2D = Mipmaps<TextureSource>;
-    /**
-        * A set of texture mipmaps specifically for cubemap textures in WebGL (where index 0 has the largest dimension)
-        */
-    export type MipmapsCube = Mipmaps<Faces<TextureSource>>;
-    /**
-        * A minimal WebGL cubemap descriptor
-        */
-    export class TextureCube {
-            internalFormat: PixelFormat;
-            type: PixelType;
-            source: MipmapsCube;
-            /**
-                * Returns the width of a face of the texture or 0 if not available
-                */
-            readonly Width: number;
-            /**
-                * Returns the height of a face of the texture or 0 if not available
-                */
-            readonly Height: number;
-            /**
-                * constructor
-                * @param internalFormat WebGL pixel format for the texture on the GPU
-                * @param type WebGL pixel type of the supplied data and texture on the GPU
-                * @param source An array containing mipmap levels of faces, where each mipmap level is an array of faces and each face is a TextureSource object
-                */
-            constructor(internalFormat: PixelFormat, type: PixelType, source?: MipmapsCube);
-    }
-    /**
-                * A static class providing methods to aid working with Bablyon textures.
-                */
-    export class TextureUtils {
-            /**
-                * A prefix used when storing a babylon texture object reference on a Spectre texture object
-                */
-            static BabylonTextureKeyPrefix: string;
-            /**
-                * Controls anisotropic filtering for deserialized textures.
-                */
-            static MaxAnisotropy: number;
-            /**
-                * Returns a BabylonCubeTexture instance from a Spectre texture cube, subject to sampling parameters.
-                * If such a texture has already been requested in the past, this texture will be returned, otherwise a new one will be created.
-                * The advantage of this is to enable working with texture objects without the need to initialize on the GPU until desired.
-                * @param scene A Babylon Scene instance
-                * @param textureCube A Spectre TextureCube object
-                * @param parameters WebGL texture sampling parameters
-                * @param automaticMipmaps Pass true to enable automatic mipmap generation where possible (requires power of images)
-                * @param environment Specifies that the texture will be used as an environment
-                * @param singleLod Specifies that the texture will be a singleLod (for environment)
-                * @return Babylon cube texture
-                */
-            static GetBabylonCubeTexture(scene: Scene, textureCube: TextureCube, automaticMipmaps: boolean, environment?: boolean, singleLod?: boolean): CubeTexture;
-            /**
-                * Applies Spectre SamplingParameters to a Babylon texture by directly setting texture parameters on the internal WebGLTexture as well as setting Babylon fields
-                * @param babylonTexture Babylon texture to apply texture to (requires the Babylon texture has an initialize _texture field)
-                * @param parameters Spectre SamplingParameters to apply
-                */
-            static ApplySamplingParameters(babylonTexture: BaseTexture, parameters: SamplingParameters): void;
-            /**
-                * Environment preprocessing dedicated value (Internal Use or Advanced only).
-                */
-            static EnvironmentLODScale: number;
-            /**
-                * Environment preprocessing dedicated value (Internal Use or Advanced only)..
-                */
-            static EnvironmentLODOffset: number;
-    }
-}
-

+ 0 - 9
sandbox/index.js

@@ -213,15 +213,6 @@ if (BABYLON.Engine.isSupported()) {
         if (debugLayerEnabled) {
             currentScene.debugLayer.show();
         }
-
-        currentScene.dispatchAllSubMeshesOfActiveMeshes = true;
-        currentScene.meshes.forEach((mesh) => mesh.alwaysSelectAsActiveMesh = true);
-        currentScene.getEngine().disableTextureBindingOptimization = true;
-        currentScene.meshes.forEach((mesh) => mesh.doNotSyncBoundingInfo = true);
-        currentScene.materials.forEach((mat) => mat.freeze());
-
-        currentScene.meshes.forEach((mesh) => mesh.ignoreNonUniformScaling = true);
-        currentScene.transformNodes.forEach((node) => node.ignoreNonUniformScaling = true);
     };
 
     var sceneError = function(sceneFile, babylonScene, message) {

+ 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);
         }

+ 119 - 103
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++) {
@@ -309,22 +346,20 @@ export class RuntimeAnimation {
 
     /**
      * Apply the interpolated value to the target
-     * @param currentValue defines the value computed by the animation
-     * @param weight defines the weight to apply to this value (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 +420,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,7 +431,7 @@ 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) {
@@ -465,22 +498,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 +516,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 +588,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;
@@ -588,10 +599,12 @@ export class RuntimeAnimation {
             }
 
             // Need to reset animation events
-            for (var index = 0; index < events.length; index++) {
-                if (!events[index].onlyOnce) {
-                    // reset event, the animation is looping
-                    events[index].isDone = false;
+            if (events.length) {
+                for (var index = 0; index < events.length; index++) {
+                    if (!events[index].onlyOnce) {
+                        // reset event, the animation is looping
+                        events[index].isDone = false;
+                    }
                 }
             }
         }
@@ -603,25 +616,28 @@ export class RuntimeAnimation {
         this.setValue(currentValue, weight);
 
         // Check events
-        for (var index = 0; index < events.length; index++) {
-            // Make sure current frame has passed event frame and that event frame is within the current range
-            // Also, handle both forward and reverse animations
-            if (
-                (range > 0 && currentFrame >= events[index].frame && events[index].frame >= from) ||
-                (range < 0 && currentFrame <= events[index].frame && events[index].frame <= from)
-            ) {
-                var event = events[index];
-                if (!event.isDone) {
-                    // If event should be done only once, remove it.
-                    if (event.onlyOnce) {
-                        events.splice(index, 1);
-                        index--;
-                    }
-                    event.isDone = true;
-                    event.action(currentFrame);
-                } // Don't do anything if the event has already be done.
+        if (events.length) {
+            for (var index = 0; index < events.length; index++) {
+                // Make sure current frame has passed event frame and that event frame is within the current range
+                // Also, handle both forward and reverse animations
+                if (
+                    (range > 0 && currentFrame >= events[index].frame && events[index].frame >= from) ||
+                    (range < 0 && currentFrame <= events[index].frame && events[index].frame <= from)
+                ) {
+                    var event = events[index];
+                    if (!event.isDone) {
+                        // If event should be done only once, remove it.
+                        if (event.onlyOnce) {
+                            events.splice(index, 1);
+                            index--;
+                        }
+                        event.isDone = true;
+                        event.action(currentFrame);
+                    } // Don't do anything if the event has already be done.
+                }
             }
         }
+
         if (!returnValue) {
             this._stopped = true;
         }

+ 4 - 5
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]);
@@ -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;
         }
 

+ 59 - 48
src/Materials/effect.ts

@@ -241,12 +241,13 @@ export class Effect {
     private _engine: Engine;
     private _uniformBuffersNames: { [key: string]: number } = {};
     private _uniformsNames: string[];
-    private _samplers: string[];
+    private _samplerList: string[];
+    private _samplers: {[key: string]: number} = {};
     private _isReady = false;
     private _compilationError = "";
     private _attributesNames: string[];
     private _attributes: number[];
-    private _uniforms: Nullable<WebGLUniformLocation>[];
+    private _uniforms: {[key: string] : Nullable<WebGLUniformLocation>} = {};
     /**
      * Key for the effect.
      * @hidden
@@ -291,7 +292,7 @@ export class Effect {
 
             this._attributesNames = options.attributes;
             this._uniformsNames = options.uniformsNames.concat(options.samplers);
-            this._samplers = options.samplers.slice();
+            this._samplerList = options.samplers.slice();
             this.defines = options.defines;
             this.onError = options.onError;
             this.onCompiled = options.onCompiled;
@@ -308,7 +309,7 @@ export class Effect {
             this._engine = <Engine>engine;
             this.defines = (defines == null ? "" : defines);
             this._uniformsNames = (<string[]>uniformsNamesOrEngine).concat(<string[]>samplers);
-            this._samplers = samplers ? <string[]>samplers.slice() : [];
+            this._samplerList = samplers ? <string[]>samplers.slice() : [];
             this._attributesNames = (<string[]>attributesNamesOrOptions);
 
             this.onError = onError;
@@ -453,7 +454,7 @@ export class Effect {
      * @returns the location of the uniform.
      */
     public getUniform(uniformName: string): Nullable<WebGLUniformLocation> {
-        return this._uniforms[this._uniformsNames.indexOf(uniformName)];
+        return this._uniforms[uniformName];
     }
 
     /**
@@ -461,7 +462,7 @@ export class Effect {
      * @returns The array of sampler variable neames.
      */
     public getSamplers(): string[] {
-        return this._samplers;
+        return this._samplerList;
     }
 
     /**
@@ -834,19 +835,27 @@ export class Effect {
                     }
                 }
 
-                this._uniforms = engine.getUniforms(this._program, this._uniformsNames);
+                let uniforms = engine.getUniforms(this._program, this._uniformsNames);
+                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++) {
-                    var sampler = this.getUniform(this._samplers[index]);
+                for (index = 0; index < this._samplerList.length; index++) {
+                    var sampler = this.getUniform(this._samplerList[index]);
 
                     if (sampler == null) {
-                        this._samplers.splice(index, 1);
+                        this._samplerList.splice(index, 1);
                         index--;
                     }
                 }
 
+                this._samplerList.forEach((name, index) => {
+                    this._samplers[name] = index;
+                });
+
                 engine.bindSamplers(this);
 
                 this._compilationError = "";
@@ -926,7 +935,7 @@ export class Effect {
      * @hidden
      */
     public _bindTexture(channel: string, texture: InternalTexture): void {
-        this._engine._bindTexture(this._samplers.indexOf(channel), texture);
+        this._engine._bindTexture(this._samplers[channel], texture);
     }
 
     /**
@@ -935,7 +944,7 @@ export class Effect {
      * @param texture Texture to set.
      */
     public setTexture(channel: string, texture: Nullable<BaseTexture>): void {
-        this._engine.setTexture(this._samplers.indexOf(channel), this.getUniform(channel), texture);
+        this._engine.setTexture(this._samplers[channel], this._uniforms[channel], texture);
     }
 
     /**
@@ -944,7 +953,7 @@ export class Effect {
      * @param texture Texture to set.
      */
     public setDepthStencilTexture(channel: string, texture: Nullable<RenderTargetTexture>): void {
-        this._engine.setDepthStencilTexture(this._samplers.indexOf(channel), this.getUniform(channel), texture);
+        this._engine.setDepthStencilTexture(this._samplers[channel], this._uniforms[channel], texture);
     }
 
     /**
@@ -953,14 +962,16 @@ 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;
             }
         }
 
-        this._engine.setTextureArray(this._samplers.indexOf(channel), this.getUniform(channel), textures);
+        this._engine.setTextureArray(this._samplers[channel], this._uniforms[channel], textures);
     }
 
     /**
@@ -969,7 +980,7 @@ export class Effect {
      * @param postProcess Post process to get the input texture from.
      */
     public setTextureFromPostProcess(channel: string, postProcess: Nullable<PostProcess>): void {
-        this._engine.setTextureFromPostProcess(this._samplers.indexOf(channel), postProcess);
+        this._engine.setTextureFromPostProcess(this._samplers[channel], postProcess);
     }
 
     /**
@@ -979,7 +990,7 @@ export class Effect {
      * @param postProcess Post process to get the output texture from.
      */
     public setTextureFromPostProcessOutput(channel: string, postProcess: Nullable<PostProcess>): void {
-        this._engine.setTextureFromPostProcessOutput(this._samplers.indexOf(channel), postProcess);
+        this._engine.setTextureFromPostProcessOutput(this._samplers[channel], postProcess);
     }
 
     /** @hidden */
@@ -1110,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;
     }
@@ -1123,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;
     }
@@ -1136,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;
     }
@@ -1149,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;
     }
@@ -1162,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;
     }
@@ -1175,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;
     }
@@ -1188,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;
     }
@@ -1201,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;
     }
@@ -1214,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;
     }
@@ -1227,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;
     }
@@ -1240,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;
     }
@@ -1253,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;
     }
@@ -1266,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;
     }
@@ -1283,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;
     }
@@ -1296,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;
     }
@@ -1309,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;
     }
@@ -1322,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;
     }
@@ -1341,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;
     }
@@ -1360,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;
     }
@@ -1373,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;
     }
@@ -1387,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;
     }
@@ -1400,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;
     }
@@ -1415,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;
     }
@@ -1428,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;
     }
@@ -1444,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;
     }
@@ -1458,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;
     }
@@ -1472,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;
     }
@@ -1485,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;
     }
@@ -1521,4 +1532,4 @@ export class Effect {
     public static ResetCache() {
         Effect._baseCache = {};
     }
-}
+}

+ 18 - 1
src/Meshes/abstractMesh.ts

@@ -25,6 +25,7 @@ import { AbstractActionManager } from '../Actions/abstractActionManager';
 declare type Ray = import("../Culling/ray").Ray;
 declare type Collider = import("../Collisions/collider").Collider;
 declare type TrianglePickingPredicate = import("../Culling/ray").TrianglePickingPredicate;
+declare type RenderingGroup = import("../Rendering/renderingGroup").RenderingGroup;
 
 /** @hidden */
 class _FacetDataStorage {
@@ -267,6 +268,11 @@ export class AbstractMesh extends TransformNode implements IDisposable, ICullabl
 
     private _visibility = 1.0;
 
+    /** @hidden */
+    public _isActive = false;
+    /** @hidden */
+    public _renderingGroup: RenderingGroup;
+
     /**
      * Gets or sets mesh visibility between 0 and 1 (default is 1)
      */
@@ -1025,8 +1031,19 @@ export class AbstractMesh extends TransformNode implements IDisposable, ICullabl
     }
 
     /** @hidden */
-    public _activate(renderId: number): void {
+    public _activate(renderId: number): boolean {
         this._renderId = renderId;
+        return true;
+    }
+
+    /** @hidden */
+    public _freeze() {
+        // Do nothing
+    }
+
+    /** @hidden */
+    public _unFreeze() {
+        // Do nothing
     }
 
     /**

+ 7 - 2
src/Meshes/instancedMesh.ts

@@ -259,11 +259,16 @@ export class InstancedMesh extends AbstractMesh {
     }
 
     /** @hidden */
-    public _activate(renderId: number): InstancedMesh {
+    public _activate(renderId: number): boolean {
         if (this._currentLOD) {
             this._currentLOD._registerInstanceForRenderId(this, renderId);
         }
-        return this;
+
+        if (this._edgesRenderer && this._edgesRenderer.isEnabled && this._sourceMesh._renderingGroup) {
+            this._sourceMesh._renderingGroup._edgesRenderers.push(this._edgesRenderer);
+        }
+
+        return !this._sourceMesh._isActive;
     }
 
     /**

+ 32 - 22
src/Meshes/mesh.ts

@@ -76,12 +76,14 @@ export class _CreationDataStorage {
  **/
 class _InstanceDataStorage {
     public visibleInstances: any = {};
-    public renderIdForInstances = new Array<number>();
     public batchCache = new _InstancesBatch();
     public instancesBufferSize = 32 * 16 * 4; // let's start with a maximum of 32 instances
     public instancesBuffer: Nullable<Buffer>;
     public instancesData: Float32Array;
     public overridenInstanceCount: number;
+    public isFrozen: boolean;
+    public _previousBatch: _InstancesBatch;
+    public hardwareInstancedRendering: boolean;
 }
 
 /**
@@ -91,6 +93,7 @@ export class _InstancesBatch {
     public mustReturn = false;
     public visibleInstances = new Array<Nullable<Array<InstancedMesh>>>();
     public renderSelf = new Array<boolean>();
+    public hardwareInstancedRendering = new Array<boolean>();
 }
 
 /**
@@ -437,6 +440,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
             this.parent = parent;
         }
 
+        this._instanceDataStorage.hardwareInstancedRendering = this.getEngine().getCaps().instancedArrays;
     }
 
     // Methods
@@ -1363,6 +1367,9 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
 
     /** @hidden */
     public _getInstancesRenderList(subMeshId: number): _InstancesBatch {
+        if (this._instanceDataStorage.isFrozen && this._instanceDataStorage._previousBatch) {
+            return this._instanceDataStorage._previousBatch;
+        }
         var scene = this.getScene();
         let batchCache = this._instanceDataStorage.batchCache;
         batchCache.mustReturn = false;
@@ -1374,29 +1381,13 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
             var currentRenderId = scene.getRenderId();
             var defaultRenderId = (scene._isInIntermediateRendering() ? visibleInstances.intermediateDefaultRenderId : visibleInstances.defaultRenderId);
             batchCache.visibleInstances[subMeshId] = visibleInstances[currentRenderId];
-            var selfRenderId = this._renderId;
 
             if (!batchCache.visibleInstances[subMeshId] && defaultRenderId) {
                 batchCache.visibleInstances[subMeshId] = visibleInstances[defaultRenderId];
-                currentRenderId = Math.max(defaultRenderId, currentRenderId);
-                selfRenderId = Math.max(visibleInstances.selfDefaultRenderId, currentRenderId);
-            }
-
-            let visibleInstancesForSubMesh = batchCache.visibleInstances[subMeshId];
-            if (visibleInstancesForSubMesh && visibleInstancesForSubMesh.length) {
-                if (this._instanceDataStorage.renderIdForInstances[subMeshId] === currentRenderId) {
-                    batchCache.mustReturn = true;
-                    return batchCache;
-                }
-
-                if (currentRenderId !== selfRenderId) {
-                    batchCache.renderSelf[subMeshId] = false;
-                }
-
             }
-            this._instanceDataStorage.renderIdForInstances[subMeshId] = currentRenderId;
         }
-
+        batchCache.hardwareInstancedRendering[subMeshId] = this._instanceDataStorage.hardwareInstancedRendering && (batchCache.visibleInstances[subMeshId] !== null) && (batchCache.visibleInstances[subMeshId] !== undefined);
+        this._instanceDataStorage._previousBatch = batchCache;
         return batchCache;
     }
 
@@ -1502,6 +1493,25 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
         return this;
     }
 
+    /** @hidden */
+    public _freeze() {
+        this._instanceDataStorage.isFrozen = true;
+
+        if (!this.subMeshes) {
+            return;
+        }
+
+        // Prepare batches
+        for (var index = 0; index < this.subMeshes.length; index++) {
+            this._getInstancesRenderList(index);
+        }
+    }
+
+    /** @hidden */
+    public _unFreeze() {
+        this._instanceDataStorage.isFrozen = false;
+    }
+
     /**
      * Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager
      * @param subMesh defines the subMesh to render
@@ -1531,7 +1541,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
         }
 
         var engine = scene.getEngine();
-        var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
+        var hardwareInstancedRendering = batch.hardwareInstancedRendering[subMesh._id];
 
         // Material
         let material = subMesh.getMaterial();
@@ -2420,7 +2430,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
                 for (var j = 0; j < 3; j++) {
                     a = vertexIndex[j];
                     b = vertexIndex[(j + 1) % 3];
-                    if (side[a] === undefined  && side[b] ===  undefined) {
+                    if (side[a] === undefined && side[b] === undefined) {
                         side[a] = new Array();
                         side[b] = new Array();
                     }
@@ -2432,7 +2442,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
                             side[b] = new Array();
                         }
                     }
-                    if (side[a][b]  === undefined  && side[b][a] === undefined) {
+                    if (side[a][b] === undefined && side[b][a] === undefined) {
                         side[a][b] = [];
                         deltaPosition.x = (positions[3 * b] - positions[3 * a]) / segments;
                         deltaPosition.y = (positions[3 * b + 1] - positions[3 * a + 1]) / segments;

+ 50 - 20
src/Meshes/transformNode.ts

@@ -108,11 +108,29 @@ 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 +184,8 @@ export class TransformNode extends Node {
         }
 
         this._activeParentProcessor = this._defaultParentProcessor;
-        this._activeCompositionProcess = this._defaultCompositionProcessor;
+        this._activeCompositionProcessor = this._defaultCompositionProcessor;
+        this._translationProcessor = this._defaultTranslationProcessor;
     }
 
     /**
@@ -227,7 +246,7 @@ export class TransformNode extends Node {
         this._rotationQuaternion = quaternion;
         //reset the rotation vector.
         if (quaternion) {
-            this.rotation.setAll(0.0);
+            this._rotation.setAll(0.0);
         }
         this._isDirty = true;
     }
@@ -363,9 +382,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 +922,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 +948,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 +1045,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 +1069,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 +1091,7 @@ export class TransformNode extends Node {
         }
 
         // Compose
-        this._activeCompositionProcess(scaling, rotation, translation);
+        this._activeCompositionProcessor(scaling, rotation, translation);
 
         // Parent
         if (parent && parent.getWorldMatrix) {

+ 4 - 1
src/Rendering/renderingGroup.ts

@@ -34,7 +34,8 @@ export class RenderingGroup {
     private _renderAlphaTest: (subMeshes: SmartArray<SubMesh>) => void;
     private _renderTransparent: (subMeshes: SmartArray<SubMesh>) => void;
 
-    private _edgesRenderers = new SmartArray<IEdgesRenderer>(16);
+    /** @hidden */
+    public _edgesRenderers = new SmartArray<IEdgesRenderer>(16);
 
     public onBeforeTransparentRendering: () => void;
 
@@ -363,6 +364,8 @@ export class RenderingGroup {
             this._opaqueSubMeshes.push(subMesh); // Opaque
         }
 
+        mesh._renderingGroup = this;
+
         if (mesh._edgesRenderer && mesh._edgesRenderer.isEnabled) {
             this._edgesRenderers.push(mesh._edgesRenderer);
         }

+ 20 - 2
src/scene.ts

@@ -3869,6 +3869,10 @@ export class Scene extends AbstractScene implements IAnimatable {
 
         this._evaluateActiveMeshes();
         this._activeMeshesFrozen = true;
+
+        for (var mesh of this._activeMeshes.data) {
+            mesh._freeze();
+        }
         return this;
     }
 
@@ -3877,12 +3881,23 @@ export class Scene extends AbstractScene implements IAnimatable {
      * @returns the current scene
      */
     public unfreezeActiveMeshes(): Scene {
+        for (var mesh of this._activeMeshes.data) {
+            mesh._unFreeze();
+        }
+
         this._activeMeshesFrozen = false;
         return this;
     }
 
     private _evaluateActiveMeshes(): void {
         if (this._activeMeshesFrozen && this._activeMeshes.length) {
+
+            const len = this._activeMeshes.length;
+            for (let i = 0; i < len; i++) {
+                let mesh = this._activeMeshes.data[i];
+                mesh.computeWorldMatrix();
+            }
+
             return;
         }
 
@@ -3910,6 +3925,7 @@ export class Scene extends AbstractScene implements IAnimatable {
         const len = meshes.length;
         for (let i = 0; i < len; i++) {
             const mesh = meshes.data[i];
+            mesh._isActive = false;
             if (mesh.isBlocked) {
                 continue;
             }
@@ -3944,12 +3960,14 @@ export class Scene extends AbstractScene implements IAnimatable {
                 this._activeMeshes.push(mesh);
                 this.activeCamera._activeMeshes.push(mesh);
 
-                mesh._activate(this._renderId);
                 if (meshLOD !== mesh) {
                     meshLOD._activate(this._renderId);
                 }
 
-                this._activeMesh(mesh, meshLOD);
+                if (mesh._activate(this._renderId)) {
+                    mesh._isActive = true;
+                    this._activeMesh(mesh, meshLOD);
+                }
             }
         }
 

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"