浏览代码

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js

David 7 年之前
父节点
当前提交
f6a1c9d63c
共有 93 个文件被更改,包括 29948 次插入27155 次删除
  1. 2 2
      .travis.yml
  2. 10582 9985
      Playground/babylon.d.txt
  3. 11 3
      Tools/Gulp/gulpfile.js
  4. 11498 10896
      dist/preview release/babylon.d.ts
  5. 43 43
      dist/preview release/babylon.js
  6. 578 147
      dist/preview release/babylon.max.js
  7. 43 43
      dist/preview release/babylon.worker.js
  8. 3984 3382
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  9. 46 46
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  10. 591 164
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  11. 591 164
      dist/preview release/customConfigurations/minimalGLTFViewer/es6.js
  12. 578 147
      dist/preview release/es6.js
  13. 4 4
      dist/preview release/inspector/babylon.inspector.bundle.js
  14. 2 0
      dist/preview release/inspector/babylon.inspector.d.ts
  15. 6 4
      dist/preview release/inspector/babylon.inspector.js
  16. 4 4
      dist/preview release/inspector/babylon.inspector.min.js
  17. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  18. 13 17
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  19. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  20. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  21. 13 17
      dist/preview release/loaders/babylon.glTFFileLoader.js
  22. 2 2
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  23. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  24. 13 17
      dist/preview release/loaders/babylonjs.loaders.js
  25. 3 3
      dist/preview release/loaders/babylonjs.loaders.min.js
  26. 1 1
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  27. 1 1
      dist/preview release/materialsLibrary/babylon.cellMaterial.js
  28. 1 1
      dist/preview release/materialsLibrary/babylon.cellMaterial.min.js
  29. 1 0
      dist/preview release/materialsLibrary/babylon.customMaterial.d.ts
  30. 4 1
      dist/preview release/materialsLibrary/babylon.customMaterial.js
  31. 2 2
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  32. 1 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.js
  33. 1 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.min.js
  34. 1 1
      dist/preview release/materialsLibrary/babylon.furMaterial.js
  35. 1 1
      dist/preview release/materialsLibrary/babylon.furMaterial.min.js
  36. 1 1
      dist/preview release/materialsLibrary/babylon.gradientMaterial.js
  37. 1 1
      dist/preview release/materialsLibrary/babylon.gradientMaterial.min.js
  38. 1 1
      dist/preview release/materialsLibrary/babylon.lavaMaterial.js
  39. 1 1
      dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js
  40. 1 1
      dist/preview release/materialsLibrary/babylon.normalMaterial.js
  41. 1 1
      dist/preview release/materialsLibrary/babylon.normalMaterial.min.js
  42. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js
  43. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  44. 1 1
      dist/preview release/materialsLibrary/babylon.simpleMaterial.js
  45. 1 1
      dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js
  46. 1 1
      dist/preview release/materialsLibrary/babylon.terrainMaterial.js
  47. 1 1
      dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js
  48. 1 1
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js
  49. 1 1
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js
  50. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.js
  51. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  52. 15 12
      dist/preview release/materialsLibrary/babylonjs.materials.js
  53. 7 7
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  54. 1 0
      dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts
  55. 2 1316
      dist/preview release/typedocValidationBaseline.json
  56. 55 55
      dist/preview release/viewer/babylon.viewer.js
  57. 2 2
      dist/preview release/what's new.md
  58. 7 6
      inspector/src/Inspector.ts
  59. 0 1
      inspector/src/adapters/MeshAdapter.ts
  60. 12 6
      inspector/src/scheduler/Scheduler.ts
  61. 11 13
      loaders/src/glTF/2.0/babylon.glTFLoader.ts
  62. 1 1
      loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts
  63. 22 22
      materialsLibrary/src/cell/babylon.cellMaterial.ts
  64. 5 1
      materialsLibrary/src/custom/babylon.customMaterial.ts
  65. 54 54
      materialsLibrary/src/fire/babylon.fireMaterial.ts
  66. 73 73
      materialsLibrary/src/fur/babylon.furMaterial.ts
  67. 19 19
      materialsLibrary/src/gradient/babylon.gradientMaterial.ts
  68. 29 29
      materialsLibrary/src/lava/babylon.lavaMaterial.ts
  69. 23 23
      materialsLibrary/src/normal/babylon.normalMaterial.ts
  70. 18 18
      materialsLibrary/src/shadowOnly/babylon.shadowOnlyMaterial.ts
  71. 27 27
      materialsLibrary/src/simple/babylon.simpleMaterial.ts
  72. 39 39
      materialsLibrary/src/terrain/babylon.terrainMaterial.ts
  73. 49 49
      materialsLibrary/src/triPlanar/babylon.triPlanarMaterial.ts
  74. 6 6
      materialsLibrary/src/water/babylon.waterMaterial.ts
  75. 19 10
      src/Animations/babylon.animationGroup.ts
  76. 23 23
      src/Debug/babylon.rayHelper.ts
  77. 80 78
      src/Engine/babylon.engine.ts
  78. 1 1
      src/Engine/babylon.nullEngine.ts
  79. 1 1
      src/Materials/Background/babylon.backgroundMaterial.ts
  80. 1 1
      src/Materials/PBR/babylon.pbrBaseMaterial.ts
  81. 2 2
      src/Materials/Textures/babylon.hdrCubeTexture.ts
  82. 5 8
      src/Materials/babylon.material.ts
  83. 10 2
      src/Materials/babylon.materialHelper.ts
  84. 1 1
      src/Materials/babylon.shaderMaterial.ts
  85. 1 1
      src/Materials/babylon.standardMaterial.ts
  86. 0 8
      src/Mesh/babylon.mesh.ts
  87. 0 2
      src/PostProcess/babylon.volumetricLightScatteringPostProcess.ts
  88. 14 20
      src/Rendering/babylon.renderingGroup.ts
  89. 576 58
      src/Tools/babylon.assetsManager.ts
  90. 20 0
      src/Tools/babylon.tools.ts
  91. 5 1
      src/babylon.mixins.ts
  92. 1 0
      tests/validation/integration.js
  93. 69 38
      tests/validation/validation.js

+ 2 - 2
.travis.yml

@@ -4,9 +4,9 @@ language: node_js
 node_js:
 node_js:
 - '6'
 - '6'
 before_script:
 before_script:
-- npm install -g gulp
+- travis_retry npm install -g gulp
 - cd ./Tools/Gulp
 - cd ./Tools/Gulp
-- npm install
+- travis_retry npm install
 - "export DISPLAY=:99.0"
 - "export DISPLAY=:99.0"
 - "sh -e /etc/init.d/xvfb start"
 - "sh -e /etc/init.d/xvfb start"
 - sleep 3 # give xvfb some time to start
 - sleep 3 # give xvfb some time to start

文件差异内容过多而无法显示
+ 10582 - 9985
Playground/babylon.d.txt


+ 11 - 3
Tools/Gulp/gulpfile.js

@@ -800,10 +800,10 @@ gulp.task("typedoc-generate", function () {
             module: "commonjs",
             module: "commonjs",
             target: "es5",
             target: "es5",
             includeDeclarations: true,
             includeDeclarations: true,
- 
+
             // Output options (see typedoc docs)
             // Output options (see typedoc docs)
             json: config.build.typedocJSON,
             json: config.build.typedocJSON,
- 
+
             // TypeDoc options (see typedoc docs)
             // TypeDoc options (see typedoc docs)
             ignoreCompilerErrors: true,
             ignoreCompilerErrors: true,
 
 
@@ -831,7 +831,7 @@ gulp.task("typedoc-validate", function () {
  */
  */
 gulp.task("typedoc-generateValidationBaseline", function () {
 gulp.task("typedoc-generateValidationBaseline", function () {
     return gulp.src(config.build.typedocJSON)
     return gulp.src(config.build.typedocJSON)
-    .pipe(validateTypedoc(config.build.typedocValidationBaseline, "BABYLON", true, true));
+        .pipe(validateTypedoc(config.build.typedocValidationBaseline, "BABYLON", true, true));
 });
 });
 
 
 /**
 /**
@@ -842,6 +842,14 @@ gulp.task("typedoc-all", function (cb) {
     runSequence("typedoc-generate", "typedoc-validate", "typedoc-generateValidationBaseline", cb);
     runSequence("typedoc-generate", "typedoc-validate", "typedoc-generateValidationBaseline", cb);
 });
 });
 
 
+
+/**
+ * Validate compile the code and check the comments and style case convention through typedoc
+ */
+gulp.task("typedoc-check", function (cb) {
+    runSequence("typescript-compile", "typedoc-generate", "typedoc-validate", cb);
+});
+
 /**
 /**
  * Launches the KARMA validation tests in chrome in order to debug them.
  * Launches the KARMA validation tests in chrome in order to debug them.
  * (Can only be launch locally.)
  * (Can only be launch locally.)

文件差异内容过多而无法显示
+ 11498 - 10896
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 43 - 43
dist/preview release/babylon.js


文件差异内容过多而无法显示
+ 578 - 147
dist/preview release/babylon.max.js


文件差异内容过多而无法显示
+ 43 - 43
dist/preview release/babylon.worker.js


文件差异内容过多而无法显示
+ 3984 - 3382
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


文件差异内容过多而无法显示
+ 46 - 46
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


文件差异内容过多而无法显示
+ 591 - 164
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


文件差异内容过多而无法显示
+ 591 - 164
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js


文件差异内容过多而无法显示
+ 578 - 147
dist/preview release/es6.js


文件差异内容过多而无法显示
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


+ 2 - 0
dist/preview release/inspector/babylon.inspector.d.ts

@@ -780,6 +780,7 @@ declare module INSPECTOR {
         static REFRESH_TIME: number;
         static REFRESH_TIME: number;
         /** The list of data to update */
         /** The list of data to update */
         private _updatableProperties;
         private _updatableProperties;
+        private interval;
         constructor();
         constructor();
         static getInstance(): Scheduler;
         static getInstance(): Scheduler;
         /** Add a property line to be updated every X ms */
         /** Add a property line to be updated every X ms */
@@ -787,6 +788,7 @@ declare module INSPECTOR {
         /** Removes the given property from the list of properties to update */
         /** Removes the given property from the list of properties to update */
         remove(prop: PropertyLine): void;
         remove(prop: PropertyLine): void;
         private _update();
         private _update();
+        dispose(): void;
     }
     }
 }
 }
 
 

+ 6 - 4
dist/preview release/inspector/babylon.inspector.js

@@ -289,6 +289,7 @@ var INSPECTOR;
                     }
                     }
                 }
                 }
             }
             }
+            INSPECTOR.Scheduler.getInstance().dispose();
         };
         };
         /** Open the inspector in a new popup
         /** Open the inspector in a new popup
          * Set 'firstTime' to true if there is no inspector created beforehands
          * Set 'firstTime' to true if there is no inspector created beforehands
@@ -1041,9 +1042,7 @@ var INSPECTOR;
     var MeshAdapter = /** @class */ (function (_super) {
     var MeshAdapter = /** @class */ (function (_super) {
         __extends(MeshAdapter, _super);
         __extends(MeshAdapter, _super);
         function MeshAdapter(mesh) {
         function MeshAdapter(mesh) {
-            var _this = _super.call(this, mesh) || this;
-            new BABYLON.Debug.AxesViewer(mesh.getScene());
-            return _this;
+            return _super.call(this, mesh) || this;
         }
         }
         /** Returns the name displayed in the tree */
         /** Returns the name displayed in the tree */
         MeshAdapter.prototype.id = function () {
         MeshAdapter.prototype.id = function () {
@@ -2433,7 +2432,7 @@ var INSPECTOR;
             this.pause = false;
             this.pause = false;
             /** The list of data to update */
             /** The list of data to update */
             this._updatableProperties = [];
             this._updatableProperties = [];
-            setInterval(this._update.bind(this), Scheduler.REFRESH_TIME);
+            this.interval = setInterval(this._update.bind(this), Scheduler.REFRESH_TIME);
         }
         }
         Scheduler.getInstance = function () {
         Scheduler.getInstance = function () {
             if (!Scheduler._instance) {
             if (!Scheduler._instance) {
@@ -2461,6 +2460,9 @@ var INSPECTOR;
                 }
                 }
             }
             }
         };
         };
+        Scheduler.prototype.dispose = function () {
+            window.clearInterval(this.interval);
+        };
         /** All properties are refreshed every 250ms */
         /** All properties are refreshed every 250ms */
         Scheduler.REFRESH_TIME = 250;
         Scheduler.REFRESH_TIME = 250;
         return Scheduler;
         return Scheduler;

文件差异内容过多而无法显示
+ 4 - 4
dist/preview release/inspector/babylon.inspector.min.js


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

@@ -225,7 +225,7 @@ declare module BABYLON.GLTF2 {
         channels: IGLTFAnimationChannel[];
         channels: IGLTFAnimationChannel[];
         samplers: IGLTFAnimationSampler[];
         samplers: IGLTFAnimationSampler[];
         index: number;
         index: number;
-        targets: any[];
+        babylonAnimationGroup: AnimationGroup;
     }
     }
     interface IGLTFAsset extends IGLTFChildRootProperty {
     interface IGLTFAsset extends IGLTFChildRootProperty {
         copyright?: string;
         copyright?: string;

+ 13 - 17
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -673,6 +673,10 @@ var BABYLON;
                 if (!animations) {
                 if (!animations) {
                     return;
                     return;
                 }
                 }
+                for (var _i = 0, animations_1 = animations; _i < animations_1.length; _i++) {
+                    var animation = animations_1[_i];
+                    animation.babylonAnimationGroup.normalize();
+                }
                 switch (this.animationStartMode) {
                 switch (this.animationStartMode) {
                     case BABYLON.GLTFLoaderAnimationStartMode.NONE: {
                     case BABYLON.GLTFLoaderAnimationStartMode.NONE: {
                         // do nothing
                         // do nothing
@@ -680,19 +684,13 @@ var BABYLON;
                     }
                     }
                     case BABYLON.GLTFLoaderAnimationStartMode.FIRST: {
                     case BABYLON.GLTFLoaderAnimationStartMode.FIRST: {
                         var animation = animations[0];
                         var animation = animations[0];
-                        for (var _i = 0, _a = animation.targets; _i < _a.length; _i++) {
-                            var target = _a[_i];
-                            this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                        }
+                        animation.babylonAnimationGroup.start(true);
                         break;
                         break;
                     }
                     }
                     case BABYLON.GLTFLoaderAnimationStartMode.ALL: {
                     case BABYLON.GLTFLoaderAnimationStartMode.ALL: {
-                        for (var _b = 0, animations_1 = animations; _b < animations_1.length; _b++) {
-                            var animation = animations_1[_b];
-                            for (var _c = 0, _d = animation.targets; _c < _d.length; _c++) {
-                                var target = _d[_c];
-                                this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                            }
+                        for (var _a = 0, animations_2 = animations; _a < animations_2.length; _a++) {
+                            var animation = animations_2[_a];
+                            animation.babylonAnimationGroup.start(true);
                         }
                         }
                         break;
                         break;
                     }
                     }
@@ -1304,7 +1302,7 @@ var BABYLON;
                 }
                 }
             };
             };
             GLTFLoader.prototype._loadAnimation = function (context, animation) {
             GLTFLoader.prototype._loadAnimation = function (context, animation) {
-                animation.targets = [];
+                animation.babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation.index, this._babylonScene);
                 for (var index = 0; index < animation.channels.length; index++) {
                 for (var index = 0; index < animation.channels.length; index++) {
                     var channel = GLTFLoader._GetProperty(animation.channels, index);
                     var channel = GLTFLoader._GetProperty(animation.channels, index);
                     if (!channel) {
                     if (!channel) {
@@ -1444,7 +1442,7 @@ var BABYLON;
                         var morphTargetManager = targetNode.babylonMesh.morphTargetManager;
                         var morphTargetManager = targetNode.babylonMesh.morphTargetManager;
                         var _loop_7 = function (targetIndex) {
                         var _loop_7 = function (targetIndex) {
                             var morphTarget = morphTargetManager.getTarget(targetIndex);
                             var morphTarget = morphTargetManager.getTarget(targetIndex);
-                            var animationName = (animation.name || "anim" + animation.index) + "_" + targetIndex;
+                            var animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                             var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                             var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                             babylonAnimation.setKeys(keys.map(function (key) { return ({
                             babylonAnimation.setKeys(keys.map(function (key) { return ({
                                 frame: key.frame,
                                 frame: key.frame,
@@ -1452,22 +1450,20 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
                             }); }));
-                            morphTarget.animations.push(babylonAnimation);
-                            animation.targets.push(morphTarget);
+                            animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
                         };
                         };
                         for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
                         for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
                             _loop_7(targetIndex);
                             _loop_7(targetIndex);
                         }
                         }
                     }
                     }
                     else {
                     else {
-                        var animationName = animation.name || "anim" + animation.index;
+                        var animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         babylonAnimation.setKeys(keys);
                         if (targetNode.babylonAnimationTargets) {
                         if (targetNode.babylonAnimationTargets) {
                             for (var _i = 0, _a = targetNode.babylonAnimationTargets; _i < _a.length; _i++) {
                             for (var _i = 0, _a = targetNode.babylonAnimationTargets; _i < _a.length; _i++) {
                                 var target = _a[_i];
                                 var target = _a[_i];
-                                target.animations.push(babylonAnimation.clone());
-                                animation.targets.push(target);
+                                animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, target);
                             }
                             }
                         }
                         }
                     }
                     }

文件差异内容过多而无法显示
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


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

@@ -782,7 +782,7 @@ declare module BABYLON.GLTF2 {
         channels: IGLTFAnimationChannel[];
         channels: IGLTFAnimationChannel[];
         samplers: IGLTFAnimationSampler[];
         samplers: IGLTFAnimationSampler[];
         index: number;
         index: number;
-        targets: any[];
+        babylonAnimationGroup: AnimationGroup;
     }
     }
     interface IGLTFAsset extends IGLTFChildRootProperty {
     interface IGLTFAsset extends IGLTFChildRootProperty {
         copyright?: string;
         copyright?: string;

+ 13 - 17
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -2839,6 +2839,10 @@ var BABYLON;
                 if (!animations) {
                 if (!animations) {
                     return;
                     return;
                 }
                 }
+                for (var _i = 0, animations_1 = animations; _i < animations_1.length; _i++) {
+                    var animation = animations_1[_i];
+                    animation.babylonAnimationGroup.normalize();
+                }
                 switch (this.animationStartMode) {
                 switch (this.animationStartMode) {
                     case BABYLON.GLTFLoaderAnimationStartMode.NONE: {
                     case BABYLON.GLTFLoaderAnimationStartMode.NONE: {
                         // do nothing
                         // do nothing
@@ -2846,19 +2850,13 @@ var BABYLON;
                     }
                     }
                     case BABYLON.GLTFLoaderAnimationStartMode.FIRST: {
                     case BABYLON.GLTFLoaderAnimationStartMode.FIRST: {
                         var animation = animations[0];
                         var animation = animations[0];
-                        for (var _i = 0, _a = animation.targets; _i < _a.length; _i++) {
-                            var target = _a[_i];
-                            this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                        }
+                        animation.babylonAnimationGroup.start(true);
                         break;
                         break;
                     }
                     }
                     case BABYLON.GLTFLoaderAnimationStartMode.ALL: {
                     case BABYLON.GLTFLoaderAnimationStartMode.ALL: {
-                        for (var _b = 0, animations_1 = animations; _b < animations_1.length; _b++) {
-                            var animation = animations_1[_b];
-                            for (var _c = 0, _d = animation.targets; _c < _d.length; _c++) {
-                                var target = _d[_c];
-                                this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                            }
+                        for (var _a = 0, animations_2 = animations; _a < animations_2.length; _a++) {
+                            var animation = animations_2[_a];
+                            animation.babylonAnimationGroup.start(true);
                         }
                         }
                         break;
                         break;
                     }
                     }
@@ -3470,7 +3468,7 @@ var BABYLON;
                 }
                 }
             };
             };
             GLTFLoader.prototype._loadAnimation = function (context, animation) {
             GLTFLoader.prototype._loadAnimation = function (context, animation) {
-                animation.targets = [];
+                animation.babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation.index, this._babylonScene);
                 for (var index = 0; index < animation.channels.length; index++) {
                 for (var index = 0; index < animation.channels.length; index++) {
                     var channel = GLTFLoader._GetProperty(animation.channels, index);
                     var channel = GLTFLoader._GetProperty(animation.channels, index);
                     if (!channel) {
                     if (!channel) {
@@ -3610,7 +3608,7 @@ var BABYLON;
                         var morphTargetManager = targetNode.babylonMesh.morphTargetManager;
                         var morphTargetManager = targetNode.babylonMesh.morphTargetManager;
                         var _loop_7 = function (targetIndex) {
                         var _loop_7 = function (targetIndex) {
                             var morphTarget = morphTargetManager.getTarget(targetIndex);
                             var morphTarget = morphTargetManager.getTarget(targetIndex);
-                            var animationName = (animation.name || "anim" + animation.index) + "_" + targetIndex;
+                            var animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                             var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                             var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                             babylonAnimation.setKeys(keys.map(function (key) { return ({
                             babylonAnimation.setKeys(keys.map(function (key) { return ({
                                 frame: key.frame,
                                 frame: key.frame,
@@ -3618,22 +3616,20 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
                             }); }));
-                            morphTarget.animations.push(babylonAnimation);
-                            animation.targets.push(morphTarget);
+                            animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
                         };
                         };
                         for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
                         for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
                             _loop_7(targetIndex);
                             _loop_7(targetIndex);
                         }
                         }
                     }
                     }
                     else {
                     else {
-                        var animationName = animation.name || "anim" + animation.index;
+                        var animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         babylonAnimation.setKeys(keys);
                         if (targetNode.babylonAnimationTargets) {
                         if (targetNode.babylonAnimationTargets) {
                             for (var _i = 0, _a = targetNode.babylonAnimationTargets; _i < _a.length; _i++) {
                             for (var _i = 0, _a = targetNode.babylonAnimationTargets; _i < _a.length; _i++) {
                                 var target = _a[_i];
                                 var target = _a[_i];
-                                target.animations.push(babylonAnimation.clone());
-                                animation.targets.push(target);
+                                animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, target);
                             }
                             }
                         }
                         }
                     }
                     }

文件差异内容过多而无法显示
+ 2 - 2
dist/preview release/loaders/babylon.glTFFileLoader.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


+ 13 - 17
dist/preview release/loaders/babylonjs.loaders.js

@@ -3813,6 +3813,10 @@ var BABYLON;
                 if (!animations) {
                 if (!animations) {
                     return;
                     return;
                 }
                 }
+                for (var _i = 0, animations_1 = animations; _i < animations_1.length; _i++) {
+                    var animation = animations_1[_i];
+                    animation.babylonAnimationGroup.normalize();
+                }
                 switch (this.animationStartMode) {
                 switch (this.animationStartMode) {
                     case BABYLON.GLTFLoaderAnimationStartMode.NONE: {
                     case BABYLON.GLTFLoaderAnimationStartMode.NONE: {
                         // do nothing
                         // do nothing
@@ -3820,19 +3824,13 @@ var BABYLON;
                     }
                     }
                     case BABYLON.GLTFLoaderAnimationStartMode.FIRST: {
                     case BABYLON.GLTFLoaderAnimationStartMode.FIRST: {
                         var animation = animations[0];
                         var animation = animations[0];
-                        for (var _i = 0, _a = animation.targets; _i < _a.length; _i++) {
-                            var target = _a[_i];
-                            this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                        }
+                        animation.babylonAnimationGroup.start(true);
                         break;
                         break;
                     }
                     }
                     case BABYLON.GLTFLoaderAnimationStartMode.ALL: {
                     case BABYLON.GLTFLoaderAnimationStartMode.ALL: {
-                        for (var _b = 0, animations_1 = animations; _b < animations_1.length; _b++) {
-                            var animation = animations_1[_b];
-                            for (var _c = 0, _d = animation.targets; _c < _d.length; _c++) {
-                                var target = _d[_c];
-                                this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                            }
+                        for (var _a = 0, animations_2 = animations; _a < animations_2.length; _a++) {
+                            var animation = animations_2[_a];
+                            animation.babylonAnimationGroup.start(true);
                         }
                         }
                         break;
                         break;
                     }
                     }
@@ -4444,7 +4442,7 @@ var BABYLON;
                 }
                 }
             };
             };
             GLTFLoader.prototype._loadAnimation = function (context, animation) {
             GLTFLoader.prototype._loadAnimation = function (context, animation) {
-                animation.targets = [];
+                animation.babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation.index, this._babylonScene);
                 for (var index = 0; index < animation.channels.length; index++) {
                 for (var index = 0; index < animation.channels.length; index++) {
                     var channel = GLTFLoader._GetProperty(animation.channels, index);
                     var channel = GLTFLoader._GetProperty(animation.channels, index);
                     if (!channel) {
                     if (!channel) {
@@ -4584,7 +4582,7 @@ var BABYLON;
                         var morphTargetManager = targetNode.babylonMesh.morphTargetManager;
                         var morphTargetManager = targetNode.babylonMesh.morphTargetManager;
                         var _loop_7 = function (targetIndex) {
                         var _loop_7 = function (targetIndex) {
                             var morphTarget = morphTargetManager.getTarget(targetIndex);
                             var morphTarget = morphTargetManager.getTarget(targetIndex);
-                            var animationName = (animation.name || "anim" + animation.index) + "_" + targetIndex;
+                            var animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                             var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                             var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                             babylonAnimation.setKeys(keys.map(function (key) { return ({
                             babylonAnimation.setKeys(keys.map(function (key) { return ({
                                 frame: key.frame,
                                 frame: key.frame,
@@ -4592,22 +4590,20 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
                             }); }));
-                            morphTarget.animations.push(babylonAnimation);
-                            animation.targets.push(morphTarget);
+                            animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
                         };
                         };
                         for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
                         for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
                             _loop_7(targetIndex);
                             _loop_7(targetIndex);
                         }
                         }
                     }
                     }
                     else {
                     else {
-                        var animationName = animation.name || "anim" + animation.index;
+                        var animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         babylonAnimation.setKeys(keys);
                         if (targetNode.babylonAnimationTargets) {
                         if (targetNode.babylonAnimationTargets) {
                             for (var _i = 0, _a = targetNode.babylonAnimationTargets; _i < _a.length; _i++) {
                             for (var _i = 0, _a = targetNode.babylonAnimationTargets; _i < _a.length; _i++) {
                                 var target = _a[_i];
                                 var target = _a[_i];
-                                target.animations.push(babylonAnimation.clone());
-                                animation.targets.push(target);
+                                animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, target);
                             }
                             }
                         }
                         }
                     }
                     }

文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/loaders/babylonjs.loaders.min.js


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

@@ -883,7 +883,7 @@ declare module BABYLON.GLTF2 {
         channels: IGLTFAnimationChannel[];
         channels: IGLTFAnimationChannel[];
         samplers: IGLTFAnimationSampler[];
         samplers: IGLTFAnimationSampler[];
         index: number;
         index: number;
-        targets: any[];
+        babylonAnimationGroup: AnimationGroup;
     }
     }
     interface IGLTFAsset extends IGLTFChildRootProperty {
     interface IGLTFAsset extends IGLTFChildRootProperty {
         copyright?: string;
         copyright?: string;

+ 1 - 1
dist/preview release/materialsLibrary/babylon.cellMaterial.js

@@ -102,7 +102,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.cellMaterial.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylon.customMaterial.d.ts

@@ -222,6 +222,7 @@ declare module BABYLON {
          * Sets the Color Grading 2D Lookup Texture.
          * Sets the Color Grading 2D Lookup Texture.
          */
          */
         cameraColorGradingTexture: Nullable<BaseTexture>;
         cameraColorGradingTexture: Nullable<BaseTexture>;
+        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
         customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines_OldVer) => string;
         customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines_OldVer) => string;
         protected _renderTargets: SmartArray<RenderTargetTexture>;
         protected _renderTargets: SmartArray<RenderTargetTexture>;
         protected _worldViewProjectionMatrix: Matrix;
         protected _worldViewProjectionMatrix: Matrix;

+ 4 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.js

@@ -315,6 +315,9 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        StandardMaterial_OldVer.prototype._shouldTurnAlphaTestOn = function (mesh) {
+            return (!this.needAlphaBlendingForMesh(mesh) && this.needAlphaTesting());
+        };
         StandardMaterial_OldVer.prototype.getClassName = function () {
         StandardMaterial_OldVer.prototype.getClassName = function () {
             return "StandardMaterial_OldVer";
             return "StandardMaterial_OldVer";
         };
         };
@@ -564,7 +567,7 @@ var BABYLON;
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Get correct effect      
             // Get correct effect      
             if (defines.isDirty) {
             if (defines.isDirty) {
                 defines.markAsProcessed();
                 defines.markAsProcessed();

文件差异内容过多而无法显示
+ 2 - 2
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.fireMaterial.js

@@ -94,7 +94,7 @@ var BABYLON;
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled);
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled);
             }
             }
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             // Get correct effect      
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.fireMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.furMaterial.js

@@ -147,7 +147,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.furMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.gradientMaterial.js

@@ -118,7 +118,7 @@ var BABYLON;
                 }
                 }
             }
             }
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
             // Attribs
             // Attribs

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gradientMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.lavaMaterial.js

@@ -135,7 +135,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.normalMaterial.js

@@ -129,7 +129,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.normalMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js

@@ -86,7 +86,7 @@ var BABYLON;
                     }
                     }
                 }
                 }
             }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
             // Attribs
             // Attribs

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.simpleMaterial.js

@@ -96,7 +96,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.terrainMaterial.js

@@ -102,7 +102,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js

@@ -121,7 +121,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.js

@@ -228,7 +228,7 @@ var BABYLON;
                     }
                     }
                 }
                 }
             }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
             if (defines._areMiscDirty) {
             if (defines._areMiscDirty) {
                 if (this._fresnelSeparate) {
                 if (this._fresnelSeparate) {

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


+ 15 - 12
dist/preview release/materialsLibrary/babylonjs.materials.js

@@ -96,7 +96,7 @@ var BABYLON;
                     }
                     }
                 }
                 }
             }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
             // Attribs
             // Attribs
@@ -326,7 +326,7 @@ var BABYLON;
                 }
                 }
             }
             }
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
             // Attribs
             // Attribs
@@ -615,7 +615,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      
@@ -926,7 +926,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      
@@ -1238,7 +1238,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      
@@ -1642,7 +1642,7 @@ var BABYLON;
                     }
                     }
                 }
                 }
             }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
             if (defines._areMiscDirty) {
             if (defines._areMiscDirty) {
                 if (this._fresnelSeparate) {
                 if (this._fresnelSeparate) {
@@ -2124,7 +2124,7 @@ var BABYLON;
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled);
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled);
             }
             }
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             // Get correct effect      
             // Get correct effect      
@@ -2498,7 +2498,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      
@@ -2915,7 +2915,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      
@@ -3321,7 +3321,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      
@@ -4311,6 +4311,9 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        StandardMaterial_OldVer.prototype._shouldTurnAlphaTestOn = function (mesh) {
+            return (!this.needAlphaBlendingForMesh(mesh) && this.needAlphaTesting());
+        };
         StandardMaterial_OldVer.prototype.getClassName = function () {
         StandardMaterial_OldVer.prototype.getClassName = function () {
             return "StandardMaterial_OldVer";
             return "StandardMaterial_OldVer";
         };
         };
@@ -4560,7 +4563,7 @@ var BABYLON;
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Get correct effect      
             // Get correct effect      
             if (defines.isDirty) {
             if (defines.isDirty) {
                 defines.markAsProcessed();
                 defines.markAsProcessed();
@@ -6150,7 +6153,7 @@ var BABYLON;
             // Lights
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
             // Get correct effect      

文件差异内容过多而无法显示
+ 7 - 7
dist/preview release/materialsLibrary/babylonjs.materials.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts

@@ -728,6 +728,7 @@ declare module BABYLON {
          * Sets the Color Grading 2D Lookup Texture.
          * Sets the Color Grading 2D Lookup Texture.
          */
          */
         cameraColorGradingTexture: Nullable<BaseTexture>;
         cameraColorGradingTexture: Nullable<BaseTexture>;
+        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
         customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines_OldVer) => string;
         customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines_OldVer) => string;
         protected _renderTargets: SmartArray<RenderTargetTexture>;
         protected _renderTargets: SmartArray<RenderTargetTexture>;
         protected _worldViewProjectionMatrix: Matrix;
         protected _worldViewProjectionMatrix: Matrix;

文件差异内容过多而无法显示
+ 2 - 1316
dist/preview release/typedocValidationBaseline.json


文件差异内容过多而无法显示
+ 55 - 55
dist/preview release/viewer/babylon.viewer.js


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

@@ -6,6 +6,7 @@
 
 
 ## Updates
 ## Updates
 - Improved [SceneOptimizer](http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer) to provide better adapatability ([deltakosh](https://github.com/deltakosh))
 - Improved [SceneOptimizer](http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer) to provide better adapatability ([deltakosh](https://github.com/deltakosh))
+- Improved `scene.isReady()` function which now takes in account shadows and LOD ([deltakosh](https://github.com/deltakosh))
 - New watcher configuration for VSCode. Now the task only compiles changed files ([sebavan](https://github.com/sebavan))
 - New watcher configuration for VSCode. Now the task only compiles changed files ([sebavan](https://github.com/sebavan))
 - Added new draw modes to engine (points, lines, linesloop, linestrip, trianglestrip, trianglefan) ([benaadams](https://github.com/benaadams))
 - Added new draw modes to engine (points, lines, linesloop, linestrip, trianglestrip, trianglefan) ([benaadams](https://github.com/benaadams))
 - Added GUI Textblock.lineSpacing setter and getter to configure vertical space between lines in pixels or percentage values when working with text wrapping ([carloslanderas](https://github.com/carloslanderas))
 - Added GUI Textblock.lineSpacing setter and getter to configure vertical space between lines in pixels or percentage values when working with text wrapping ([carloslanderas](https://github.com/carloslanderas))
@@ -17,8 +18,7 @@
    ([carloslanderas](https://github.com/carloslanderas))
    ([carloslanderas](https://github.com/carloslanderas))
 - VRHelper now exposes onNewMeshPicked observable that will notify a PickingInfo object after meshSelectionPredicate evaluation
 - VRHelper now exposes onNewMeshPicked observable that will notify a PickingInfo object after meshSelectionPredicate evaluation
    ([carloslanderas](https://github.com/carloslanderas))
    ([carloslanderas](https://github.com/carloslanderas))
-  
-  
+- `AssetsManager` will now clear its `tasks` lsit from all successfully loaded tasks ([deltakosh](https://github.com/deltakosh))
 
 
 ## Bug fixes
 ## Bug fixes
 
 

+ 7 - 6
inspector/src/Inspector.ts

@@ -39,15 +39,15 @@ module INSPECTOR {
         }) {
         }) {
 
 
             // Load GUI library if not already done
             // Load GUI library if not already done
-            if(!BABYLON.GUI){
-            	BABYLON.Tools.LoadScript("https://preview.babylonjs.com/gui/babylon.gui.js", () => { 
+            if (!BABYLON.GUI) {
+                BABYLON.Tools.LoadScript("https://preview.babylonjs.com/gui/babylon.gui.js", () => {
                     //Load properties of GUI objects now as BABYLON.GUI has to be declared before 
                     //Load properties of GUI objects now as BABYLON.GUI has to be declared before 
                     loadGUIProperties();
                     loadGUIProperties();
                 }, () => {
                 }, () => {
                     console.warn("Please add script https://preview.babylonjs.com/gui/babylon.gui.js to the HTML file")
                     console.warn("Please add script https://preview.babylonjs.com/gui/babylon.gui.js to the HTML file")
                 });
                 });
             }
             }
-            else{
+            else {
                 //Load properties of GUI objects now as BABYLON.GUI has to be declared before 
                 //Load properties of GUI objects now as BABYLON.GUI has to be declared before 
                 loadGUIProperties();
                 loadGUIProperties();
             }
             }
@@ -139,7 +139,7 @@ module INSPECTOR {
                             this._c2diwrapper.style.maxWidth = `${widthPx - leftPx}px`;
                             this._c2diwrapper.style.maxWidth = `${widthPx - leftPx}px`;
                         }
                         }
                     }
                     }
-                    
+
 
 
                     // Check if the parent of the canvas is the body page. If yes, the size ratio is computed
                     // Check if the parent of the canvas is the body page. If yes, the size ratio is computed
                     let parent = this._getRelativeParent(canvas);
                     let parent = this._getRelativeParent(canvas);
@@ -357,6 +357,7 @@ module INSPECTOR {
                     }
                     }
                 }
                 }
             }
             }
+            Scheduler.getInstance().dispose();
         }
         }
 
 
         /** Open the inspector in a new popup
         /** Open the inspector in a new popup
@@ -412,8 +413,8 @@ module INSPECTOR {
             }
             }
         }
         }
 
 
-        public getActiveTabIndex():number {
-           return this._tabbar.getActiveTabIndex();
+        public getActiveTabIndex(): number {
+            return this._tabbar.getActiveTabIndex();
         }
         }
     }
     }
 }
 }

+ 0 - 1
inspector/src/adapters/MeshAdapter.ts

@@ -10,7 +10,6 @@ module INSPECTOR {
 
 
         constructor(mesh: BABYLON.Node) {
         constructor(mesh: BABYLON.Node) {
             super(mesh);
             super(mesh);
-            new BABYLON.Debug.AxesViewer(mesh.getScene());
         }
         }
 
 
         /** Returns the name displayed in the tree */
         /** Returns the name displayed in the tree */

+ 12 - 6
inspector/src/scheduler/Scheduler.ts

@@ -13,11 +13,13 @@ module INSPECTOR {
         /** The list of data to update */
         /** The list of data to update */
         private _updatableProperties: Array<PropertyLine> = [];
         private _updatableProperties: Array<PropertyLine> = [];
 
 
-        constructor () {
-            setInterval(this._update.bind(this), Scheduler.REFRESH_TIME);
+        private interval: number;
+
+        constructor() {
+            this.interval = setInterval(this._update.bind(this), Scheduler.REFRESH_TIME);
         }
         }
 
 
-        public static getInstance() : Scheduler {
+        public static getInstance(): Scheduler {
             if (!Scheduler._instance) {
             if (!Scheduler._instance) {
                 Scheduler._instance = new Scheduler();
                 Scheduler._instance = new Scheduler();
             }
             }
@@ -25,12 +27,12 @@ module INSPECTOR {
         }
         }
 
 
         /** Add a property line to be updated every X ms */
         /** Add a property line to be updated every X ms */
-        public add(prop:PropertyLine) {
+        public add(prop: PropertyLine) {
             this._updatableProperties.push(prop);
             this._updatableProperties.push(prop);
         }
         }
-        
+
         /** Removes the given property from the list of properties to update */
         /** Removes the given property from the list of properties to update */
-        public remove(prop:PropertyLine) {
+        public remove(prop: PropertyLine) {
             let index = this._updatableProperties.indexOf(prop);
             let index = this._updatableProperties.indexOf(prop);
             if (index != -1) {
             if (index != -1) {
                 this._updatableProperties.splice(index, 1);
                 this._updatableProperties.splice(index, 1);
@@ -45,5 +47,9 @@ module INSPECTOR {
                 }
                 }
             }
             }
         }
         }
+
+        public dispose() {
+            window.clearInterval(this.interval);
+        }
     }
     }
 }
 }

+ 11 - 13
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -253,6 +253,10 @@ module BABYLON.GLTF2 {
                 return;
                 return;
             }
             }
 
 
+            for (const animation of animations) {
+                animation.babylonAnimationGroup.normalize();
+            }
+
             switch (this.animationStartMode) {
             switch (this.animationStartMode) {
                 case GLTFLoaderAnimationStartMode.NONE: {
                 case GLTFLoaderAnimationStartMode.NONE: {
                     // do nothing
                     // do nothing
@@ -260,16 +264,12 @@ module BABYLON.GLTF2 {
                 }
                 }
                 case GLTFLoaderAnimationStartMode.FIRST: {
                 case GLTFLoaderAnimationStartMode.FIRST: {
                     const animation = animations[0];
                     const animation = animations[0];
-                    for (const target of animation.targets) {
-                        this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                    }
+                    animation.babylonAnimationGroup.start(true);
                     break;
                     break;
                 }
                 }
                 case GLTFLoaderAnimationStartMode.ALL: {
                 case GLTFLoaderAnimationStartMode.ALL: {
                     for (const animation of animations) {
                     for (const animation of animations) {
-                        for (const target of animation.targets) {
-                            this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                        }
+                        animation.babylonAnimationGroup.start(true);
                     }
                     }
                     break;
                     break;
                 }
                 }
@@ -941,7 +941,7 @@ module BABYLON.GLTF2 {
         }
         }
 
 
         private _loadAnimation(context: string, animation: IGLTFAnimation): void {
         private _loadAnimation(context: string, animation: IGLTFAnimation): void {
-            animation.targets = [];
+            animation.babylonAnimationGroup = new AnimationGroup(animation.name || "animation" + animation.index, this._babylonScene);
 
 
             for (let index = 0; index < animation.channels.length; index++) {
             for (let index = 0; index < animation.channels.length; index++) {
                 const channel = GLTFLoader._GetProperty(animation.channels, index);
                 const channel = GLTFLoader._GetProperty(animation.channels, index);
@@ -1096,7 +1096,7 @@ module BABYLON.GLTF2 {
 
 
                     for (let targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
                     for (let targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
                         const morphTarget = morphTargetManager.getTarget(targetIndex);
                         const morphTarget = morphTargetManager.getTarget(targetIndex);
-                        const animationName = (animation.name || "anim" + animation.index) + "_" + targetIndex;
+                        const animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                         const babylonAnimation = new Animation(animationName, targetPath, 1, animationType);
                         const babylonAnimation = new Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys.map(key => ({
                         babylonAnimation.setKeys(keys.map(key => ({
                             frame: key.frame,
                             frame: key.frame,
@@ -1105,19 +1105,17 @@ module BABYLON.GLTF2 {
                             outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                         })));
                         })));
 
 
-                        morphTarget.animations.push(babylonAnimation);
-                        animation.targets.push(morphTarget);
+                        animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
                     }
                     }
                 }
                 }
                 else {
                 else {
-                    const animationName = animation.name || "anim" + animation.index;
+                    const animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                     const babylonAnimation = new Animation(animationName, targetPath, 1, animationType);
                     const babylonAnimation = new Animation(animationName, targetPath, 1, animationType);
                     babylonAnimation.setKeys(keys);
                     babylonAnimation.setKeys(keys);
 
 
                     if (targetNode.babylonAnimationTargets) {
                     if (targetNode.babylonAnimationTargets) {
                         for (const target of targetNode.babylonAnimationTargets) {
                         for (const target of targetNode.babylonAnimationTargets) {
-                            target.animations.push(babylonAnimation.clone());
-                            animation.targets.push(target);
+                            animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, target);
                         }
                         }
                     }
                     }
                 }
                 }

+ 1 - 1
loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts

@@ -109,7 +109,7 @@ module BABYLON.GLTF2 {
 
 
         // Runtime values
         // Runtime values
         index: number;
         index: number;
-        targets: any[];
+        babylonAnimationGroup: AnimationGroup;
     }
     }
 
 
     export interface IGLTFAsset extends IGLTFChildRootProperty {
     export interface IGLTFAsset extends IGLTFChildRootProperty {

+ 22 - 22
materialsLibrary/src/cell/babylon.cellMaterial.ts

@@ -39,16 +39,16 @@ module BABYLON {
         public _computeHighLevel: boolean = false;
         public _computeHighLevel: boolean = false;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         public computeHighLevel: boolean;
         public computeHighLevel: boolean;
-        
+
         @serialize("disableLighting")
         @serialize("disableLighting")
         private _disableLighting = false;
         private _disableLighting = false;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;   
-        
+        public disableLighting: boolean;
+
         @serialize("maxSimultaneousLights")
         @serialize("maxSimultaneousLights")
         private _maxSimultaneousLights = 4;
         private _maxSimultaneousLights = 4;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number; 
+        public maxSimultaneousLights: number;
 
 
         private _renderId: number;
         private _renderId: number;
 
 
@@ -69,7 +69,7 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
             if (this.isFrozen) {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
@@ -102,7 +102,7 @@ module BABYLON {
                             defines._needUVs = true;
                             defines._needUVs = true;
                             defines.DIFFUSE = true;
                             defines.DIFFUSE = true;
                         }
                         }
-                    }                
+                    }
                 }
                 }
             }
             }
 
 
@@ -116,8 +116,8 @@ module BABYLON {
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-            
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+
             // Attribs
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
@@ -127,13 +127,13 @@ module BABYLON {
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
-                var fallbacks = new EffectFallbacks();             
+                var fallbacks = new EffectFallbacks();
                 if (defines.FOG) {
                 if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
-                
+
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
@@ -163,19 +163,19 @@ module BABYLON {
                 var shaderName = "cell";
                 var shaderName = "cell";
                 var join = defines.toString();
                 var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
-                                "vFogInfos", "vFogColor", "pointSize",
-                                "vDiffuseInfos", 
-                                "mBones",
-                                "vClipPlane", "diffuseMatrix"
+                    "vFogInfos", "vFogColor", "pointSize",
+                    "vDiffuseInfos",
+                    "mBones",
+                    "vClipPlane", "diffuseMatrix"
                 ];
                 ];
                 var samplers = ["diffuseSampler"];
                 var samplers = ["diffuseSampler"];
                 var uniformBuffers = new Array<string>()
                 var uniformBuffers = new Array<string>()
 
 
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms, 
+                    uniformsNames: uniforms,
                     uniformBuffersNames: uniformBuffers,
                     uniformBuffersNames: uniformBuffers,
-                    samplers: samplers, 
-                    defines: defines, 
+                    samplers: samplers,
+                    defines: defines,
                     maxSimultaneousLights: this.maxSimultaneousLights
                     maxSimultaneousLights: this.maxSimultaneousLights
                 });
                 });
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
@@ -231,7 +231,7 @@ module BABYLON {
                     this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
                     this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
                     this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
                     this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
                 }
                 }
-                
+
                 // Clip plane
                 // Clip plane
                 MaterialHelper.BindClipPlane(this._activeEffect, scene);
                 MaterialHelper.BindClipPlane(this._activeEffect, scene);
 
 
@@ -240,14 +240,14 @@ module BABYLON {
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                MaterialHelper.BindEyePosition(effect, scene);               
+                MaterialHelper.BindEyePosition(effect, scene);
             }
             }
 
 
             this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
 
 
             // Lights
             // Lights
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights);          
+                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights);
             }
             }
 
 
             // View
             // View
@@ -304,7 +304,7 @@ module BABYLON {
         public clone(name: string): CellMaterial {
         public clone(name: string): CellMaterial {
             return SerializationHelper.Clone<CellMaterial>(() => new CellMaterial(name, this.getScene()), this);
             return SerializationHelper.Clone<CellMaterial>(() => new CellMaterial(name, this.getScene()), this);
         }
         }
-        
+
         public serialize(): any {
         public serialize(): any {
             var serializationObject = SerializationHelper.Serialize(this);
             var serializationObject = SerializationHelper.Serialize(this);
             serializationObject.customType = "BABYLON.CellMaterial";
             serializationObject.customType = "BABYLON.CellMaterial";
@@ -316,5 +316,5 @@ module BABYLON {
             return SerializationHelper.Parse(() => new CellMaterial(source.name, scene), source, scene, rootUrl);
             return SerializationHelper.Parse(() => new CellMaterial(source.name, scene), source, scene, rootUrl);
         }
         }
     }
     }
-} 
+}
 
 

+ 5 - 1
materialsLibrary/src/custom/babylon.customMaterial.ts

@@ -423,6 +423,10 @@ module BABYLON {
             this._imageProcessingConfiguration.colorGradingTexture = value;
             this._imageProcessingConfiguration.colorGradingTexture = value;
         }
         }
 
 
+        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean {
+            return (!this.needAlphaBlendingForMesh(mesh) && this.needAlphaTesting());
+        }
+
         public customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines_OldVer) => string;
         public customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines_OldVer) => string;
 
 
         protected _renderTargets = new SmartArray<RenderTargetTexture>(16);
         protected _renderTargets = new SmartArray<RenderTargetTexture>(16);
@@ -721,7 +725,7 @@ module BABYLON {
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
 
 
             // Get correct effect      
             // Get correct effect      
             if (defines.isDirty) {
             if (defines.isDirty) {

+ 54 - 54
materialsLibrary/src/fire/babylon.fireMaterial.ts

@@ -26,24 +26,24 @@ module BABYLON {
         @serializeAsTexture("diffuseTexture")
         @serializeAsTexture("diffuseTexture")
         private _diffuseTexture: Nullable<BaseTexture>;
         private _diffuseTexture: Nullable<BaseTexture>;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTexture: Nullable<BaseTexture>;        
-        
+        public diffuseTexture: Nullable<BaseTexture>;
+
         @serializeAsTexture("distortionTexture")
         @serializeAsTexture("distortionTexture")
         private _distortionTexture: Nullable<BaseTexture>;
         private _distortionTexture: Nullable<BaseTexture>;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public distortionTexture: Nullable<BaseTexture>;       
-        
+        public distortionTexture: Nullable<BaseTexture>;
+
         @serializeAsTexture("opacityTexture")
         @serializeAsTexture("opacityTexture")
         private _opacityTexture: Nullable<BaseTexture>;
         private _opacityTexture: Nullable<BaseTexture>;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         public opacityTexture: Nullable<BaseTexture>;
         public opacityTexture: Nullable<BaseTexture>;
-        
+
         @serializeAsColor3("diffuse")
         @serializeAsColor3("diffuse")
         public diffuseColor = new Color3(1, 1, 1);
         public diffuseColor = new Color3(1, 1, 1);
-        
+
         @serialize()
         @serialize()
         public speed = 1.0;
         public speed = 1.0;
-        
+
         private _scaledDiffuse = new Color3();
         private _scaledDiffuse = new Color3();
         private _renderId: number;
         private _renderId: number;
         private _lastTime: number = 0;
         private _lastTime: number = 0;
@@ -65,7 +65,7 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
             if (this.isFrozen) {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
@@ -97,7 +97,7 @@ module BABYLON {
                         defines._needUVs = true;
                         defines._needUVs = true;
                         defines.DIFFUSE = true;
                         defines.DIFFUSE = true;
                     }
                     }
-                }              
+                }
             }
             }
 
 
             // Misc.
             // Misc.
@@ -105,10 +105,10 @@ module BABYLON {
                 defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
                 defines.POINTSIZE = (this.pointsCloud || scene.forcePointsCloud);
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled);
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled);
             }
             }
-            
+
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-            
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+
             // Attribs
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
 
 
@@ -119,11 +119,11 @@ module BABYLON {
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
-                var fallbacks = new EffectFallbacks();             
+                var fallbacks = new EffectFallbacks();
                 if (defines.FOG) {
                 if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
-                
+
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
@@ -144,24 +144,24 @@ module BABYLON {
 
 
                 // Legacy browser patch
                 // Legacy browser patch
                 var shaderName = "fire";
                 var shaderName = "fire";
-                
+
                 var join = defines.toString();
                 var join = defines.toString();
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     {
                     {
                         attributes: attribs,
                         attributes: attribs,
                         uniformsNames: ["world", "view", "viewProjection", "vEyePosition",
                         uniformsNames: ["world", "view", "viewProjection", "vEyePosition",
-                                "vFogInfos", "vFogColor", "pointSize",
-                                "vDiffuseInfos", 
-                                "mBones",
-                                "vClipPlane", "diffuseMatrix",
-                                // Fire
-                                "time", "speed"
-                            ],
+                            "vFogInfos", "vFogColor", "pointSize",
+                            "vDiffuseInfos",
+                            "mBones",
+                            "vClipPlane", "diffuseMatrix",
+                            // Fire
+                            "time", "speed"
+                        ],
                         uniformBuffersNames: [],
                         uniformBuffersNames: [],
                         samplers: ["diffuseSampler",
                         samplers: ["diffuseSampler",
-                                // Fire
-                                "distortionSampler", "opacitySampler"
-                            ],
+                            // Fire
+                            "distortionSampler", "opacitySampler"
+                        ],
                         defines: join,
                         defines: join,
                         fallbacks: fallbacks,
                         fallbacks: fallbacks,
                         onCompiled: this.onCompiled,
                         onCompiled: this.onCompiled,
@@ -171,7 +171,7 @@ module BABYLON {
                         transformFeedbackVaryings: null
                         transformFeedbackVaryings: null
                     }, engine), defines);
                     }, engine), defines);
             }
             }
-            
+
             if (!subMesh.effect || !subMesh.effect.isReady()) {
             if (!subMesh.effect || !subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
@@ -210,11 +210,11 @@ module BABYLON {
 
 
                     this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
                     this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
                     this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
                     this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
-                    
+
                     this._activeEffect.setTexture("distortionSampler", this._distortionTexture);
                     this._activeEffect.setTexture("distortionSampler", this._distortionTexture);
                     this._activeEffect.setTexture("opacitySampler", this._opacityTexture);
                     this._activeEffect.setTexture("opacitySampler", this._opacityTexture);
                 }
                 }
-                
+
                 // Clip plane
                 // Clip plane
                 if (scene.clipPlane) {
                 if (scene.clipPlane) {
                     var clipPlane = scene.clipPlane;
                     var clipPlane = scene.clipPlane;
@@ -226,7 +226,7 @@ module BABYLON {
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                MaterialHelper.BindEyePosition(effect, scene);               
+                MaterialHelper.BindEyePosition(effect, scene);
             }
             }
 
 
             this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
             this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
@@ -235,14 +235,14 @@ module BABYLON {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
             if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
                 this._activeEffect.setMatrix("view", scene.getViewMatrix());
                 this._activeEffect.setMatrix("view", scene.getViewMatrix());
             }
             }
-            
+
             // Fog
             // Fog
             MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
             MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-            
+
             // Time
             // Time
             this._lastTime += scene.getEngine().getDeltaTime();
             this._lastTime += scene.getEngine().getDeltaTime();
             this._activeEffect.setFloat("time", this._lastTime);
             this._activeEffect.setFloat("time", this._lastTime);
-            
+
             // Speed
             // Speed
             this._activeEffect.setFloat("speed", this.speed);
             this._activeEffect.setFloat("speed", this.speed);
 
 
@@ -294,18 +294,18 @@ module BABYLON {
 
 
             if (this._distortionTexture === texture) {
             if (this._distortionTexture === texture) {
                 return true;
                 return true;
-            }    
+            }
 
 
             if (this._opacityTexture === texture) {
             if (this._opacityTexture === texture) {
                 return true;
                 return true;
-            }            
+            }
 
 
-            return false;    
-        }         
+            return false;
+        }
 
 
         public getClassName(): string {
         public getClassName(): string {
             return "FireMaterial";
             return "FireMaterial";
-        }        
+        }
 
 
         public dispose(forceDisposeEffect?: boolean): void {
         public dispose(forceDisposeEffect?: boolean): void {
             if (this._diffuseTexture) {
             if (this._diffuseTexture) {
@@ -321,23 +321,23 @@ module BABYLON {
         public clone(name: string): FireMaterial {
         public clone(name: string): FireMaterial {
             return SerializationHelper.Clone<FireMaterial>(() => new FireMaterial(name, this.getScene()), this);
             return SerializationHelper.Clone<FireMaterial>(() => new FireMaterial(name, this.getScene()), this);
         }
         }
-		
-		public serialize(): any {
-		
+
+        public serialize(): any {
+
             var serializationObject = super.serialize();
             var serializationObject = super.serialize();
-            serializationObject.customType      = "BABYLON.FireMaterial";
-            serializationObject.diffuseColor    = this.diffuseColor.asArray();
-            serializationObject.speed           = this.speed;
+            serializationObject.customType = "BABYLON.FireMaterial";
+            serializationObject.diffuseColor = this.diffuseColor.asArray();
+            serializationObject.speed = this.speed;
 
 
             if (this._diffuseTexture) {
             if (this._diffuseTexture) {
                 serializationObject._diffuseTexture = this._diffuseTexture.serialize();
                 serializationObject._diffuseTexture = this._diffuseTexture.serialize();
             }
             }
-            
-			if (this._distortionTexture) {
+
+            if (this._distortionTexture) {
                 serializationObject._distortionTexture = this._distortionTexture.serialize();
                 serializationObject._distortionTexture = this._distortionTexture.serialize();
             }
             }
-			
-			if (this._opacityTexture) {
+
+            if (this._opacityTexture) {
                 serializationObject._opacityTexture = this._opacityTexture.serialize();
                 serializationObject._opacityTexture = this._opacityTexture.serialize();
             }
             }
 
 
@@ -347,12 +347,12 @@ module BABYLON {
         public static Parse(source: any, scene: Scene, rootUrl: string): FireMaterial {
         public static Parse(source: any, scene: Scene, rootUrl: string): FireMaterial {
             var material = new FireMaterial(source.name, scene);
             var material = new FireMaterial(source.name, scene);
 
 
-            material.diffuseColor   = Color3.FromArray(source.diffuseColor);
-            material.speed          = source.speed;
+            material.diffuseColor = Color3.FromArray(source.diffuseColor);
+            material.speed = source.speed;
 
 
-            material.alpha          = source.alpha;
+            material.alpha = source.alpha;
 
 
-            material.id             = source.id;
+            material.id = source.id;
 
 
             Tags.AddTagsTo(material, source.tags);
             Tags.AddTagsTo(material, source.tags);
             material.backFaceCulling = source.backFaceCulling;
             material.backFaceCulling = source.backFaceCulling;
@@ -365,8 +365,8 @@ module BABYLON {
             if (source._distortionTexture) {
             if (source._distortionTexture) {
                 material._distortionTexture = Texture.Parse(source._distortionTexture, scene, rootUrl);
                 material._distortionTexture = Texture.Parse(source._distortionTexture, scene, rootUrl);
             }
             }
-			
-			if (source._opacityTexture) {
+
+            if (source._opacityTexture) {
                 material._opacityTexture = Texture.Parse(source._opacityTexture, scene, rootUrl);
                 material._opacityTexture = Texture.Parse(source._opacityTexture, scene, rootUrl);
             }
             }
 
 
@@ -377,5 +377,5 @@ module BABYLON {
             return material;
             return material;
         }
         }
     }
     }
-} 
+}
 
 

+ 73 - 73
materialsLibrary/src/fur/babylon.furMaterial.ts

@@ -26,75 +26,75 @@ module BABYLON {
     }
     }
 
 
     export class FurMaterial extends PushMaterial {
     export class FurMaterial extends PushMaterial {
-        
+
         @serializeAsTexture("diffuseTexture")
         @serializeAsTexture("diffuseTexture")
         private _diffuseTexture: BaseTexture;
         private _diffuseTexture: BaseTexture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         public diffuseTexture: BaseTexture;
         public diffuseTexture: BaseTexture;
-        
+
         @serializeAsTexture("heightTexture")
         @serializeAsTexture("heightTexture")
         private _heightTexture: BaseTexture;
         private _heightTexture: BaseTexture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public heightTexture: BaseTexture;        
-        
+        public heightTexture: BaseTexture;
+
         @serializeAsColor3()
         @serializeAsColor3()
         public diffuseColor = new Color3(1, 1, 1);
         public diffuseColor = new Color3(1, 1, 1);
-        
+
         @serialize()
         @serialize()
         public furLength: number = 1;
         public furLength: number = 1;
-        
+
         @serialize()
         @serialize()
         public furAngle: number = 0;
         public furAngle: number = 0;
-        
+
         @serializeAsColor3()
         @serializeAsColor3()
-        public furColor = new Color3(0.44,0.21,0.02);
-        
+        public furColor = new Color3(0.44, 0.21, 0.02);
+
         @serialize()
         @serialize()
         public furOffset: number = 0.0;
         public furOffset: number = 0.0;
-        
+
         @serialize()
         @serialize()
         public furSpacing: number = 12;
         public furSpacing: number = 12;
-        
+
         @serializeAsVector3()
         @serializeAsVector3()
         public furGravity = new Vector3(0, 0, 0);
         public furGravity = new Vector3(0, 0, 0);
-        
+
         @serialize()
         @serialize()
         public furSpeed: number = 100;
         public furSpeed: number = 100;
-        
+
         @serialize()
         @serialize()
         public furDensity: number = 20;
         public furDensity: number = 20;
-        
+
         public furTexture: DynamicTexture;
         public furTexture: DynamicTexture;
-        
-        
+
+
         @serialize("disableLighting")
         @serialize("disableLighting")
         private _disableLighting = false;
         private _disableLighting = false;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;   
-        
+        public disableLighting: boolean;
+
         @serialize("maxSimultaneousLights")
         @serialize("maxSimultaneousLights")
         private _maxSimultaneousLights = 4;
         private _maxSimultaneousLights = 4;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number; 
-        
+        public maxSimultaneousLights: number;
+
         @serialize()
         @serialize()
         public highLevelFur: boolean = true;
         public highLevelFur: boolean = true;
-               
+
         public _meshes: AbstractMesh[];
         public _meshes: AbstractMesh[];
 
 
         private _renderId: number;
         private _renderId: number;
-        
+
         private _furTime: number = 0;
         private _furTime: number = 0;
 
 
         constructor(name: string, scene: Scene) {
         constructor(name: string, scene: Scene) {
             super(name, scene);
             super(name, scene);
         }
         }
-        
+
         @serialize()
         @serialize()
         public get furTime() {
         public get furTime() {
             return this._furTime;
             return this._furTime;
         }
         }
-        
+
         public set furTime(furTime: number) {
         public set furTime(furTime: number) {
             this._furTime = furTime;
             this._furTime = furTime;
         }
         }
@@ -110,11 +110,11 @@ module BABYLON {
         public getAlphaTestTexture(): Nullable<BaseTexture> {
         public getAlphaTestTexture(): Nullable<BaseTexture> {
             return null;
             return null;
         }
         }
-        
+
         public updateFur(): void {
         public updateFur(): void {
             for (var i = 1; i < this._meshes.length; i++) {
             for (var i = 1; i < this._meshes.length; i++) {
                 var offsetFur = <FurMaterial>this._meshes[i].material;
                 var offsetFur = <FurMaterial>this._meshes[i].material;
-                
+
                 offsetFur.furLength = this.furLength;
                 offsetFur.furLength = this.furLength;
                 offsetFur.furAngle = this.furAngle;
                 offsetFur.furAngle = this.furAngle;
                 offsetFur.furGravity = this.furGravity;
                 offsetFur.furGravity = this.furGravity;
@@ -130,7 +130,7 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
             if (this.isFrozen) {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
@@ -162,7 +162,7 @@ module BABYLON {
                             defines._needUVs = true;
                             defines._needUVs = true;
                             defines.DIFFUSE = true;
                             defines.DIFFUSE = true;
                         }
                         }
-                    } 
+                    }
                     if (this.heightTexture && engine.getCaps().maxVertexTextureImageUnits) {
                     if (this.heightTexture && engine.getCaps().maxVertexTextureImageUnits) {
                         if (!this.heightTexture.isReady()) {
                         if (!this.heightTexture.isReady()) {
                             return false;
                             return false;
@@ -170,7 +170,7 @@ module BABYLON {
                             defines._needUVs = true;
                             defines._needUVs = true;
                             defines.HEIGHTMAP = true;
                             defines.HEIGHTMAP = true;
                         }
                         }
-                    }               
+                    }
                 }
                 }
             }
             }
 
 
@@ -187,8 +187,8 @@ module BABYLON {
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-            
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+
             // Attribs
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
@@ -199,13 +199,13 @@ module BABYLON {
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
-                var fallbacks = new EffectFallbacks();             
+                var fallbacks = new EffectFallbacks();
                 if (defines.FOG) {
                 if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
-             
+
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
@@ -237,7 +237,7 @@ module BABYLON {
                 var join = defines.toString();
                 var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
-                    "vDiffuseInfos", 
+                    "vDiffuseInfos",
                     "mBones",
                     "mBones",
                     "vClipPlane", "diffuseMatrix",
                     "vClipPlane", "diffuseMatrix",
                     "furLength", "furAngle", "furColor", "furOffset", "furGravity", "furTime", "furSpacing", "furDensity"
                     "furLength", "furAngle", "furColor", "furOffset", "furGravity", "furTime", "furSpacing", "furDensity"
@@ -245,17 +245,17 @@ module BABYLON {
                 var samplers = ["diffuseSampler",
                 var samplers = ["diffuseSampler",
                     "heightTexture", "furTexture"
                     "heightTexture", "furTexture"
                 ];
                 ];
-                
+
                 var uniformBuffers = new Array<string>()
                 var uniformBuffers = new Array<string>()
 
 
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms, 
+                    uniformsNames: uniforms,
                     uniformBuffersNames: uniformBuffers,
                     uniformBuffersNames: uniformBuffers,
-                    samplers: samplers, 
-                    defines: defines, 
+                    samplers: samplers,
+                    defines: defines,
                     maxSimultaneousLights: this.maxSimultaneousLights
                     maxSimultaneousLights: this.maxSimultaneousLights
                 });
                 });
-                
+
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     <EffectCreationOptions>{
                     <EffectCreationOptions>{
                         attributes: attribs,
                         attributes: attribs,
@@ -308,11 +308,11 @@ module BABYLON {
                     this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
                     this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
                     this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
                     this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
                 }
                 }
-                
+
                 if (this._heightTexture) {
                 if (this._heightTexture) {
                     this._activeEffect.setTexture("heightTexture", this._heightTexture);
                     this._activeEffect.setTexture("heightTexture", this._heightTexture);
                 }
                 }
-                
+
                 // Clip plane
                 // Clip plane
                 MaterialHelper.BindClipPlane(this._activeEffect, scene);
                 MaterialHelper.BindClipPlane(this._activeEffect, scene);
 
 
@@ -321,7 +321,7 @@ module BABYLON {
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                MaterialHelper.BindEyePosition(effect, scene);               
+                MaterialHelper.BindEyePosition(effect, scene);
             }
             }
 
 
             this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
@@ -337,23 +337,23 @@ module BABYLON {
 
 
             // Fog
             // Fog
             MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
             MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
-            
+
             this._activeEffect.setFloat("furLength", this.furLength);
             this._activeEffect.setFloat("furLength", this.furLength);
             this._activeEffect.setFloat("furAngle", this.furAngle);
             this._activeEffect.setFloat("furAngle", this.furAngle);
             this._activeEffect.setColor4("furColor", this.furColor, 1.0);
             this._activeEffect.setColor4("furColor", this.furColor, 1.0);
-            
+
             if (this.highLevelFur) {
             if (this.highLevelFur) {
                 this._activeEffect.setVector3("furGravity", this.furGravity);
                 this._activeEffect.setVector3("furGravity", this.furGravity);
                 this._activeEffect.setFloat("furOffset", this.furOffset);
                 this._activeEffect.setFloat("furOffset", this.furOffset);
                 this._activeEffect.setFloat("furSpacing", this.furSpacing);
                 this._activeEffect.setFloat("furSpacing", this.furSpacing);
                 this._activeEffect.setFloat("furDensity", this.furDensity);
                 this._activeEffect.setFloat("furDensity", this.furDensity);
-                
+
                 this._furTime += this.getScene().getEngine().getDeltaTime() / this.furSpeed;
                 this._furTime += this.getScene().getEngine().getDeltaTime() / this.furSpeed;
                 this._activeEffect.setFloat("furTime", this._furTime);
                 this._activeEffect.setFloat("furTime", this._furTime);
-                
+
                 this._activeEffect.setTexture("furTexture", this.furTexture);
                 this._activeEffect.setTexture("furTexture", this.furTexture);
             }
             }
- 
+
             this._afterBind(mesh, this._activeEffect);
             this._afterBind(mesh, this._activeEffect);
         }
         }
 
 
@@ -363,7 +363,7 @@ module BABYLON {
             if (this.diffuseTexture && this.diffuseTexture.animations && this.diffuseTexture.animations.length > 0) {
             if (this.diffuseTexture && this.diffuseTexture.animations && this.diffuseTexture.animations.length > 0) {
                 results.push(this.diffuseTexture);
                 results.push(this.diffuseTexture);
             }
             }
-            
+
             if (this.heightTexture && this.heightTexture.animations && this.heightTexture.animations.length > 0) {
             if (this.heightTexture && this.heightTexture.animations && this.heightTexture.animations.length > 0) {
                 results.push(this.heightTexture);
                 results.push(this.heightTexture);
             }
             }
@@ -396,16 +396,16 @@ module BABYLON {
 
 
             if (this._heightTexture === texture) {
             if (this._heightTexture === texture) {
                 return true;
                 return true;
-            }        
+            }
 
 
-            return false;    
-        }        
+            return false;
+        }
 
 
         public dispose(forceDisposeEffect?: boolean): void {
         public dispose(forceDisposeEffect?: boolean): void {
             if (this.diffuseTexture) {
             if (this.diffuseTexture) {
                 this.diffuseTexture.dispose();
                 this.diffuseTexture.dispose();
             }
             }
-            
+
             if (this._meshes) {
             if (this._meshes) {
                 for (var i = 1; i < this._meshes.length; i++) {
                 for (var i = 1; i < this._meshes.length; i++) {
                     let mat = this._meshes[i].material;
                     let mat = this._meshes[i].material;
@@ -419,7 +419,7 @@ module BABYLON {
 
 
             super.dispose(forceDisposeEffect);
             super.dispose(forceDisposeEffect);
         }
         }
-        
+
         public clone(name: string): FurMaterial {
         public clone(name: string): FurMaterial {
             return SerializationHelper.Clone(() => new FurMaterial(name, this.getScene()), this);
             return SerializationHelper.Clone(() => new FurMaterial(name, this.getScene()), this);
         }
         }
@@ -427,23 +427,23 @@ module BABYLON {
         public serialize(): any {
         public serialize(): any {
             var serializationObject = SerializationHelper.Serialize(this);
             var serializationObject = SerializationHelper.Serialize(this);
             serializationObject.customType = "BABYLON.FurMaterial";
             serializationObject.customType = "BABYLON.FurMaterial";
-            
+
             if (this._meshes) {
             if (this._meshes) {
                 serializationObject.sourceMeshName = this._meshes[0].name;
                 serializationObject.sourceMeshName = this._meshes[0].name;
                 serializationObject.quality = this._meshes.length;
                 serializationObject.quality = this._meshes.length;
             }
             }
-            
+
             return serializationObject;
             return serializationObject;
         }
         }
 
 
         public getClassName(): string {
         public getClassName(): string {
             return "FurMaterial";
             return "FurMaterial";
-        }          
+        }
 
 
         // Statics
         // Statics
         public static Parse(source: any, scene: Scene, rootUrl: string): FurMaterial {
         public static Parse(source: any, scene: Scene, rootUrl: string): FurMaterial {
             var material = SerializationHelper.Parse(() => new FurMaterial(source.name, scene), source, scene, rootUrl);
             var material = SerializationHelper.Parse(() => new FurMaterial(source.name, scene), source, scene, rootUrl);
-            
+
             if (source.sourceMeshName && material.highLevelFur) {
             if (source.sourceMeshName && material.highLevelFur) {
                 scene.executeWhenReady(() => {
                 scene.executeWhenReady(() => {
                     var sourceMesh = <Mesh>scene.getMeshByName(source.sourceMeshName);
                     var sourceMesh = <Mesh>scene.getMeshByName(source.sourceMeshName);
@@ -454,27 +454,27 @@ module BABYLON {
                     }
                     }
                 });
                 });
             }
             }
-            
+
             return material;
             return material;
         }
         }
-        
+
         public static GenerateTexture(name: string, scene: Scene): DynamicTexture {
         public static GenerateTexture(name: string, scene: Scene): DynamicTexture {
             // Generate fur textures
             // Generate fur textures
             var texture = new DynamicTexture("FurTexture " + name, 256, scene, true);
             var texture = new DynamicTexture("FurTexture " + name, 256, scene, true);
             var context = texture.getContext();
             var context = texture.getContext();
-            
-            for ( var i = 0; i < 20000; ++i ) {
+
+            for (var i = 0; i < 20000; ++i) {
                 context.fillStyle = "rgba(255, " + Math.floor(Math.random() * 255) + ", " + Math.floor(Math.random() * 255) + ", 1)";
                 context.fillStyle = "rgba(255, " + Math.floor(Math.random() * 255) + ", " + Math.floor(Math.random() * 255) + ", 1)";
                 context.fillRect((Math.random() * texture.getSize().width), (Math.random() * texture.getSize().height), 2, 2);
                 context.fillRect((Math.random() * texture.getSize().width), (Math.random() * texture.getSize().height), 2, 2);
             }
             }
-            
+
             texture.update(false);
             texture.update(false);
             texture.wrapU = Texture.WRAP_ADDRESSMODE;
             texture.wrapU = Texture.WRAP_ADDRESSMODE;
             texture.wrapV = Texture.WRAP_ADDRESSMODE;
             texture.wrapV = Texture.WRAP_ADDRESSMODE;
-            
+
             return texture;
             return texture;
         }
         }
-        
+
         // Creates and returns an array of meshes used as shells for the Fur Material
         // Creates and returns an array of meshes used as shells for the Fur Material
         // that can be disposed later in your code
         // that can be disposed later in your code
         // The quality is in interval [0, 100]
         // The quality is in interval [0, 100]
@@ -482,17 +482,17 @@ module BABYLON {
             var meshes = [sourceMesh];
             var meshes = [sourceMesh];
             var mat: FurMaterial = <FurMaterial>sourceMesh.material;
             var mat: FurMaterial = <FurMaterial>sourceMesh.material;
             var i;
             var i;
-            
+
             if (!(mat instanceof FurMaterial)) {
             if (!(mat instanceof FurMaterial)) {
                 throw "The material of the source mesh must be a Fur Material";
                 throw "The material of the source mesh must be a Fur Material";
             }
             }
-            
+
             for (i = 1; i < quality; i++) {
             for (i = 1; i < quality; i++) {
                 var offsetFur = new BABYLON.FurMaterial(mat.name + i, sourceMesh.getScene());
                 var offsetFur = new BABYLON.FurMaterial(mat.name + i, sourceMesh.getScene());
                 sourceMesh.getScene().materials.pop();
                 sourceMesh.getScene().materials.pop();
                 Tags.EnableFor(offsetFur);
                 Tags.EnableFor(offsetFur);
                 Tags.AddTagsTo(offsetFur, "furShellMaterial");
                 Tags.AddTagsTo(offsetFur, "furShellMaterial");
-                
+
                 offsetFur.furLength = mat.furLength;
                 offsetFur.furLength = mat.furLength;
                 offsetFur.furAngle = mat.furAngle;
                 offsetFur.furAngle = mat.furAngle;
                 offsetFur.furGravity = mat.furGravity;
                 offsetFur.furGravity = mat.furGravity;
@@ -505,23 +505,23 @@ module BABYLON {
                 offsetFur.highLevelFur = mat.highLevelFur;
                 offsetFur.highLevelFur = mat.highLevelFur;
                 offsetFur.furTime = mat.furTime;
                 offsetFur.furTime = mat.furTime;
                 offsetFur.furDensity = mat.furDensity;
                 offsetFur.furDensity = mat.furDensity;
-                
+
                 var offsetMesh = sourceMesh.clone(sourceMesh.name + i);
                 var offsetMesh = sourceMesh.clone(sourceMesh.name + i);
-                
+
                 offsetMesh.material = offsetFur;
                 offsetMesh.material = offsetFur;
                 offsetMesh.skeleton = sourceMesh.skeleton;
                 offsetMesh.skeleton = sourceMesh.skeleton;
                 offsetMesh.position = Vector3.Zero();
                 offsetMesh.position = Vector3.Zero();
                 meshes.push(offsetMesh);
                 meshes.push(offsetMesh);
             }
             }
-            
+
             for (i = 1; i < meshes.length; i++) {
             for (i = 1; i < meshes.length; i++) {
                 meshes[i].parent = sourceMesh;
                 meshes[i].parent = sourceMesh;
             }
             }
-            
+
             (<FurMaterial>sourceMesh.material)._meshes = meshes;
             (<FurMaterial>sourceMesh.material)._meshes = meshes;
-            
+
             return meshes;
             return meshes;
         }
         }
     }
     }
-} 
+}
 
 

+ 19 - 19
materialsLibrary/src/gradient/babylon.gradientMaterial.ts

@@ -27,7 +27,7 @@ module BABYLON {
         public POINTLIGHT0 = false;
         public POINTLIGHT0 = false;
         public POINTLIGHT1 = false;
         public POINTLIGHT1 = false;
         public POINTLIGHT2 = false;
         public POINTLIGHT2 = false;
-        public POINTLIGHT3 = false;        
+        public POINTLIGHT3 = false;
         public SHADOW0 = false;
         public SHADOW0 = false;
         public SHADOW1 = false;
         public SHADOW1 = false;
         public SHADOW2 = false;
         public SHADOW2 = false;
@@ -57,30 +57,30 @@ module BABYLON {
     }
     }
 
 
     export class GradientMaterial extends PushMaterial {
     export class GradientMaterial extends PushMaterial {
-          
+
         @serialize("maxSimultaneousLights")
         @serialize("maxSimultaneousLights")
         private _maxSimultaneousLights = 4;
         private _maxSimultaneousLights = 4;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number;       
+        public maxSimultaneousLights: number;
 
 
         // The gradient top color, red by default
         // The gradient top color, red by default
         @serializeAsColor3()
         @serializeAsColor3()
         public topColor = new Color3(1, 0, 0);
         public topColor = new Color3(1, 0, 0);
-        
+
         @serialize()
         @serialize()
         public topColorAlpha = 1.0;
         public topColorAlpha = 1.0;
 
 
         // The gradient top color, blue by default
         // The gradient top color, blue by default
         @serializeAsColor3()
         @serializeAsColor3()
         public bottomColor = new Color3(0, 0, 1);
         public bottomColor = new Color3(0, 0, 1);
-        
+
         @serialize()
         @serialize()
         public bottomColorAlpha = 1.0;
         public bottomColorAlpha = 1.0;
 
 
         // Gradient offset
         // Gradient offset
         @serialize()
         @serialize()
         public offset = 0;
         public offset = 0;
-        
+
         @serialize()
         @serialize()
         public smoothness = 1.0;
         public smoothness = 1.0;
 
 
@@ -106,7 +106,7 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
             if (this.isFrozen) {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
@@ -128,7 +128,7 @@ module BABYLON {
 
 
             var engine = scene.getEngine();
             var engine = scene.getEngine();
 
 
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
 
 
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
 
 
@@ -144,13 +144,13 @@ module BABYLON {
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
-                var fallbacks = new EffectFallbacks();             
+                var fallbacks = new EffectFallbacks();
                 if (defines.FOG) {
                 if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
-             
+
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
@@ -184,7 +184,7 @@ module BABYLON {
 
 
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
-                    "vDiffuseInfos", 
+                    "vDiffuseInfos",
                     "mBones",
                     "mBones",
                     "vClipPlane", "diffuseMatrix",
                     "vClipPlane", "diffuseMatrix",
                     "topColor", "bottomColor", "offset", "smoothness"
                     "topColor", "bottomColor", "offset", "smoothness"
@@ -193,13 +193,13 @@ module BABYLON {
                 var uniformBuffers = new Array<string>();
                 var uniformBuffers = new Array<string>();
 
 
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms, 
+                    uniformsNames: uniforms,
                     uniformBuffersNames: uniformBuffers,
                     uniformBuffersNames: uniformBuffers,
-                    samplers: samplers, 
-                    defines: defines, 
+                    samplers: samplers,
+                    defines: defines,
                     maxSimultaneousLights: 4
                     maxSimultaneousLights: 4
                 });
                 });
-                
+
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     <EffectCreationOptions>{
                     <EffectCreationOptions>{
                         attributes: attribs,
                         attributes: attribs,
@@ -237,7 +237,7 @@ module BABYLON {
             }
             }
 
 
             this._activeEffect = effect;
             this._activeEffect = effect;
-            
+
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
             this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
             this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
@@ -254,7 +254,7 @@ module BABYLON {
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                MaterialHelper.BindEyePosition(effect, scene);              
+                MaterialHelper.BindEyePosition(effect, scene);
             }
             }
 
 
             this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
             this._activeEffect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
@@ -300,12 +300,12 @@ module BABYLON {
 
 
         public getClassName(): string {
         public getClassName(): string {
             return "GradientMaterial";
             return "GradientMaterial";
-        }              
+        }
 
 
         // Statics
         // Statics
         public static Parse(source: any, scene: Scene, rootUrl: string): GradientMaterial {
         public static Parse(source: any, scene: Scene, rootUrl: string): GradientMaterial {
             return SerializationHelper.Parse(() => new GradientMaterial(source.name, scene), source, scene, rootUrl);
             return SerializationHelper.Parse(() => new GradientMaterial(source.name, scene), source, scene, rootUrl);
         }
         }
     }
     }
-} 
+}
 
 

+ 29 - 29
materialsLibrary/src/lava/babylon.lavaMaterial.ts

@@ -61,39 +61,39 @@ module BABYLON {
         private _diffuseTexture: BaseTexture;
         private _diffuseTexture: BaseTexture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         public diffuseTexture: BaseTexture;
         public diffuseTexture: BaseTexture;
-        
+
         @serializeAsTexture()
         @serializeAsTexture()
         public noiseTexture: BaseTexture;
         public noiseTexture: BaseTexture;
-        
+
         @serializeAsColor3()
         @serializeAsColor3()
         public fogColor: Color3;
         public fogColor: Color3;
-        
+
         @serialize()
         @serialize()
-        public speed : number = 1;
-        
+        public speed: number = 1;
+
         @serialize()
         @serialize()
-        public movingSpeed : number = 1;
-        
+        public movingSpeed: number = 1;
+
         @serialize()
         @serialize()
-        public lowFrequencySpeed : number = 1;
-        
+        public lowFrequencySpeed: number = 1;
+
         @serialize()
         @serialize()
-        public fogDensity : number = 0.15;
+        public fogDensity: number = 0.15;
 
 
-        private _lastTime : number = 0;
+        private _lastTime: number = 0;
 
 
         @serializeAsColor3()
         @serializeAsColor3()
         public diffuseColor = new Color3(1, 1, 1);
         public diffuseColor = new Color3(1, 1, 1);
-        
+
         @serialize("disableLighting")
         @serialize("disableLighting")
         private _disableLighting = false;
         private _disableLighting = false;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;   
+        public disableLighting: boolean;
 
 
         @serialize("maxSimultaneousLights")
         @serialize("maxSimultaneousLights")
         private _maxSimultaneousLights = 4;
         private _maxSimultaneousLights = 4;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number; 
+        public maxSimultaneousLights: number;
 
 
         private _scaledDiffuse = new Color3();
         private _scaledDiffuse = new Color3();
         private _renderId: number;
         private _renderId: number;
@@ -115,7 +115,7 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
             if (this.isFrozen) {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
@@ -148,19 +148,19 @@ module BABYLON {
                             defines._needUVs = true;
                             defines._needUVs = true;
                             defines.DIFFUSE = true;
                             defines.DIFFUSE = true;
                         }
                         }
-                    }                
+                    }
                 }
                 }
             }
             }
 
 
-               // Misc.
+            // Misc.
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
 
 
             // Lights
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-            
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+
             // Attribs
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
@@ -212,8 +212,8 @@ module BABYLON {
                     "vDiffuseInfos",
                     "vDiffuseInfos",
                     "mBones",
                     "mBones",
                     "vClipPlane", "diffuseMatrix",
                     "vClipPlane", "diffuseMatrix",
-                    "time", "speed","movingSpeed",
-                    "fogColor","fogDensity", "lowFrequencySpeed"
+                    "time", "speed", "movingSpeed",
+                    "fogColor", "fogDensity", "lowFrequencySpeed"
                 ];
                 ];
 
 
                 var samplers = ["diffuseSampler",
                 var samplers = ["diffuseSampler",
@@ -222,10 +222,10 @@ module BABYLON {
                 var uniformBuffers = new Array<string>()
                 var uniformBuffers = new Array<string>()
 
 
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms, 
+                    uniformsNames: uniforms,
                     uniformBuffersNames: uniformBuffers,
                     uniformBuffersNames: uniformBuffers,
-                    samplers: samplers, 
-                    defines: defines, 
+                    samplers: samplers,
+                    defines: defines,
                     maxSimultaneousLights: this.maxSimultaneousLights
                     maxSimultaneousLights: this.maxSimultaneousLights
                 });
                 });
 
 
@@ -248,7 +248,7 @@ module BABYLON {
 
 
             this._renderId = scene.getRenderId();
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
             this._wasPreviouslyReady = true;
-            
+
             return true;
             return true;
         }
         }
 
 
@@ -316,7 +316,7 @@ module BABYLON {
             this._lastTime += scene.getEngine().getDeltaTime();
             this._lastTime += scene.getEngine().getDeltaTime();
             this._activeEffect.setFloat("time", this._lastTime * this.speed / 1000);
             this._activeEffect.setFloat("time", this._lastTime * this.speed / 1000);
 
 
-            if (! this.fogColor) {
+            if (!this.fogColor) {
                 this.fogColor = Color3.Black();
                 this.fogColor = Color3.Black();
             }
             }
             this._activeEffect.setColor3("fogColor", this.fogColor);
             this._activeEffect.setColor3("fogColor", this.fogColor);
@@ -360,9 +360,9 @@ module BABYLON {
             if (this.diffuseTexture === texture) {
             if (this.diffuseTexture === texture) {
                 return true;
                 return true;
             }
             }
-            
-            return false;    
-        }        
+
+            return false;
+        }
 
 
         public dispose(forceDisposeEffect?: boolean): void {
         public dispose(forceDisposeEffect?: boolean): void {
             if (this.diffuseTexture) {
             if (this.diffuseTexture) {

+ 23 - 23
materialsLibrary/src/normal/babylon.normalMaterial.ts

@@ -27,7 +27,7 @@ module BABYLON {
         public POINTLIGHT0 = false;
         public POINTLIGHT0 = false;
         public POINTLIGHT1 = false;
         public POINTLIGHT1 = false;
         public POINTLIGHT2 = false;
         public POINTLIGHT2 = false;
-        public POINTLIGHT3 = false;        
+        public POINTLIGHT3 = false;
         public SHADOW0 = false;
         public SHADOW0 = false;
         public SHADOW1 = false;
         public SHADOW1 = false;
         public SHADOW2 = false;
         public SHADOW2 = false;
@@ -64,16 +64,16 @@ module BABYLON {
 
 
         @serializeAsColor3()
         @serializeAsColor3()
         public diffuseColor = new Color3(1, 1, 1);
         public diffuseColor = new Color3(1, 1, 1);
-        
+
         @serialize("disableLighting")
         @serialize("disableLighting")
         private _disableLighting = false;
         private _disableLighting = false;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;   
-        
+        public disableLighting: boolean;
+
         @serialize("maxSimultaneousLights")
         @serialize("maxSimultaneousLights")
         private _maxSimultaneousLights = 4;
         private _maxSimultaneousLights = 4;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number; 
+        public maxSimultaneousLights: number;
 
 
         private _renderId: number;
         private _renderId: number;
 
 
@@ -94,7 +94,7 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
             if (this.isFrozen) {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
@@ -116,7 +116,7 @@ module BABYLON {
 
 
             var engine = scene.getEngine();
             var engine = scene.getEngine();
 
 
-             // Textures
+            // Textures
             if (defines._areTexturesDirty) {
             if (defines._areTexturesDirty) {
                 defines._needUVs = false;
                 defines._needUVs = false;
                 if (scene.texturesEnabled) {
                 if (scene.texturesEnabled) {
@@ -127,7 +127,7 @@ module BABYLON {
                             defines._needUVs = true;
                             defines._needUVs = true;
                             defines.DIFFUSE = true;
                             defines.DIFFUSE = true;
                         }
                         }
-                    }                
+                    }
                 }
                 }
             }
             }
 
 
@@ -138,8 +138,8 @@ module BABYLON {
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-            
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+
             // Attribs
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
@@ -150,13 +150,13 @@ module BABYLON {
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
-                var fallbacks = new EffectFallbacks();             
+                var fallbacks = new EffectFallbacks();
                 if (defines.FOG) {
                 if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks);
-                
+
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
@@ -188,7 +188,7 @@ module BABYLON {
 
 
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
-                    "vDiffuseInfos", 
+                    "vDiffuseInfos",
                     "mBones",
                     "mBones",
                     "vClipPlane", "diffuseMatrix"
                     "vClipPlane", "diffuseMatrix"
                 ];
                 ];
@@ -196,10 +196,10 @@ module BABYLON {
                 var uniformBuffers = new Array<string>()
                 var uniformBuffers = new Array<string>()
 
 
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms, 
+                    uniformsNames: uniforms,
                     uniformBuffersNames: uniformBuffers,
                     uniformBuffersNames: uniformBuffers,
-                    samplers: samplers, 
-                    defines: defines, 
+                    samplers: samplers,
+                    defines: defines,
                     maxSimultaneousLights: 4
                     maxSimultaneousLights: 4
                 });
                 });
 
 
@@ -263,14 +263,14 @@ module BABYLON {
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                MaterialHelper.BindEyePosition(effect, scene);            
+                MaterialHelper.BindEyePosition(effect, scene);
             }
             }
 
 
             this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
 
 
             // Lights
             // Lights
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);          
+                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines);
             }
             }
 
 
             // View
             // View
@@ -311,10 +311,10 @@ module BABYLON {
 
 
             if (this.diffuseTexture === texture) {
             if (this.diffuseTexture === texture) {
                 return true;
                 return true;
-            }  
+            }
 
 
-            return false;    
-        }        
+            return false;
+        }
 
 
         public dispose(forceDisposeEffect?: boolean): void {
         public dispose(forceDisposeEffect?: boolean): void {
             if (this.diffuseTexture) {
             if (this.diffuseTexture) {
@@ -336,12 +336,12 @@ module BABYLON {
 
 
         public getClassName(): string {
         public getClassName(): string {
             return "NormalMaterial";
             return "NormalMaterial";
-        }        
+        }
 
 
         // Statics
         // Statics
         public static Parse(source: any, scene: Scene, rootUrl: string): NormalMaterial {
         public static Parse(source: any, scene: Scene, rootUrl: string): NormalMaterial {
             return SerializationHelper.Parse(() => new NormalMaterial(source.name, scene), source, scene, rootUrl);
             return SerializationHelper.Parse(() => new NormalMaterial(source.name, scene), source, scene, rootUrl);
         }
         }
     }
     }
-} 
+}
 
 

+ 18 - 18
materialsLibrary/src/shadowOnly/babylon.shadowOnlyMaterial.ts

@@ -42,10 +42,10 @@ module BABYLON {
 
 
         public set activeLight(light: IShadowLight) {
         public set activeLight(light: IShadowLight) {
             this._activeLight = light;
             this._activeLight = light;
-        }        
+        }
 
 
         // Methods   
         // Methods   
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
             if (this.isFrozen) {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
@@ -86,7 +86,7 @@ module BABYLON {
                 }
                 }
             }
             }
 
 
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
 
 
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
 
 
@@ -102,13 +102,13 @@ module BABYLON {
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
-                var fallbacks = new EffectFallbacks();             
+                var fallbacks = new EffectFallbacks();
                 if (defines.FOG) {
                 if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, 1);
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, 1);
-                
+
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
@@ -126,22 +126,22 @@ module BABYLON {
                 var shaderName = "shadowOnly";
                 var shaderName = "shadowOnly";
                 var join = defines.toString();
                 var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType",
-                                "vFogInfos", "vFogColor", "pointSize", "alpha",
-                                "mBones",
-                                "vClipPlane"
+                    "vFogInfos", "vFogColor", "pointSize", "alpha",
+                    "mBones",
+                    "vClipPlane"
                 ];
                 ];
                 var samplers = new Array<string>();
                 var samplers = new Array<string>();
-                
+
                 var uniformBuffers = new Array<string>()
                 var uniformBuffers = new Array<string>()
 
 
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms, 
+                    uniformsNames: uniforms,
                     uniformBuffersNames: uniformBuffers,
                     uniformBuffersNames: uniformBuffers,
-                    samplers: samplers, 
-                    defines: defines, 
+                    samplers: samplers,
+                    defines: defines,
                     maxSimultaneousLights: 1
                     maxSimultaneousLights: 1
                 });
                 });
-                
+
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     <EffectCreationOptions>{
                     <EffectCreationOptions>{
                         attributes: attribs,
                         attributes: attribs,
@@ -197,12 +197,12 @@ module BABYLON {
 
 
                 this._activeEffect.setFloat("alpha", this.alpha);
                 this._activeEffect.setFloat("alpha", this.alpha);
 
 
-                MaterialHelper.BindEyePosition(effect, scene);             
+                MaterialHelper.BindEyePosition(effect, scene);
             }
             }
 
 
             // Lights
             // Lights
             if (scene.lightsEnabled) {
             if (scene.lightsEnabled) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, 1);          
+                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, 1);
             }
             }
 
 
             // View
             // View
@@ -219,7 +219,7 @@ module BABYLON {
         public clone(name: string): ShadowOnlyMaterial {
         public clone(name: string): ShadowOnlyMaterial {
             return SerializationHelper.Clone<ShadowOnlyMaterial>(() => new ShadowOnlyMaterial(name, this.getScene()), this);
             return SerializationHelper.Clone<ShadowOnlyMaterial>(() => new ShadowOnlyMaterial(name, this.getScene()), this);
         }
         }
-        
+
         public serialize(): any {
         public serialize(): any {
             var serializationObject = SerializationHelper.Serialize(this);
             var serializationObject = SerializationHelper.Serialize(this);
             serializationObject.customType = "BABYLON.ShadowOnlyMaterial";
             serializationObject.customType = "BABYLON.ShadowOnlyMaterial";
@@ -228,12 +228,12 @@ module BABYLON {
 
 
         public getClassName(): string {
         public getClassName(): string {
             return "ShadowOnlyMaterial";
             return "ShadowOnlyMaterial";
-        }               
+        }
 
 
         // Statics
         // Statics
         public static Parse(source: any, scene: Scene, rootUrl: string): ShadowOnlyMaterial {
         public static Parse(source: any, scene: Scene, rootUrl: string): ShadowOnlyMaterial {
             return SerializationHelper.Parse(() => new ShadowOnlyMaterial(source.name, scene), source, scene, rootUrl);
             return SerializationHelper.Parse(() => new ShadowOnlyMaterial(source.name, scene), source, scene, rootUrl);
         }
         }
     }
     }
-} 
+}
 
 

+ 27 - 27
materialsLibrary/src/simple/babylon.simpleMaterial.ts

@@ -31,16 +31,16 @@ module BABYLON {
 
 
         @serializeAsColor3("diffuse")
         @serializeAsColor3("diffuse")
         public diffuseColor = new Color3(1, 1, 1);
         public diffuseColor = new Color3(1, 1, 1);
-        
+
         @serialize("disableLighting")
         @serialize("disableLighting")
         private _disableLighting = false;
         private _disableLighting = false;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;   
-        
+        public disableLighting: boolean;
+
         @serialize("maxSimultaneousLights")
         @serialize("maxSimultaneousLights")
         private _maxSimultaneousLights = 4;
         private _maxSimultaneousLights = 4;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number; 
+        public maxSimultaneousLights: number;
 
 
         private _renderId: number;
         private _renderId: number;
 
 
@@ -61,7 +61,7 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
             if (this.isFrozen) {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
@@ -94,7 +94,7 @@ module BABYLON {
                             defines._needUVs = true;
                             defines._needUVs = true;
                             defines.DIFFUSE = true;
                             defines.DIFFUSE = true;
                         }
                         }
-                    }                
+                    }
                 }
                 }
             }
             }
 
 
@@ -105,8 +105,8 @@ module BABYLON {
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-            
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+
             // Attribs
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
@@ -116,13 +116,13 @@ module BABYLON {
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
-                var fallbacks = new EffectFallbacks();             
+                var fallbacks = new EffectFallbacks();
                 if (defines.FOG) {
                 if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
-                
+
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
@@ -152,19 +152,19 @@ module BABYLON {
                 var shaderName = "simple";
                 var shaderName = "simple";
                 var join = defines.toString();
                 var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
-                                "vFogInfos", "vFogColor", "pointSize",
-                                "vDiffuseInfos", 
-                                "mBones",
-                                "vClipPlane", "diffuseMatrix"
+                    "vFogInfos", "vFogColor", "pointSize",
+                    "vDiffuseInfos",
+                    "mBones",
+                    "vClipPlane", "diffuseMatrix"
                 ];
                 ];
                 var samplers = ["diffuseSampler"];
                 var samplers = ["diffuseSampler"];
                 var uniformBuffers = new Array<string>()
                 var uniformBuffers = new Array<string>()
 
 
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms, 
+                    uniformsNames: uniforms,
                     uniformBuffersNames: uniformBuffers,
                     uniformBuffersNames: uniformBuffers,
-                    samplers: samplers, 
-                    defines: defines, 
+                    samplers: samplers,
+                    defines: defines,
                     maxSimultaneousLights: this.maxSimultaneousLights
                     maxSimultaneousLights: this.maxSimultaneousLights
                 });
                 });
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
@@ -220,7 +220,7 @@ module BABYLON {
                     this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
                     this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
                     this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
                     this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
                 }
                 }
-                
+
                 // Clip plane
                 // Clip plane
                 MaterialHelper.BindClipPlane(this._activeEffect, scene);
                 MaterialHelper.BindClipPlane(this._activeEffect, scene);
 
 
@@ -229,14 +229,14 @@ module BABYLON {
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                MaterialHelper.BindEyePosition(effect, scene);            
+                MaterialHelper.BindEyePosition(effect, scene);
             }
             }
 
 
             this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
 
 
             // Lights
             // Lights
             if (scene.lightsEnabled && !this.disableLighting) {
             if (scene.lightsEnabled && !this.disableLighting) {
-                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);          
+                MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
             }
             }
 
 
             // View
             // View
@@ -277,10 +277,10 @@ module BABYLON {
 
 
             if (this.diffuseTexture === texture) {
             if (this.diffuseTexture === texture) {
                 return true;
                 return true;
-            } 
+            }
 
 
-            return false;    
-        }        
+            return false;
+        }
 
 
         public dispose(forceDisposeEffect?: boolean): void {
         public dispose(forceDisposeEffect?: boolean): void {
             if (this._diffuseTexture) {
             if (this._diffuseTexture) {
@@ -293,7 +293,7 @@ module BABYLON {
         public clone(name: string): SimpleMaterial {
         public clone(name: string): SimpleMaterial {
             return SerializationHelper.Clone<SimpleMaterial>(() => new SimpleMaterial(name, this.getScene()), this);
             return SerializationHelper.Clone<SimpleMaterial>(() => new SimpleMaterial(name, this.getScene()), this);
         }
         }
-        
+
         public serialize(): any {
         public serialize(): any {
             var serializationObject = SerializationHelper.Serialize(this);
             var serializationObject = SerializationHelper.Serialize(this);
             serializationObject.customType = "BABYLON.SimpleMaterial";
             serializationObject.customType = "BABYLON.SimpleMaterial";
@@ -302,12 +302,12 @@ module BABYLON {
 
 
         public getClassName(): string {
         public getClassName(): string {
             return "SimpleMaterial";
             return "SimpleMaterial";
-        }               
-        
+        }
+
         // Statics
         // Statics
         public static Parse(source: any, scene: Scene, rootUrl: string): SimpleMaterial {
         public static Parse(source: any, scene: Scene, rootUrl: string): SimpleMaterial {
             return SerializationHelper.Parse(() => new SimpleMaterial(source.name, scene), source, scene, rootUrl);
             return SerializationHelper.Parse(() => new SimpleMaterial(source.name, scene), source, scene, rootUrl);
         }
         }
     }
     }
-} 
+}
 
 

+ 39 - 39
materialsLibrary/src/terrain/babylon.terrainMaterial.ts

@@ -30,8 +30,8 @@ module BABYLON {
         @serializeAsTexture("mixTexture")
         @serializeAsTexture("mixTexture")
         private _mixTexture: BaseTexture;
         private _mixTexture: BaseTexture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public mixTexture: BaseTexture;        
-        
+        public mixTexture: BaseTexture;
+
         @serializeAsTexture("diffuseTexture1")
         @serializeAsTexture("diffuseTexture1")
         private _diffuseTexture1: Texture;
         private _diffuseTexture1: Texture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
@@ -41,45 +41,45 @@ module BABYLON {
         private _diffuseTexture2: Texture;
         private _diffuseTexture2: Texture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         public diffuseTexture2: Texture;
         public diffuseTexture2: Texture;
-        
+
         @serializeAsTexture("diffuseTexture3")
         @serializeAsTexture("diffuseTexture3")
         private _diffuseTexture3: Texture;
         private _diffuseTexture3: Texture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         public diffuseTexture3: Texture;
         public diffuseTexture3: Texture;
-        
+
         @serializeAsTexture("bumpTexture1")
         @serializeAsTexture("bumpTexture1")
         private _bumpTexture1: Texture;
         private _bumpTexture1: Texture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public bumpTexture1: Texture;        
-        
+        public bumpTexture1: Texture;
+
         @serializeAsTexture("bumpTexture2")
         @serializeAsTexture("bumpTexture2")
         private _bumpTexture2: Texture;
         private _bumpTexture2: Texture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public bumpTexture2: Texture;        
-        
+        public bumpTexture2: Texture;
+
         @serializeAsTexture("bumpTexture3")
         @serializeAsTexture("bumpTexture3")
         private _bumpTexture3: Texture;
         private _bumpTexture3: Texture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public bumpTexture3: Texture;   
-        
+        public bumpTexture3: Texture;
+
         @serializeAsColor3()
         @serializeAsColor3()
         public diffuseColor = new Color3(1, 1, 1);
         public diffuseColor = new Color3(1, 1, 1);
-        
+
         @serializeAsColor3()
         @serializeAsColor3()
         public specularColor = new Color3(0, 0, 0);
         public specularColor = new Color3(0, 0, 0);
-        
+
         @serialize()
         @serialize()
         public specularPower = 64;
         public specularPower = 64;
-        
+
         @serialize("disableLighting")
         @serialize("disableLighting")
         private _disableLighting = false;
         private _disableLighting = false;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;   
-        
+        public disableLighting: boolean;
+
         @serialize("maxSimultaneousLights")
         @serialize("maxSimultaneousLights")
         private _maxSimultaneousLights = 4;
         private _maxSimultaneousLights = 4;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number; 
+        public maxSimultaneousLights: number;
 
 
         private _renderId: number;
         private _renderId: number;
 
 
@@ -100,7 +100,7 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
             if (this.isFrozen) {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
@@ -138,7 +138,7 @@ module BABYLON {
                     defines.BUMP = true;
                     defines.BUMP = true;
                 }
                 }
             }
             }
-            
+
             // Misc.
             // Misc.
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
 
 
@@ -146,8 +146,8 @@ module BABYLON {
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-            
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+
             // Attribs
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
@@ -157,13 +157,13 @@ module BABYLON {
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
-                var fallbacks = new EffectFallbacks();             
+                var fallbacks = new EffectFallbacks();
                 if (defines.FOG) {
                 if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
-             
+
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
@@ -195,7 +195,7 @@ module BABYLON {
                 var join = defines.toString();
                 var join = defines.toString();
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                 var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                     "vFogInfos", "vFogColor", "pointSize",
                     "vFogInfos", "vFogColor", "pointSize",
-                    "vTextureInfos", 
+                    "vTextureInfos",
                     "mBones",
                     "mBones",
                     "vClipPlane", "textureMatrix",
                     "vClipPlane", "textureMatrix",
                     "diffuse1Infos", "diffuse2Infos", "diffuse3Infos"
                     "diffuse1Infos", "diffuse2Infos", "diffuse3Infos"
@@ -207,13 +207,13 @@ module BABYLON {
                 var uniformBuffers = new Array<string>()
                 var uniformBuffers = new Array<string>()
 
 
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms, 
+                    uniformsNames: uniforms,
                     uniformBuffersNames: uniformBuffers,
                     uniformBuffersNames: uniformBuffers,
-                    samplers: samplers, 
-                    defines: defines, 
+                    samplers: samplers,
+                    defines: defines,
                     maxSimultaneousLights: this.maxSimultaneousLights
                     maxSimultaneousLights: this.maxSimultaneousLights
                 });
                 });
-                
+
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     <EffectCreationOptions>{
                     <EffectCreationOptions>{
                         attributes: attribs,
                         attributes: attribs,
@@ -264,7 +264,7 @@ module BABYLON {
                     this._activeEffect.setTexture("textureSampler", this._mixTexture);
                     this._activeEffect.setTexture("textureSampler", this._mixTexture);
                     this._activeEffect.setFloat2("vTextureInfos", this._mixTexture.coordinatesIndex, this._mixTexture.level);
                     this._activeEffect.setFloat2("vTextureInfos", this._mixTexture.coordinatesIndex, this._mixTexture.level);
                     this._activeEffect.setMatrix("textureMatrix", this._mixTexture.getTextureMatrix());
                     this._activeEffect.setMatrix("textureMatrix", this._mixTexture.getTextureMatrix());
-                    
+
                     if (StandardMaterial.DiffuseTextureEnabled) {
                     if (StandardMaterial.DiffuseTextureEnabled) {
                         if (this._diffuseTexture1) {
                         if (this._diffuseTexture1) {
                             this._activeEffect.setTexture("diffuse1Sampler", this._diffuseTexture1);
                             this._activeEffect.setTexture("diffuse1Sampler", this._diffuseTexture1);
@@ -279,7 +279,7 @@ module BABYLON {
                             this._activeEffect.setFloat2("diffuse3Infos", this._diffuseTexture3.uScale, this._diffuseTexture3.vScale);
                             this._activeEffect.setFloat2("diffuse3Infos", this._diffuseTexture3.uScale, this._diffuseTexture3.vScale);
                         }
                         }
                     }
                     }
-                    
+
                     if (StandardMaterial.BumpTextureEnabled && scene.getEngine().getCaps().standardDerivatives) {
                     if (StandardMaterial.BumpTextureEnabled && scene.getEngine().getCaps().standardDerivatives) {
                         if (this._bumpTexture1) {
                         if (this._bumpTexture1) {
                             this._activeEffect.setTexture("bump1Sampler", this._bumpTexture1);
                             this._activeEffect.setTexture("bump1Sampler", this._bumpTexture1);
@@ -300,11 +300,11 @@ module BABYLON {
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                MaterialHelper.BindEyePosition(effect, scene);             
+                MaterialHelper.BindEyePosition(effect, scene);
             }
             }
 
 
             this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-            
+
             if (defines.SPECULARTERM) {
             if (defines.SPECULARTERM) {
                 this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
                 this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
             }
             }
@@ -379,7 +379,7 @@ module BABYLON {
 
 
             if (this._diffuseTexture1 === texture) {
             if (this._diffuseTexture1 === texture) {
                 return true;
                 return true;
-            }    
+            }
 
 
             if (this._diffuseTexture2 === texture) {
             if (this._diffuseTexture2 === texture) {
                 return true;
                 return true;
@@ -387,7 +387,7 @@ module BABYLON {
 
 
             if (this._diffuseTexture3 === texture) {
             if (this._diffuseTexture3 === texture) {
                 return true;
                 return true;
-            }        
+            }
 
 
             if (this._bumpTexture1 === texture) {
             if (this._bumpTexture1 === texture) {
                 return true;
                 return true;
@@ -395,14 +395,14 @@ module BABYLON {
 
 
             if (this._bumpTexture2 === texture) {
             if (this._bumpTexture2 === texture) {
                 return true;
                 return true;
-            }        
+            }
 
 
             if (this._bumpTexture3 === texture) {
             if (this._bumpTexture3 === texture) {
                 return true;
                 return true;
-            }      
+            }
 
 
-            return false;    
-        }        
+            return false;
+        }
 
 
         public dispose(forceDisposeEffect?: boolean): void {
         public dispose(forceDisposeEffect?: boolean): void {
             if (this.mixTexture) {
             if (this.mixTexture) {
@@ -411,7 +411,7 @@ module BABYLON {
 
 
             super.dispose(forceDisposeEffect);
             super.dispose(forceDisposeEffect);
         }
         }
-        
+
         public clone(name: string): TerrainMaterial {
         public clone(name: string): TerrainMaterial {
             return SerializationHelper.Clone(() => new TerrainMaterial(name, this.getScene()), this);
             return SerializationHelper.Clone(() => new TerrainMaterial(name, this.getScene()), this);
         }
         }
@@ -431,5 +431,5 @@ module BABYLON {
             return SerializationHelper.Parse(() => new TerrainMaterial(source.name, scene), source, scene, rootUrl);
             return SerializationHelper.Parse(() => new TerrainMaterial(source.name, scene), source, scene, rootUrl);
         }
         }
     }
     }
-} 
+}
 
 

+ 49 - 49
materialsLibrary/src/triPlanar/babylon.triPlanarMaterial.ts

@@ -5,11 +5,11 @@ module BABYLON {
         public DIFFUSEX = false;
         public DIFFUSEX = false;
         public DIFFUSEY = false;
         public DIFFUSEY = false;
         public DIFFUSEZ = false;
         public DIFFUSEZ = false;
-        
+
         public BUMPX = false;
         public BUMPX = false;
         public BUMPY = false;
         public BUMPY = false;
         public BUMPZ = false;
         public BUMPZ = false;
-        
+
         public CLIPPLANE = false;
         public CLIPPLANE = false;
         public ALPHATEST = false;
         public ALPHATEST = false;
         public DEPTHPREPASS = false;
         public DEPTHPREPASS = false;
@@ -32,59 +32,59 @@ module BABYLON {
     export class TriPlanarMaterial extends PushMaterial {
     export class TriPlanarMaterial extends PushMaterial {
         @serializeAsTexture()
         @serializeAsTexture()
         public mixTexture: BaseTexture;
         public mixTexture: BaseTexture;
-        
+
         @serializeAsTexture("diffuseTextureX")
         @serializeAsTexture("diffuseTextureX")
         private _diffuseTextureX: BaseTexture;
         private _diffuseTextureX: BaseTexture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         public diffuseTextureX: BaseTexture;
         public diffuseTextureX: BaseTexture;
-        
+
         @serializeAsTexture("diffuseTexturY")
         @serializeAsTexture("diffuseTexturY")
         private _diffuseTextureY: BaseTexture;
         private _diffuseTextureY: BaseTexture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTextureY: BaseTexture;        
-        
+        public diffuseTextureY: BaseTexture;
+
         @serializeAsTexture("diffuseTextureZ")
         @serializeAsTexture("diffuseTextureZ")
         private _diffuseTextureZ: BaseTexture;
         private _diffuseTextureZ: BaseTexture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public diffuseTextureZ: BaseTexture;        
-        
+        public diffuseTextureZ: BaseTexture;
+
         @serializeAsTexture("normalTextureX")
         @serializeAsTexture("normalTextureX")
         private _normalTextureX: BaseTexture;
         private _normalTextureX: BaseTexture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public normalTextureX: BaseTexture;        
-        
+        public normalTextureX: BaseTexture;
+
         @serializeAsTexture("normalTextureY")
         @serializeAsTexture("normalTextureY")
         private _normalTextureY: BaseTexture;
         private _normalTextureY: BaseTexture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public normalTextureY: BaseTexture;        
-        
+        public normalTextureY: BaseTexture;
+
         @serializeAsTexture("normalTextureZ")
         @serializeAsTexture("normalTextureZ")
         private _normalTextureZ: BaseTexture;
         private _normalTextureZ: BaseTexture;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public normalTextureZ: BaseTexture;        
-               
+        public normalTextureZ: BaseTexture;
+
         @serialize()
         @serialize()
         public tileSize: number = 1;
         public tileSize: number = 1;
-        
+
         @serializeAsColor3()
         @serializeAsColor3()
         public diffuseColor = new Color3(1, 1, 1);
         public diffuseColor = new Color3(1, 1, 1);
-        
+
         @serializeAsColor3()
         @serializeAsColor3()
         public specularColor = new Color3(0.2, 0.2, 0.2);
         public specularColor = new Color3(0.2, 0.2, 0.2);
-        
+
         @serialize()
         @serialize()
         public specularPower = 64;
         public specularPower = 64;
-        
+
         @serialize("disableLighting")
         @serialize("disableLighting")
         private _disableLighting = false;
         private _disableLighting = false;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public disableLighting: boolean;   
-        
+        public disableLighting: boolean;
+
         @serialize("maxSimultaneousLights")
         @serialize("maxSimultaneousLights")
         private _maxSimultaneousLights = 4;
         private _maxSimultaneousLights = 4;
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
         @expandToProperty("_markAllSubMeshesAsLightsDirty")
-        public maxSimultaneousLights: number; 
-        
+        public maxSimultaneousLights: number;
+
         private _renderId: number;
         private _renderId: number;
 
 
         constructor(name: string, scene: Scene) {
         constructor(name: string, scene: Scene) {
@@ -104,7 +104,7 @@ module BABYLON {
         }
         }
 
 
         // Methods   
         // Methods   
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {   
+        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
             if (this.isFrozen) {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
                     return true;
                     return true;
@@ -127,13 +127,13 @@ module BABYLON {
             var engine = scene.getEngine();
             var engine = scene.getEngine();
 
 
             // Textures
             // Textures
-            if (defines._areTexturesDirty) {                
+            if (defines._areTexturesDirty) {
                 if (scene.texturesEnabled) {
                 if (scene.texturesEnabled) {
                     if (StandardMaterial.DiffuseTextureEnabled) {
                     if (StandardMaterial.DiffuseTextureEnabled) {
                         var textures = [this.diffuseTextureX, this.diffuseTextureY, this.diffuseTextureZ];
                         var textures = [this.diffuseTextureX, this.diffuseTextureY, this.diffuseTextureZ];
                         var textureDefines = ["DIFFUSEX", "DIFFUSEY", "DIFFUSEZ"];
                         var textureDefines = ["DIFFUSEX", "DIFFUSEY", "DIFFUSEZ"];
-                        
-                        for (var i=0; i < textures.length; i++) {
+
+                        for (var i = 0; i < textures.length; i++) {
                             if (textures[i]) {
                             if (textures[i]) {
                                 if (!textures[i].isReady()) {
                                 if (!textures[i].isReady()) {
                                     return false;
                                     return false;
@@ -146,8 +146,8 @@ module BABYLON {
                     if (StandardMaterial.BumpTextureEnabled) {
                     if (StandardMaterial.BumpTextureEnabled) {
                         var textures = [this.normalTextureX, this.normalTextureY, this.normalTextureZ];
                         var textures = [this.normalTextureX, this.normalTextureY, this.normalTextureZ];
                         var textureDefines = ["BUMPX", "BUMPY", "BUMPZ"];
                         var textureDefines = ["BUMPX", "BUMPY", "BUMPZ"];
-                        
-                        for (var i=0; i < textures.length; i++) {
+
+                        for (var i = 0; i < textures.length; i++) {
                             if (textures[i]) {
                             if (textures[i]) {
                                 if (!textures[i].isReady()) {
                                 if (!textures[i].isReady()) {
                                     return false;
                                     return false;
@@ -167,8 +167,8 @@ module BABYLON {
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
-            
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+
             // Attribs
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
 
 
@@ -178,13 +178,13 @@ module BABYLON {
                 scene.resetCachedMaterial();
                 scene.resetCachedMaterial();
 
 
                 // Fallbacks
                 // Fallbacks
-                var fallbacks = new EffectFallbacks();             
+                var fallbacks = new EffectFallbacks();
                 if (defines.FOG) {
                 if (defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                     fallbacks.addFallback(1, "FOG");
                 }
                 }
 
 
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
                 MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
-             
+
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                 if (defines.NUM_BONE_INFLUENCERS > 0) {
                     fallbacks.addCPUSkinningFallback(0, mesh);
                     fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 }
@@ -219,13 +219,13 @@ module BABYLON {
                 var uniformBuffers = new Array<string>()
                 var uniformBuffers = new Array<string>()
 
 
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
                 MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms, 
+                    uniformsNames: uniforms,
                     uniformBuffersNames: uniformBuffers,
                     uniformBuffersNames: uniformBuffers,
-                    samplers: samplers, 
-                    defines: defines, 
+                    samplers: samplers,
+                    defines: defines,
                     maxSimultaneousLights: this.maxSimultaneousLights
                     maxSimultaneousLights: this.maxSimultaneousLights
                 });
                 });
-                
+
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                 subMesh.setEffect(scene.getEngine().createEffect(shaderName,
                     <EffectCreationOptions>{
                     <EffectCreationOptions>{
                         attributes: attribs,
                         attributes: attribs,
@@ -245,7 +245,7 @@ module BABYLON {
 
 
             this._renderId = scene.getRenderId();
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
             this._wasPreviouslyReady = true;
-            
+
             return true;
             return true;
         }
         }
 
 
@@ -269,7 +269,7 @@ module BABYLON {
 
 
             // Bones
             // Bones
             MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
             MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
-            
+
             this._activeEffect.setFloat("tileSize", this.tileSize);
             this._activeEffect.setFloat("tileSize", this.tileSize);
 
 
             if (scene.getCachedMaterial() !== this) {
             if (scene.getCachedMaterial() !== this) {
@@ -300,11 +300,11 @@ module BABYLON {
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                     this._activeEffect.setFloat("pointSize", this.pointSize);
                 }
                 }
 
 
-                MaterialHelper.BindEyePosition(effect, scene);               
+                MaterialHelper.BindEyePosition(effect, scene);
             }
             }
 
 
             this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
             this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-            
+
             if (defines.SPECULARTERM) {
             if (defines.SPECULARTERM) {
                 this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
                 this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
             }
             }
@@ -371,11 +371,11 @@ module BABYLON {
 
 
             if (this._diffuseTextureX === texture) {
             if (this._diffuseTextureX === texture) {
                 return true;
                 return true;
-            }    
+            }
 
 
             if (this._diffuseTextureY === texture) {
             if (this._diffuseTextureY === texture) {
                 return true;
                 return true;
-            }         
+            }
 
 
             if (this._diffuseTextureZ === texture) {
             if (this._diffuseTextureZ === texture) {
                 return true;
                 return true;
@@ -383,17 +383,17 @@ module BABYLON {
 
 
             if (this._normalTextureX === texture) {
             if (this._normalTextureX === texture) {
                 return true;
                 return true;
-            }     
+            }
 
 
             if (this._normalTextureY === texture) {
             if (this._normalTextureY === texture) {
                 return true;
                 return true;
-            }     
+            }
 
 
             if (this._normalTextureZ === texture) {
             if (this._normalTextureZ === texture) {
                 return true;
                 return true;
-            }                                 
-            return false;    
-        }        
+            }
+            return false;
+        }
 
 
         public dispose(forceDisposeEffect?: boolean): void {
         public dispose(forceDisposeEffect?: boolean): void {
             if (this.mixTexture) {
             if (this.mixTexture) {
@@ -402,7 +402,7 @@ module BABYLON {
 
 
             super.dispose(forceDisposeEffect);
             super.dispose(forceDisposeEffect);
         }
         }
-        
+
         public clone(name: string): TriPlanarMaterial {
         public clone(name: string): TriPlanarMaterial {
             return SerializationHelper.Clone(() => new TriPlanarMaterial(name, this.getScene()), this);
             return SerializationHelper.Clone(() => new TriPlanarMaterial(name, this.getScene()), this);
         }
         }
@@ -422,5 +422,5 @@ module BABYLON {
             return SerializationHelper.Parse(() => new TriPlanarMaterial(source.name, scene), source, scene, rootUrl);
             return SerializationHelper.Parse(() => new TriPlanarMaterial(source.name, scene), source, scene, rootUrl);
         }
         }
     }
     }
-} 
+}
 
 

+ 6 - 6
materialsLibrary/src/water/babylon.waterMaterial.ts

@@ -164,8 +164,8 @@ module BABYLON {
             // Create render targets
             // Create render targets
             this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {
             this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {
                 this._renderTargets.reset();
                 this._renderTargets.reset();
-                this._renderTargets.push(<RenderTargetTexture> this._reflectionRTT);
-                this._renderTargets.push(<RenderTargetTexture> this._refractionRTT);
+                this._renderTargets.push(<RenderTargetTexture>this._reflectionRTT);
+                this._renderTargets.push(<RenderTargetTexture>this._refractionRTT);
 
 
                 return this._renderTargets;
                 return this._renderTargets;
             }
             }
@@ -275,7 +275,7 @@ module BABYLON {
                 }
                 }
             }
             }
 
 
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
 
 
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
 
 
@@ -614,12 +614,12 @@ module BABYLON {
                 this.bumpTexture.dispose();
                 this.bumpTexture.dispose();
             }
             }
 
 
-            var index = this.getScene().customRenderTargets.indexOf(<RenderTargetTexture> this._refractionRTT);
+            var index = this.getScene().customRenderTargets.indexOf(<RenderTargetTexture>this._refractionRTT);
             if (index != -1) {
             if (index != -1) {
                 this.getScene().customRenderTargets.splice(index, 1);
                 this.getScene().customRenderTargets.splice(index, 1);
             }
             }
             index = -1;
             index = -1;
-            index = this.getScene().customRenderTargets.indexOf(<RenderTargetTexture> this._reflectionRTT);
+            index = this.getScene().customRenderTargets.indexOf(<RenderTargetTexture>this._reflectionRTT);
             if (index != -1) {
             if (index != -1) {
                 this.getScene().customRenderTargets.splice(index, 1);
                 this.getScene().customRenderTargets.splice(index, 1);
             }
             }
@@ -641,7 +641,7 @@ module BABYLON {
         public serialize(): any {
         public serialize(): any {
             var serializationObject = SerializationHelper.Serialize(this);
             var serializationObject = SerializationHelper.Serialize(this);
             serializationObject.customType = "BABYLON.WaterMaterial";
             serializationObject.customType = "BABYLON.WaterMaterial";
-            
+
             serializationObject.renderList = [];
             serializationObject.renderList = [];
             if (this._refractionRTT && this._refractionRTT.renderList) {
             if (this._refractionRTT && this._refractionRTT.renderList) {
                 for (var i = 0; i < this._refractionRTT.renderList.length; i++) {
                 for (var i = 0; i < this._refractionRTT.renderList.length; i++) {

+ 19 - 10
src/Animations/babylon.animationGroup.ts

@@ -16,7 +16,7 @@ module BABYLON {
         private _targetedAnimations = new Array<TargetedAnimation>();
         private _targetedAnimations = new Array<TargetedAnimation>();
         private _animatables = new Array<Animatable>();
         private _animatables = new Array<Animatable>();
         private _from = Number.MAX_VALUE;
         private _from = Number.MAX_VALUE;
-        private _to = Number.MIN_VALUE;
+        private _to = -Number.MAX_VALUE;
         private _isStarted: boolean;
         private _isStarted: boolean;
         private _speedRatio = 1;
         private _speedRatio = 1;
 
 
@@ -52,6 +52,13 @@ module BABYLON {
             }
             }
         }
         }
 
 
+        /**
+         * Gets the targeted animations for this animation group
+         */
+        public get targetedAnimations(): Array<TargetedAnimation> {
+            return this._targetedAnimations;
+        }
+
         public constructor(public name: string, scene: Nullable<Scene> = null) {
         public constructor(public name: string, scene: Nullable<Scene> = null) {
             this._scene = scene || Engine.LastCreatedScene!;
             this._scene = scene || Engine.LastCreatedScene!;
 
 
@@ -87,11 +94,11 @@ module BABYLON {
         /**
         /**
          * This function will normalize every animation in the group to make sure they all go from beginFrame to endFrame
          * This function will normalize every animation in the group to make sure they all go from beginFrame to endFrame
          * It can add constant keys at begin or end
          * It can add constant keys at begin or end
-         * @param beginFrame defines the new begin frame for all animations. It can't be bigger than the smaller begin frame of all animations
-         * @param endFrame defines the new end frame for all animations. It can't be smaller than the larger end frame of all animations
+         * @param beginFrame defines the new begin frame for all animations. It can't be bigger than the smallest begin frame of all animations
+         * @param endFrame defines the new end frame for all animations. It can't be smaller than the largest end frame of all animations
          */
          */
-        public normalize(beginFrame: number, endFrame: number): AnimationGroup {
-            beginFrame = Math.min(beginFrame, this._from);
+        public normalize(beginFrame = -Number.MAX_VALUE, endFrame = Number.MAX_VALUE): AnimationGroup {
+            beginFrame = Math.max(beginFrame, this._from);
             endFrame = Math.min(endFrame, this._to);
             endFrame = Math.min(endFrame, this._to);
 
 
             for (var index = 0; index < this._targetedAnimations.length; index++) {
             for (var index = 0; index < this._targetedAnimations.length; index++) {
@@ -101,21 +108,23 @@ module BABYLON {
                 let endKey = keys[keys.length - 1];
                 let endKey = keys[keys.length - 1];
 
 
                 if (startKey.frame > beginFrame) {
                 if (startKey.frame > beginFrame) {
-                    let newKey = {
+                    let newKey: IAnimationKey = {
                         frame: beginFrame,
                         frame: beginFrame,
                         value: startKey.value,
                         value: startKey.value,
                         inTangent: startKey.inTangent,
                         inTangent: startKey.inTangent,
-                        outTangent: startKey.outTangent
+                        outTangent: startKey.outTangent,
+                        interpolation: startKey.interpolation
                     }
                     }
                     keys.splice(0, 0, newKey);
                     keys.splice(0, 0, newKey);
                 }
                 }
 
 
                 if (endKey.frame < endFrame) {
                 if (endKey.frame < endFrame) {
-                    let newKey = {
+                    let newKey: IAnimationKey = {
                         frame: endFrame,
                         frame: endFrame,
                         value: endKey.value,
                         value: endKey.value,
-                        inTangent: startKey.outTangent,
-                        outTangent: startKey.outTangent
+                        inTangent: endKey.outTangent,
+                        outTangent: endKey.outTangent,
+                        interpolation: endKey.interpolation
                     }
                     }
                     keys.push(newKey);
                     keys.push(newKey);
                 }
                 }

+ 23 - 23
src/Debug/babylon.rayHelper.ts

@@ -1,19 +1,19 @@
 module BABYLON {
 module BABYLON {
     export class RayHelper {
     export class RayHelper {
-        
+
         public ray: Nullable<Ray>;
         public ray: Nullable<Ray>;
 
 
         private _renderPoints: Vector3[];
         private _renderPoints: Vector3[];
         private _renderLine: Nullable<LinesMesh>;
         private _renderLine: Nullable<LinesMesh>;
         private _renderFunction: Nullable<() => void>;
         private _renderFunction: Nullable<() => void>;
         private _scene: Nullable<Scene>;
         private _scene: Nullable<Scene>;
-        
+
         private _updateToMeshFunction: Nullable<() => void>;
         private _updateToMeshFunction: Nullable<() => void>;
         private _attachedToMesh: Nullable<AbstractMesh>;
         private _attachedToMesh: Nullable<AbstractMesh>;
         private _meshSpaceDirection: Vector3;
         private _meshSpaceDirection: Vector3;
         private _meshSpaceOrigin: Vector3;
         private _meshSpaceOrigin: Vector3;
 
 
-        public static CreateAndShow(ray: Ray, scene: Scene, color:Color3): RayHelper {
+        public static CreateAndShow(ray: Ray, scene: Scene, color: Color3): RayHelper {
             var helper = new RayHelper(ray);
             var helper = new RayHelper(ray);
 
 
             helper.show(scene, color);
             helper.show(scene, color);
@@ -21,13 +21,13 @@ module BABYLON {
             return helper;
             return helper;
         }
         }
 
 
-        constructor(ray:Ray) {
+        constructor(ray: Ray) {
             this.ray = ray;
             this.ray = ray;
         }
         }
 
 
-        public show(scene:Scene, color:Color3): void{
+        public show(scene: Scene, color: Color3): void {
 
 
-            if(!this._renderFunction && this.ray){
+            if (!this._renderFunction && this.ray) {
 
 
                 var ray = this.ray;
                 var ray = this.ray;
 
 
@@ -47,9 +47,9 @@ module BABYLON {
 
 
         }
         }
 
 
-        public hide(): void{
+        public hide(): void {
 
 
-            if(this._renderFunction && this._scene){
+            if (this._renderFunction && this._scene) {
                 this._scene.unregisterBeforeRender(this._renderFunction);
                 this._scene.unregisterBeforeRender(this._renderFunction);
                 this._scene = null;
                 this._scene = null;
                 this._renderFunction = null;
                 this._renderFunction = null;
@@ -73,7 +73,7 @@ module BABYLON {
 
 
             var point = this._renderPoints[1];
             var point = this._renderPoints[1];
             var len = Math.min(ray.length, 1000000);
             var len = Math.min(ray.length, 1000000);
-            
+
             point.copyFrom(ray.direction);
             point.copyFrom(ray.direction);
             point.scaleInPlace(len);
             point.scaleInPlace(len);
             point.addInPlace(ray.origin);
             point.addInPlace(ray.origin);
@@ -82,7 +82,7 @@ module BABYLON {
 
 
         }
         }
 
 
-        public attachToMesh(mesh:AbstractMesh, meshSpaceDirection?:Vector3, meshSpaceOrigin?:Vector3, length?:number): void{
+        public attachToMesh(mesh: AbstractMesh, meshSpaceDirection?: Vector3, meshSpaceOrigin?: Vector3, length?: number): void {
 
 
             this._attachedToMesh = mesh;
             this._attachedToMesh = mesh;
 
 
@@ -92,36 +92,36 @@ module BABYLON {
                 return;
                 return;
             }
             }
 
 
-            if(!ray.direction){
+            if (!ray.direction) {
                 ray.direction = Vector3.Zero();
                 ray.direction = Vector3.Zero();
             }
             }
 
 
-            if(!ray.origin){
+            if (!ray.origin) {
                 ray.origin = Vector3.Zero();
                 ray.origin = Vector3.Zero();
             }
             }
 
 
-            if(length){
+            if (length) {
                 ray.length = length;
                 ray.length = length;
             }
             }
 
 
-            if(!meshSpaceOrigin){
+            if (!meshSpaceOrigin) {
                 meshSpaceOrigin = Vector3.Zero();
                 meshSpaceOrigin = Vector3.Zero();
             }
             }
 
 
-            if(!meshSpaceDirection){
+            if (!meshSpaceDirection) {
                 // -1 so that this will work with Mesh.lookAt
                 // -1 so that this will work with Mesh.lookAt
                 meshSpaceDirection = new Vector3(0, 0, -1);
                 meshSpaceDirection = new Vector3(0, 0, -1);
             }
             }
 
 
-            if(!this._meshSpaceDirection){
+            if (!this._meshSpaceDirection) {
                 this._meshSpaceDirection = meshSpaceDirection.clone();
                 this._meshSpaceDirection = meshSpaceDirection.clone();
                 this._meshSpaceOrigin = meshSpaceOrigin.clone();
                 this._meshSpaceOrigin = meshSpaceOrigin.clone();
-            }else{
+            } else {
                 this._meshSpaceDirection.copyFrom(meshSpaceDirection);
                 this._meshSpaceDirection.copyFrom(meshSpaceDirection);
                 this._meshSpaceOrigin.copyFrom(meshSpaceOrigin);
                 this._meshSpaceOrigin.copyFrom(meshSpaceOrigin);
             }
             }
 
 
-            if(!this._updateToMeshFunction){
+            if (!this._updateToMeshFunction) {
                 this._updateToMeshFunction = (<() => void>this._updateToMesh.bind(this));
                 this._updateToMeshFunction = (<() => void>this._updateToMesh.bind(this));
                 this._attachedToMesh.getScene().registerBeforeRender(this._updateToMeshFunction);
                 this._attachedToMesh.getScene().registerBeforeRender(this._updateToMeshFunction);
             }
             }
@@ -130,9 +130,9 @@ module BABYLON {
 
 
         }
         }
 
 
-        public detachFromMesh(): void{
+        public detachFromMesh(): void {
 
 
-            if(this._attachedToMesh){
+            if (this._attachedToMesh) {
                 if (this._updateToMeshFunction) {
                 if (this._updateToMeshFunction) {
                     this._attachedToMesh.getScene().unregisterBeforeRender(this._updateToMeshFunction);
                     this._attachedToMesh.getScene().unregisterBeforeRender(this._updateToMeshFunction);
                 }
                 }
@@ -142,7 +142,7 @@ module BABYLON {
 
 
         }
         }
 
 
-        private _updateToMesh(): void{
+        private _updateToMesh(): void {
 
 
             var ray = this.ray;
             var ray = this.ray;
 
 
@@ -150,7 +150,7 @@ module BABYLON {
                 return;
                 return;
             }
             }
 
 
-            if(this._attachedToMesh._isDisposed){
+            if (this._attachedToMesh._isDisposed) {
                 this.detachFromMesh();
                 this.detachFromMesh();
                 return;
                 return;
             }
             }
@@ -160,7 +160,7 @@ module BABYLON {
 
 
         }
         }
 
 
-        public dispose(): void{
+        public dispose(): void {
 
 
             this.hide();
             this.hide();
             this.detachFromMesh();
             this.detachFromMesh();

+ 80 - 78
src/Engine/babylon.engine.ts

@@ -654,7 +654,7 @@
          */
          */
         public disableTextureBindingOptimization = false;
         public disableTextureBindingOptimization = false;
 
 
-        public static audioEngine: AudioEngine;       
+        public static audioEngine: AudioEngine;
 
 
         // Focus
         // Focus
         private _onFocus: () => void;
         private _onFocus: () => void;
@@ -680,7 +680,6 @@
         private _hardwareScalingLevel: number;
         private _hardwareScalingLevel: number;
         protected _caps: EngineCapabilities;
         protected _caps: EngineCapabilities;
         private _pointerLockRequested: boolean;
         private _pointerLockRequested: boolean;
-        private _alphaTest: boolean;
         private _isStencilEnable: boolean;
         private _isStencilEnable: boolean;
         private _colorWrite = true;
         private _colorWrite = true;
 
 
@@ -731,7 +730,8 @@
 
 
         // Cache
         // Cache
         private _internalTexturesCache = new Array<InternalTexture>();
         private _internalTexturesCache = new Array<InternalTexture>();
-        protected _activeChannel: number;
+        protected _activeChannel = 0;
+        private _currentTextureChannel = -1;
         protected _boundTexturesCache: { [key: string]: Nullable<InternalTexture> } = {};
         protected _boundTexturesCache: { [key: string]: Nullable<InternalTexture> } = {};
         protected _boundTexturesStack = new Array<InternalTexture>();
         protected _boundTexturesStack = new Array<InternalTexture>();
         protected _currentEffect: Nullable<Effect>;
         protected _currentEffect: Nullable<Effect>;
@@ -818,11 +818,12 @@
 
 
         /**
         /**
          * @constructor
          * @constructor
-         * @param {HTMLCanvasElement | WebGLRenderingContext} canvasOrContext - the canvas or the webgl context to be used for rendering
-         * @param {boolean} [antialias] - enable antialias
-         * @param options - further options to be sent to the getContext function
+         * @param canvasOrContext defines the canvas or WebGL context to use for rendering
+         * @param antialias defines enable antialiasing (default: false)
+         * @param options defines further options to be sent to the getContext() function
+         * @param adaptToDeviceRatio defines whether to adapt to the device's viewport characteristics (default: false)
          */
          */
-        constructor(canvasOrContext: Nullable<HTMLCanvasElement | WebGLRenderingContext>, antialias?: boolean, options?: EngineOptions, adaptToDeviceRatio = false) {
+        constructor(canvasOrContext: Nullable<HTMLCanvasElement | WebGLRenderingContext>, antialias?: boolean, options?: EngineOptions, adaptToDeviceRatio: boolean = false) {
             let canvas: Nullable<HTMLCanvasElement> = null;
             let canvas: Nullable<HTMLCanvasElement> = null;
             Engine.Instances.push(this);
             Engine.Instances.push(this);
 
 
@@ -894,8 +895,8 @@
                                         this.disableUniformBuffers = true;
                                         this.disableUniformBuffers = true;
                                         break;
                                         break;
                                     case "textureBindingOptimization":
                                     case "textureBindingOptimization":
-                                        this.disableTextureBindingOptimization = true;    
-                                        break;    
+                                        this.disableTextureBindingOptimization = true;
+                                        break;
                                 }
                                 }
                             }
                             }
                             break;
                             break;
@@ -1348,7 +1349,7 @@
             for (let slot = 0; slot < this._maxSimultaneousTextures; slot++) {
             for (let slot = 0; slot < this._maxSimultaneousTextures; slot++) {
                 this._nextFreeTextureSlots.push(slot);
                 this._nextFreeTextureSlots.push(slot);
             }
             }
-            this._activeChannel = -1;
+            this._currentTextureChannel = -1;
         }
         }
 
 
         public isDeterministicLockStep(): boolean {
         public isDeterministicLockStep(): boolean {
@@ -3026,14 +3027,6 @@
             return this._alphaMode;
             return this._alphaMode;
         }
         }
 
 
-        public setAlphaTesting(enable: boolean): void {
-            this._alphaTest = enable;
-        }
-
-        public getAlphaTesting(): boolean {
-            return !!this._alphaTest;
-        }
-
         // Textures
         // Textures
         public wipeCaches(bruteForce?: boolean): void {
         public wipeCaches(bruteForce?: boolean): void {
             if (this.preventCacheWipeBetweenFrames && !bruteForce) {
             if (this.preventCacheWipeBetweenFrames && !bruteForce) {
@@ -4746,13 +4739,6 @@
             this._currentEffect = null;
             this._currentEffect = null;
         }
         }
 
 
-        private _activateTextureChannel(channel: number): void {
-            if (this._activeChannel !== channel && channel > -1) {
-                this._gl.activeTexture(this._gl.TEXTURE0 + channel);
-                this._activeChannel = channel;
-            }
-        }
-
         private _moveBoundTextureOnTop(internalTexture: InternalTexture): void {
         private _moveBoundTextureOnTop(internalTexture: InternalTexture): void {
             let index = this._boundTexturesStack.indexOf(internalTexture);
             let index = this._boundTexturesStack.indexOf(internalTexture);
 
 
@@ -4762,8 +4748,42 @@
             }
             }
         }
         }
 
 
+
+        private _getCorrectTextureChannel(channel: number, internalTexture: Nullable<InternalTexture>): number {
+            if (!internalTexture) {
+                return -1;
+            }
+
+            internalTexture._initialSlot = channel;
+
+            if (this.disableTextureBindingOptimization) { // We want texture sampler ID === texture channel
+                if (channel !== internalTexture._designatedSlot) {
+                    this._textureCollisions.addCount(1, false);
+                }
+            } else {
+                if (channel !== internalTexture._designatedSlot) {
+                    if (internalTexture._designatedSlot > -1) { // Texture is already assigned to a slot
+                        return internalTexture._designatedSlot;
+                    } else {
+                        // No slot for this texture, let's pick a new one (if we find a free slot)
+                        if (this._nextFreeTextureSlots.length) {
+                            return this._nextFreeTextureSlots[0];
+                        }
+
+                        // We need to recycle the oldest bound texture, sorry.
+                        this._textureCollisions.addCount(1, false);
+                        return this._removeDesignatedSlot(this._boundTexturesStack[0]);
+                    }
+                }
+            }
+
+            return channel;
+        }
+
+
         private _removeDesignatedSlot(internalTexture: InternalTexture): number {
         private _removeDesignatedSlot(internalTexture: InternalTexture): number {
             let currentSlot = internalTexture._designatedSlot;
             let currentSlot = internalTexture._designatedSlot;
+
             internalTexture._designatedSlot = -1;
             internalTexture._designatedSlot = -1;
             let index = this._boundTexturesStack.indexOf(internalTexture);
             let index = this._boundTexturesStack.indexOf(internalTexture);
 
 
@@ -4778,7 +4798,18 @@
             return currentSlot;
             return currentSlot;
         }
         }
 
 
-        public _bindTextureDirectly(target: number, texture: Nullable<InternalTexture>, doNotBindUniformToTextureChannel = false): void {
+        private _activateCurrentTexture() {
+            if (this._currentTextureChannel !== this._activeChannel) {
+                this._gl.activeTexture(this._gl.TEXTURE0 + this._activeChannel);
+                this._currentTextureChannel = this._activeChannel;
+            }
+        }
+
+        protected _bindTextureDirectly(target: number, texture: Nullable<InternalTexture>, forTextureDataUpdate = false): void {
+            if (forTextureDataUpdate && texture && texture._designatedSlot > -1) {
+                this._activeChannel = texture._designatedSlot;
+            }
+
             let currentTextureBound = this._boundTexturesCache[this._activeChannel];
             let currentTextureBound = this._boundTexturesCache[this._activeChannel];
             let isTextureForRendering = texture && texture._initialSlot > -1;
             let isTextureForRendering = texture && texture._initialSlot > -1;
 
 
@@ -4787,26 +4818,28 @@
                     this._removeDesignatedSlot(currentTextureBound);
                     this._removeDesignatedSlot(currentTextureBound);
                 }
                 }
 
 
-                this._gl.bindTexture(target, texture ? texture._webGLTexture : null);
+                this._activateCurrentTexture();
 
 
-                if (this._activeChannel >= 0) {
-                    this._boundTexturesCache[this._activeChannel] = texture;
+                this._gl.bindTexture(target, texture ? texture._webGLTexture : null);
+                this._boundTexturesCache[this._activeChannel] = texture;
 
 
-                    if (isTextureForRendering && !this.disableTextureBindingOptimization) {
+                if (texture) {
+                    if (!this.disableTextureBindingOptimization) {
                         let slotIndex = this._nextFreeTextureSlots.indexOf(this._activeChannel);
                         let slotIndex = this._nextFreeTextureSlots.indexOf(this._activeChannel);
                         if (slotIndex > -1) {
                         if (slotIndex > -1) {
                             this._nextFreeTextureSlots.splice(slotIndex, 1);
                             this._nextFreeTextureSlots.splice(slotIndex, 1);
                         }
                         }
-                        this._boundTexturesStack.push(texture!);
+                        this._boundTexturesStack.push(texture);
                     }
                     }
+
+                    texture._designatedSlot = this._activeChannel;
                 }
                 }
+            } else if (forTextureDataUpdate) {
+                this._activateCurrentTexture();
             }
             }
 
 
-            if (isTextureForRendering && this._activeChannel > -1) {
-                texture!._designatedSlot = this._activeChannel;
-                if (!doNotBindUniformToTextureChannel) {
-                    this._bindSamplerUniformToChannel(texture!._initialSlot, this._activeChannel);
-                }
+            if (isTextureForRendering && !forTextureDataUpdate) {
+                this._bindSamplerUniformToChannel(texture!._initialSlot, this._activeChannel);
             }
             }
         }
         }
 
 
@@ -4819,7 +4852,7 @@
                 channel = this._getCorrectTextureChannel(channel, texture);
                 channel = this._getCorrectTextureChannel(channel, texture);
             }
             }
 
 
-            this._activateTextureChannel(channel);
+            this._activeChannel = channel;
             this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
             this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
         }
         }
 
 
@@ -4829,7 +4862,7 @@
 
 
         public unbindAllTextures(): void {
         public unbindAllTextures(): void {
             for (var channel = 0; channel < this._maxSimultaneousTextures; channel++) {
             for (var channel = 0; channel < this._maxSimultaneousTextures; channel++) {
-                this._activateTextureChannel(channel);
+                this._activeChannel = channel;
                 this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
                 this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
                 this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
                 this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
                 if (this.webGLVersion > 1) {
                 if (this.webGLVersion > 1) {
@@ -4850,47 +4883,20 @@
             this._setTexture(channel, texture);
             this._setTexture(channel, texture);
         }
         }
 
 
-        private _getCorrectTextureChannel(channel: number, internalTexture: Nullable<InternalTexture>): number {
-            if (!internalTexture) {
-                return -1;
-            }
-
-            internalTexture._initialSlot = channel;
-
-            if (this.disableTextureBindingOptimization) { // We want texture sampler ID == texture channel
-                if (channel !== internalTexture._designatedSlot) {              
-                    this._textureCollisions.addCount(1, false);
-                }
-            } else {          
-                if (channel !== internalTexture._designatedSlot) {
-                    if (internalTexture._designatedSlot > -1) { // Texture is already assigned to a slot
-                        return internalTexture._designatedSlot;
-                    } else {
-                        // No slot for this texture, let's pick a new one (if we find a free slot)
-                        if (this._nextFreeTextureSlots.length) {
-                            return this._nextFreeTextureSlots[0];
-                        }
-
-                        // We need to recycle the oldest bound texture, sorry.
-                        this._textureCollisions.addCount(1, false);
-                        return this._removeDesignatedSlot(this._boundTexturesStack[0]);
-                    }
-                }
-            }    
-
-            return channel;
-        }
-
         private _bindSamplerUniformToChannel(sourceSlot: number, destination: number) {
         private _bindSamplerUniformToChannel(sourceSlot: number, destination: number) {
             let uniform = this._boundUniforms[sourceSlot];
             let uniform = this._boundUniforms[sourceSlot];
+            if (uniform._currentState === destination) {
+                return;
+            }
             this._gl.uniform1i(uniform, destination);
             this._gl.uniform1i(uniform, destination);
+            uniform._currentState = destination;
         }
         }
 
 
         private _setTexture(channel: number, texture: Nullable<BaseTexture>, isPartOfTextureArray = false): boolean {
         private _setTexture(channel: number, texture: Nullable<BaseTexture>, isPartOfTextureArray = false): boolean {
             // Not ready?
             // Not ready?
             if (!texture) {
             if (!texture) {
                 if (this._boundTexturesCache[channel] != null) {
                 if (this._boundTexturesCache[channel] != null) {
-                    this._activateTextureChannel(channel);
+                    this._activeChannel = channel;
                     this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
                     this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
                     this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
                     this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
                     if (this.webGLVersion > 1) {
                     if (this.webGLVersion > 1) {
@@ -4901,10 +4907,8 @@
             }
             }
 
 
             // Video
             // Video
-            var alreadyActivated = false;
             if ((<VideoTexture>texture).video) {
             if ((<VideoTexture>texture).video) {
-                this._activateTextureChannel(channel);
-                alreadyActivated = true;
+                this._activeChannel = channel;
                 (<VideoTexture>texture).update();
                 (<VideoTexture>texture).update();
             } else if (texture.delayLoadState === Engine.DELAYLOADSTATE_NOTLOADED) { // Delay loading
             } else if (texture.delayLoadState === Engine.DELAYLOADSTATE_NOTLOADED) { // Delay loading
                 texture.delayLoad();
                 texture.delayLoad();
@@ -4937,9 +4941,7 @@
                 return false;
                 return false;
             }
             }
 
 
-            if (!alreadyActivated) {
-                this._activateTextureChannel(channel);
-            }
+            this._activeChannel = channel;
 
 
             if (internalTexture && internalTexture.is3D) {
             if (internalTexture && internalTexture.is3D) {
                 this._bindTextureDirectly(this._gl.TEXTURE_3D, internalTexture, isPartOfTextureArray);
                 this._bindTextureDirectly(this._gl.TEXTURE_3D, internalTexture, isPartOfTextureArray);
@@ -5267,7 +5269,7 @@
             var index = Engine.Instances.indexOf(this);
             var index = Engine.Instances.indexOf(this);
 
 
             if (index >= 0) {
             if (index >= 0) {
-                Engine.Instances.splice(index, 1);
+                delete Engine.Instances[index];
             }
             }
 
 
             this._workingCanvas = null;
             this._workingCanvas = null;
@@ -5728,7 +5730,7 @@
             let request = Tools.LoadFile(url, onSuccess, onProgress, database, useArrayBuffer, onError);
             let request = Tools.LoadFile(url, onSuccess, onProgress, database, useArrayBuffer, onError);
             this._activeRequests.push(request);
             this._activeRequests.push(request);
             request.onCompleteObservable.add(request => {
             request.onCompleteObservable.add(request => {
-                this._activeRequests.splice(this._activeRequests.indexOf(request), 1);
+                delete this._activeRequests[this._activeRequests.indexOf(request)];
             });
             });
             return request;
             return request;
         }
         }

+ 1 - 1
src/Engine/babylon.nullEngine.ts

@@ -392,7 +392,7 @@
         public updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, vertices: FloatArray, offset?: number, count?: number): void {
         public updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, vertices: FloatArray, offset?: number, count?: number): void {
         }
         }
 
 
-        public _bindTextureDirectly(target: number, texture: InternalTexture): void {
+        protected _bindTextureDirectly(target: number, texture: InternalTexture): void {
             if (this._boundTexturesCache[this._activeChannel] !== texture) {
             if (this._boundTexturesCache[this._activeChannel] !== texture) {
                 this._boundTexturesCache[this._activeChannel] = texture;
                 this._boundTexturesCache[this._activeChannel] = texture;
             }
             }

+ 1 - 1
src/Materials/Background/babylon.backgroundMaterial.ts

@@ -699,7 +699,7 @@
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, false);
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, this._shouldTurnAlphaTestOn(mesh));
 
 
             // Attribs
             // Attribs
             if (MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true, false)) {
             if (MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true, false)) {

+ 1 - 1
src/Materials/PBR/babylon.pbrBaseMaterial.ts

@@ -904,7 +904,7 @@
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._forceAlphaTest);
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest);
 
 
             // Attribs
             // Attribs
             if (MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true, this._transparencyMode !== PBRMaterial.PBRMATERIAL_OPAQUE) && mesh) {
             if (MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true, this._transparencyMode !== PBRMaterial.PBRMATERIAL_OPAQUE) && mesh) {

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

@@ -64,9 +64,9 @@ module BABYLON {
          * @param scene The scene the texture will be used in
          * @param scene The scene the texture will be used in
          * @param size The cubemap desired size (the more it increases the longer the generation will be) If the size is omitted this implies you are using a preprocessed cubemap.
          * @param size The cubemap desired size (the more it increases the longer the generation will be) If the size is omitted this implies you are using a preprocessed cubemap.
          * @param noMipmap Forces to not generate the mipmap if true
          * @param noMipmap Forces to not generate the mipmap if true
-         * @param generateHarmonics Specifies wether you want to extract the polynomial harmonics during the generation process
+         * @param generateHarmonics Specifies whether you want to extract the polynomial harmonics during the generation process
          * @param useInGammaSpace Specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space)
          * @param useInGammaSpace Specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space)
-         * @param usePMREMGenerator Specifies wether or not to generate the CubeMap through CubeMapGen to avoid seams issue at run time.
+         * @param usePMREMGenerator Specifies whether or not to generate the CubeMap through CubeMapGen to avoid seams issue at run time.
          */
          */
         constructor(url: string, scene: Scene, size?: number, noMipmap = false, generateHarmonics = true, useInGammaSpace = false, usePMREMGenerator = false, onLoad: Nullable<() => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null) {
         constructor(url: string, scene: Scene, size?: number, noMipmap = false, generateHarmonics = true, useInGammaSpace = false, usePMREMGenerator = false, onLoad: Nullable<() => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null) {
             super(scene);
             super(scene);

+ 5 - 8
src/Materials/babylon.material.ts

@@ -539,6 +539,10 @@
             }
             }
         }
         }
 
 
+        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean {
+            return (!this.needAlphaBlendingForMesh(mesh) && this.needAlphaTesting());
+        }
+
         protected _afterBind(mesh?: Mesh): void {
         protected _afterBind(mesh?: Mesh): void {
             this._scene._cachedMaterial = this;
             this._scene._cachedMaterial = this;
             if (mesh) {
             if (mesh) {
@@ -597,16 +601,14 @@
         /**
         /**
          * Force shader compilation including textures ready check
          * Force shader compilation including textures ready check
          */
          */
-        public forceCompilation(mesh: AbstractMesh, onCompiled?: (material: Material) => void, options?: Partial<{ alphaTest: Nullable<boolean>, clipPlane: boolean }>): void {
+        public forceCompilation(mesh: AbstractMesh, onCompiled?: (material: Material) => void, options?: Partial<{ clipPlane: boolean }>): void {
             let localOptions = {
             let localOptions = {
-                alphaTest: null,
                 clipPlane: false,
                 clipPlane: false,
                 ...options
                 ...options
             };
             };
 
 
             var subMesh = new BaseSubMesh();
             var subMesh = new BaseSubMesh();
             var scene = this.getScene();
             var scene = this.getScene();
-            var engine = scene.getEngine();
 
 
             var checkReady = () => {
             var checkReady = () => {
                 if (!this._scene || !this._scene.getEngine()) {
                 if (!this._scene || !this._scene.getEngine()) {
@@ -617,11 +619,8 @@
                     subMesh._materialDefines._renderId = -1;
                     subMesh._materialDefines._renderId = -1;
                 }
                 }
 
 
-                var alphaTestState = engine.getAlphaTesting();
                 var clipPlaneState = scene.clipPlane;
                 var clipPlaneState = scene.clipPlane;
 
 
-                engine.setAlphaTesting(localOptions.alphaTest || (!this.needAlphaBlendingForMesh(mesh) && this.needAlphaTesting()));
-
                 if (localOptions.clipPlane) {
                 if (localOptions.clipPlane) {
                     scene.clipPlane = new Plane(0, 0, 0, 1);
                     scene.clipPlane = new Plane(0, 0, 0, 1);
                 }
                 }
@@ -646,8 +645,6 @@
                     }
                     }
                 }
                 }
 
 
-                engine.setAlphaTesting(alphaTestState);
-
                 if (options && options.clipPlane) {
                 if (options && options.clipPlane) {
                     scene.clipPlane = clipPlaneState;
                     scene.clipPlane = clipPlaneState;
                 }
                 }

+ 10 - 2
src/Materials/babylon.materialHelper.ts

@@ -41,7 +41,15 @@
             }
             }
         }
         }
 
 
-        public static PrepareDefinesForFrameBoundValues(scene: Scene, engine: Engine, defines: any, useInstances: boolean, forceAlphaTest = false): void {
+        /**
+         * Helper used to prepare the list of defines for shader compilation
+         * @param scene defines the current scene
+         * @param engine defines the current engine
+         * @param defines specifies the list of active defines
+         * @param useInstances defines if instances have to be turned on
+         * @param alphaTest defines if alpha testing has to be turned on
+         */
+        public static PrepareDefinesForFrameBoundValues(scene: Scene, engine: Engine, defines: any, useInstances: boolean, alphaTest: boolean): void {
             var changed = false;
             var changed = false;
 
 
             if (defines["CLIPPLANE"] !== (scene.clipPlane !== undefined && scene.clipPlane !== null)) {
             if (defines["CLIPPLANE"] !== (scene.clipPlane !== undefined && scene.clipPlane !== null)) {
@@ -49,7 +57,7 @@
                 changed = true;
                 changed = true;
             }
             }
 
 
-            if (defines["ALPHATEST"] !== (engine.getAlphaTesting() || forceAlphaTest)) {
+            if (defines["ALPHATEST"] !== alphaTest) {
                 defines["ALPHATEST"] = !defines["ALPHATEST"];
                 defines["ALPHATEST"] = !defines["ALPHATEST"];
                 changed = true;
                 changed = true;
             }
             }

+ 1 - 1
src/Materials/babylon.shaderMaterial.ts

@@ -247,7 +247,7 @@
             }
             }
 
 
             // Alpha test
             // Alpha test
-            if (engine.getAlphaTesting()) {
+            if (mesh && this._shouldTurnAlphaTestOn(mesh)) {
                 defines.push("#define ALPHATEST");
                 defines.push("#define ALPHATEST");
             }
             }
 
 

+ 1 - 1
src/Materials/babylon.standardMaterial.ts

@@ -745,7 +745,7 @@ module BABYLON {
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, this._shouldTurnAlphaTestOn(mesh));
 
 
             // Get correct effect      
             // Get correct effect      
             if (defines.isDirty) {
             if (defines.isDirty) {

+ 0 - 8
src/Mesh/babylon.mesh.ts

@@ -623,28 +623,20 @@
 
 
             let mat = this.material || scene.defaultMaterial;
             let mat = this.material || scene.defaultMaterial;
             if (mat) {
             if (mat) {
-                let currentAlphaTestingState = engine.getAlphaTesting();
-
                 if (mat.storeEffectOnSubMeshes) {
                 if (mat.storeEffectOnSubMeshes) {
                     for (var subMesh of this.subMeshes) {
                     for (var subMesh of this.subMeshes) {
                         let effectiveMaterial = subMesh.getMaterial();
                         let effectiveMaterial = subMesh.getMaterial();
                         if (effectiveMaterial) {
                         if (effectiveMaterial) {
-                            engine.setAlphaTesting(effectiveMaterial.needAlphaTesting() && !effectiveMaterial.needAlphaBlendingForMesh(this));
                             if (!effectiveMaterial.isReadyForSubMesh(this, subMesh, hardwareInstancedRendering)) {
                             if (!effectiveMaterial.isReadyForSubMesh(this, subMesh, hardwareInstancedRendering)) {
-                                engine.setAlphaTesting(currentAlphaTestingState);
                                 return false;
                                 return false;
                             }
                             }
                         }
                         }
                     }
                     }
                 } else {
                 } else {
-                    engine.setAlphaTesting(mat.needAlphaTesting() && !mat.needAlphaBlendingForMesh(this));
                     if (!mat.isReady(this, hardwareInstancedRendering)) {
                     if (!mat.isReady(this, hardwareInstancedRendering)) {
-                        engine.setAlphaTesting(currentAlphaTestingState);
                         return false;
                         return false;
                     }
                     }
                 }
                 }
-
-                engine.setAlphaTesting(currentAlphaTestingState);
             }
             }
 
 
             // Shadows
             // Shadows

+ 0 - 2
src/PostProcess/babylon.volumetricLightScatteringPostProcess.ts

@@ -358,11 +358,9 @@
                     renderSubMesh(opaqueSubMeshes.data[index]);
                     renderSubMesh(opaqueSubMeshes.data[index]);
                 }
                 }
 
 
-                engine.setAlphaTesting(true);
                 for (index = 0; index < alphaTestSubMeshes.length; index++) {
                 for (index = 0; index < alphaTestSubMeshes.length; index++) {
                     renderSubMesh(alphaTestSubMeshes.data[index]);
                     renderSubMesh(alphaTestSubMeshes.data[index]);
                 }
                 }
-                engine.setAlphaTesting(false);
 
 
                 if (transparentSubMeshes.length) {
                 if (transparentSubMeshes.length) {
                     // Sort sub meshes
                     // Sort sub meshes

+ 14 - 20
src/Rendering/babylon.renderingGroup.ts

@@ -6,12 +6,12 @@
         private _alphaTestSubMeshes = new SmartArray<SubMesh>(256);
         private _alphaTestSubMeshes = new SmartArray<SubMesh>(256);
         private _depthOnlySubMeshes = new SmartArray<SubMesh>(256);
         private _depthOnlySubMeshes = new SmartArray<SubMesh>(256);
         private _particleSystems = new SmartArray<IParticleSystem>(256);
         private _particleSystems = new SmartArray<IParticleSystem>(256);
-        private _spriteManagers = new SmartArray<SpriteManager>(256);        
+        private _spriteManagers = new SmartArray<SpriteManager>(256);
 
 
         private _opaqueSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number>;
         private _opaqueSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number>;
         private _alphaTestSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number>;
         private _alphaTestSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number>;
         private _transparentSortCompareFn: (a: SubMesh, b: SubMesh) => number;
         private _transparentSortCompareFn: (a: SubMesh, b: SubMesh) => number;
-        
+
         private _renderOpaque: (subMeshes: SmartArray<SubMesh>) => void;
         private _renderOpaque: (subMeshes: SmartArray<SubMesh>) => void;
         private _renderAlphaTest: (subMeshes: SmartArray<SubMesh>) => void;
         private _renderAlphaTest: (subMeshes: SmartArray<SubMesh>) => void;
         private _renderTransparent: (subMeshes: SmartArray<SubMesh>) => void;
         private _renderTransparent: (subMeshes: SmartArray<SubMesh>) => void;
@@ -77,7 +77,7 @@
 
 
             this.opaqueSortCompareFn = opaqueSortCompareFn;
             this.opaqueSortCompareFn = opaqueSortCompareFn;
             this.alphaTestSortCompareFn = alphaTestSortCompareFn;
             this.alphaTestSortCompareFn = alphaTestSortCompareFn;
-            this.transparentSortCompareFn = transparentSortCompareFn;            
+            this.transparentSortCompareFn = transparentSortCompareFn;
         }
         }
 
 
         /**
         /**
@@ -95,13 +95,11 @@
 
 
             // Depth only
             // Depth only
             if (this._depthOnlySubMeshes.length !== 0) {
             if (this._depthOnlySubMeshes.length !== 0) {
-                engine.setAlphaTesting(true);
                 engine.setColorWrite(false);
                 engine.setColorWrite(false);
                 this._renderAlphaTest(this._depthOnlySubMeshes);
                 this._renderAlphaTest(this._depthOnlySubMeshes);
-                engine.setAlphaTesting(false);
                 engine.setColorWrite(true);
                 engine.setColorWrite(true);
-            }            
-            
+            }
+
             // Opaque
             // Opaque
             if (this._opaqueSubMeshes.length !== 0) {
             if (this._opaqueSubMeshes.length !== 0) {
                 this._renderOpaque(this._opaqueSubMeshes);
                 this._renderOpaque(this._opaqueSubMeshes);
@@ -109,9 +107,7 @@
 
 
             // Alpha test
             // Alpha test
             if (this._alphaTestSubMeshes.length !== 0) {
             if (this._alphaTestSubMeshes.length !== 0) {
-                engine.setAlphaTesting(true);
                 this._renderAlphaTest(this._alphaTestSubMeshes);
                 this._renderAlphaTest(this._alphaTestSubMeshes);
-                engine.setAlphaTesting(false);
             }
             }
 
 
             var stencilState = engine.getStencilBuffer();
             var stencilState = engine.getStencilBuffer();
@@ -121,7 +117,7 @@
             if (renderSprites) {
             if (renderSprites) {
                 this._renderSprites();
                 this._renderSprites();
             }
             }
-            
+
             // Particles
             // Particles
             if (renderParticles) {
             if (renderParticles) {
                 this._renderParticles(activeMeshes);
                 this._renderParticles(activeMeshes);
@@ -205,10 +201,8 @@
                     if (material && material.needDepthPrePass) {
                     if (material && material.needDepthPrePass) {
                         let engine = material.getScene().getEngine();
                         let engine = material.getScene().getEngine();
                         engine.setColorWrite(false);
                         engine.setColorWrite(false);
-                        engine.setAlphaTesting(true);
                         engine.setAlphaMode(Engine.ALPHA_DISABLE);
                         engine.setAlphaMode(Engine.ALPHA_DISABLE);
                         subMesh.render(false);
                         subMesh.render(false);
-                        engine.setAlphaTesting(false);
                         engine.setColorWrite(true);
                         engine.setColorWrite(true);
                     }
                     }
                 }
                 }
@@ -236,7 +230,7 @@
          * @param b The second submesh
          * @param b The second submesh
          * @returns The result of the comparison
          * @returns The result of the comparison
          */
          */
-        public static defaultTransparentSortCompare(a: SubMesh, b:SubMesh) : number {
+        public static defaultTransparentSortCompare(a: SubMesh, b: SubMesh): number {
             // Alpha index first
             // Alpha index first
             if (a._alphaIndex > b._alphaIndex) {
             if (a._alphaIndex > b._alphaIndex) {
                 return 1;
                 return 1;
@@ -257,7 +251,7 @@
          * @param b The second submesh
          * @param b The second submesh
          * @returns The result of the comparison
          * @returns The result of the comparison
          */
          */
-        public static backToFrontSortCompare(a: SubMesh, b:SubMesh) : number {
+        public static backToFrontSortCompare(a: SubMesh, b: SubMesh): number {
             // Then distance to camera
             // Then distance to camera
             if (a._distanceToCamera < b._distanceToCamera) {
             if (a._distanceToCamera < b._distanceToCamera) {
                 return 1;
                 return 1;
@@ -277,7 +271,7 @@
          * @param b The second submesh
          * @param b The second submesh
          * @returns The result of the comparison
          * @returns The result of the comparison
          */
          */
-        public static frontToBackSortCompare(a: SubMesh, b:SubMesh) : number {
+        public static frontToBackSortCompare(a: SubMesh, b: SubMesh): number {
             // Then distance to camera
             // Then distance to camera
             if (a._distanceToCamera < b._distanceToCamera) {
             if (a._distanceToCamera < b._distanceToCamera) {
                 return -1;
                 return -1;
@@ -298,7 +292,7 @@
             this._alphaTestSubMeshes.reset();
             this._alphaTestSubMeshes.reset();
             this._depthOnlySubMeshes.reset();
             this._depthOnlySubMeshes.reset();
             this._particleSystems.reset();
             this._particleSystems.reset();
-            this._spriteManagers.reset();            
+            this._spriteManagers.reset();
             this._edgesRenderers.reset();
             this._edgesRenderers.reset();
         }
         }
 
 
@@ -308,7 +302,7 @@
             this._alphaTestSubMeshes.dispose();
             this._alphaTestSubMeshes.dispose();
             this._depthOnlySubMeshes.dispose();
             this._depthOnlySubMeshes.dispose();
             this._particleSystems.dispose();
             this._particleSystems.dispose();
-            this._spriteManagers.dispose();                      
+            this._spriteManagers.dispose();
             this._edgesRenderers.dispose();
             this._edgesRenderers.dispose();
         }
         }
 
 
@@ -337,13 +331,13 @@
                 if (material.needDepthPrePass) {
                 if (material.needDepthPrePass) {
                     this._depthOnlySubMeshes.push(subMesh);
                     this._depthOnlySubMeshes.push(subMesh);
                 }
                 }
-                
+
                 this._alphaTestSubMeshes.push(subMesh);
                 this._alphaTestSubMeshes.push(subMesh);
             } else {
             } else {
                 if (material.needDepthPrePass) {
                 if (material.needDepthPrePass) {
                     this._depthOnlySubMeshes.push(subMesh);
                     this._depthOnlySubMeshes.push(subMesh);
                 }
                 }
-                
+
                 this._opaqueSubMeshes.push(subMesh); // Opaque
                 this._opaqueSubMeshes.push(subMesh); // Opaque
             }
             }
 
 
@@ -381,7 +375,7 @@
                 }
                 }
             }
             }
             this._scene.onAfterParticlesRenderingObservable.notifyObservers(this._scene);
             this._scene.onAfterParticlesRenderingObservable.notifyObservers(this._scene);
-            
+
         }
         }
 
 
         private _renderSprites(): void {
         private _renderSprites(): void {

+ 576 - 58
src/Tools/babylon.assetsManager.ts

@@ -1,26 +1,99 @@
 module BABYLON {
 module BABYLON {
 
 
+    /**
+     * Defines the list of states available for a task inside a {BABYLON.AssetsManager}
+     */
     export enum AssetTaskState {
     export enum AssetTaskState {
+        /**
+         * Initialization
+         */
         INIT,
         INIT,
+        /**
+         * Running
+         */
         RUNNING,
         RUNNING,
+        /**
+         * Done
+         */
         DONE,
         DONE,
+        /**
+         * Error
+         */
         ERROR
         ERROR
     }
     }
 
 
+    /**
+     * Define an abstract asset task used with a {BABYLON.AssetsManager} class to load assets into a scene
+     */
     export abstract class AbstractAssetTask {
     export abstract class AbstractAssetTask {
+        /**
+         * Callback called when the task is successful
+         */
         public onSuccess: (task: any) => void;
         public onSuccess: (task: any) => void;
+
+        /**
+         * Callback called when the task is successful
+         */
         public onError: (task: any, message?: string, exception?: any) => void;
         public onError: (task: any, message?: string, exception?: any) => void;
 
 
-        constructor(public name: string) {
-            this.taskState = AssetTaskState.INIT;
+        /**
+         * Creates a new {BABYLON.AssetsManager}
+         * @param name defines the name of the task
+         */
+        constructor(
+            /**
+             * Task name
+             */public name: string) {
         }
         }
 
 
-        isCompleted: boolean = false;
-        taskState: AssetTaskState;
-        errorObject: { message?: string; exception?: any; };
+        private _isCompleted = false;
+        private _taskState = AssetTaskState.INIT;
+        private _errorObject: { message?: string; exception?: any; };
+
+        /**
+         * Get if the task is completed
+         */
+        public get isCompleted(): boolean {
+            return this._isCompleted;
+        }
+
+        /**
+         * Gets the current state of the task
+         */
+        public get taskState(): AssetTaskState {
+            return this._taskState;
+        }
+
+        /**
+         * Gets the current error object (if task is in error)
+         */
+        public get errorObject(): { message?: string; exception?: any; } {
+            return this._errorObject;
+        }
+
+        /**
+         * Internal only
+         * @ignore 
+         */
+        public _setErrorObject(message?: string, exception?: any) {
+            if (this._errorObject) {
+                return;
+            }
 
 
-        run(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
-            this.taskState = AssetTaskState.RUNNING;
+            this._errorObject = {
+                message: message,
+                exception: exception
+            };
+        }
+
+        /**
+         * Execute the current task
+         * @param scene defines the scene where you want your assets to be loaded
+         * @param onSuccess is a callback called when the task is successfully executed
+         * @param onError is a callback called if an error occurs
+         */
+        public run(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
+            this._taskState = AssetTaskState.RUNNING;
             this.runTask(scene, () => {
             this.runTask(scene, () => {
                 this.onDoneCallback(onSuccess, onError);
                 this.onDoneCallback(onSuccess, onError);
             }, (msg, exception) => {
             }, (msg, exception) => {
@@ -28,14 +101,20 @@ module BABYLON {
             });
             });
         }
         }
 
 
+        /**
+         * Execute the current task
+         * @param scene defines the scene where you want your assets to be loaded
+         * @param onSuccess is a callback called when the task is successfully executed
+         * @param onError is a callback called if an error occurs
+         */
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
             throw new Error("runTask is not implemented");
             throw new Error("runTask is not implemented");
         }
         }
 
 
         private onErrorCallback(onError: (message?: string, exception?: any) => void, message?: string, exception?: any) {
         private onErrorCallback(onError: (message?: string, exception?: any) => void, message?: string, exception?: any) {
-            this.taskState = AssetTaskState.ERROR;
+            this._taskState = AssetTaskState.ERROR;
 
 
-            this.errorObject = {
+            this._errorObject = {
                 message: message,
                 message: message,
                 exception: exception
                 exception: exception
             }
             }
@@ -49,8 +128,8 @@ module BABYLON {
 
 
         private onDoneCallback(onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
         private onDoneCallback(onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
             try {
             try {
-                this.taskState = AssetTaskState.DONE;
-                this.isCompleted = true;
+                this._taskState = AssetTaskState.DONE;
+                this._isCompleted = true;
 
 
                 if (this.onSuccess) {
                 if (this.onSuccess) {
                     this.onSuccess(this);
                     this.onSuccess(this);
@@ -64,17 +143,47 @@ module BABYLON {
 
 
     }
     }
 
 
+    /**
+     * Define the interface used by progress events raised during assets loading
+     */
     export interface IAssetsProgressEvent {
     export interface IAssetsProgressEvent {
+        /**
+         * Defines the number of remaining tasks to process
+         */
         remainingCount: number;
         remainingCount: number;
+        /**
+         * Defines the total number of tasks
+         */
         totalCount: number;
         totalCount: number;
+        /**
+         * Defines the task that was just processed
+         */
         task: AbstractAssetTask;
         task: AbstractAssetTask;
     }
     }
 
 
+    /**
+     * Class used to share progress information about assets loading
+     */
     export class AssetsProgressEvent implements IAssetsProgressEvent {
     export class AssetsProgressEvent implements IAssetsProgressEvent {
-        remainingCount: number;
-        totalCount: number;
-        task: AbstractAssetTask;
-
+        /**
+         * Defines the number of remaining tasks to process
+         */
+        public remainingCount: number;
+        /**
+         * Defines the total number of tasks
+         */
+        public totalCount: number;
+        /**
+         * Defines the task that was just processed
+         */
+        public task: AbstractAssetTask;
+
+        /**
+         * Creates a {BABYLON.AssetsProgressEvent}
+         * @param remainingCount defines the number of remaining tasks to process
+         * @param totalCount defines the total number of tasks
+         * @param task defines the task that was just processed
+         */
         constructor(remainingCount: number, totalCount: number, task: AbstractAssetTask) {
         constructor(remainingCount: number, totalCount: number, task: AbstractAssetTask) {
             this.remainingCount = remainingCount;
             this.remainingCount = remainingCount;
             this.totalCount = totalCount;
             this.totalCount = totalCount;
@@ -82,18 +191,66 @@ module BABYLON {
         }
         }
     }
     }
 
 
+    /**
+     * Define a task used by {BABYLON.AssetsManager} to load meshes
+     */
     export class MeshAssetTask extends AbstractAssetTask {
     export class MeshAssetTask extends AbstractAssetTask {
+        /**
+         * Gets the list of loaded meshes
+         */
         public loadedMeshes: Array<AbstractMesh>;
         public loadedMeshes: Array<AbstractMesh>;
+        /**
+         * Gets the list of loaded particle systems
+         */
         public loadedParticleSystems: Array<ParticleSystem>;
         public loadedParticleSystems: Array<ParticleSystem>;
+        /**
+         * Gets the list of loaded skeletons
+         */
         public loadedSkeletons: Array<Skeleton>;
         public loadedSkeletons: Array<Skeleton>;
 
 
+        /**
+         * Callback called when the task is successful
+         */
         public onSuccess: (task: MeshAssetTask) => void;
         public onSuccess: (task: MeshAssetTask) => void;
+
+        /**
+         * Callback called when the task is successful
+         */
         public onError: (task: MeshAssetTask, message?: string, exception?: any) => void;
         public onError: (task: MeshAssetTask, message?: string, exception?: any) => void;
 
 
-        constructor(public name: string, public meshesNames: any, public rootUrl: string, public sceneFilename: string) {
+        /**
+         * Creates a new {BABYLON.MeshAssetTask}
+         * @param name defines the name of the task
+         * @param meshesNames defines the list of mesh's names you want to load
+         * @param rootUrl defines the root url to use as a base to load your meshes and associated resources
+         * @param sceneFilename defines the filename of the scene to load from
+         */
+        constructor(
+            /**
+             * Defines the name of the task
+             */
+            public name: string,
+            /**
+             * Defines the list of mesh's names you want to load
+             */
+            public meshesNames: any,
+            /**
+             * Defines the root url to use as a base to load your meshes and associated resources
+             */
+            public rootUrl: string,
+            /**
+             * Defines the filename of the scene to load from
+             */
+            public sceneFilename: string) {
             super(name);
             super(name);
         }
         }
 
 
+        /**
+         * Execute the current task
+         * @param scene defines the scene where you want your assets to be loaded
+         * @param onSuccess is a callback called when the task is successfully executed
+         * @param onError is a callback called if an error occurs
+         */
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
             SceneLoader.ImportMesh(this.meshesNames, this.rootUrl, this.sceneFilename, scene,
             SceneLoader.ImportMesh(this.meshesNames, this.rootUrl, this.sceneFilename, scene,
                 (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => {
                 (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => {
@@ -108,16 +265,48 @@ module BABYLON {
         }
         }
     }
     }
 
 
+    /**
+     * Define a task used by {BABYLON.AssetsManager} to load text content
+     */
     export class TextFileAssetTask extends AbstractAssetTask {
     export class TextFileAssetTask extends AbstractAssetTask {
+        /**
+         * Gets the loaded text string
+         */
         public text: string;
         public text: string;
 
 
+        /**
+         * Callback called when the task is successful
+         */
         public onSuccess: (task: TextFileAssetTask) => void;
         public onSuccess: (task: TextFileAssetTask) => void;
+
+        /**
+         * Callback called when the task is successful
+         */
         public onError: (task: TextFileAssetTask, message?: string, exception?: any) => void;
         public onError: (task: TextFileAssetTask, message?: string, exception?: any) => void;
 
 
-        constructor(public name: string, public url: string) {
+        /**
+         * Creates a new TextFileAssetTask object
+         * @param name defines the name of the task
+         * @param url defines the location of the file to load
+         */
+        constructor(
+            /**
+             * Defines the name of the task
+             */
+            public name: string,
+            /**
+             * Defines the location of the file to load
+             */
+            public url: string) {
             super(name);
             super(name);
         }
         }
 
 
+        /**
+         * Execute the current task
+         * @param scene defines the scene where you want your assets to be loaded
+         * @param onSuccess is a callback called when the task is successfully executed
+         * @param onError is a callback called if an error occurs
+         */
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
             scene._loadFile(this.url, (data) => {
             scene._loadFile(this.url, (data) => {
                 this.text = data as string;
                 this.text = data as string;
@@ -130,16 +319,47 @@ module BABYLON {
         }
         }
     }
     }
 
 
+    /**
+     * Define a task used by {BABYLON.AssetsManager} to load binary data
+     */
     export class BinaryFileAssetTask extends AbstractAssetTask {
     export class BinaryFileAssetTask extends AbstractAssetTask {
+        /**
+         * Gets the lodaded data (as an array buffer)
+         */
         public data: ArrayBuffer;
         public data: ArrayBuffer;
 
 
+        /**
+         * Callback called when the task is successful
+         */
         public onSuccess: (task: BinaryFileAssetTask) => void;
         public onSuccess: (task: BinaryFileAssetTask) => void;
+        /**
+         * Callback called when the task is successful
+         */
         public onError: (task: BinaryFileAssetTask, message?: string, exception?: any) => void;
         public onError: (task: BinaryFileAssetTask, message?: string, exception?: any) => void;
 
 
-        constructor(public name: string, public url: string) {
+        /**
+         * Creates a new BinaryFileAssetTask object
+         * @param name defines the name of the new task
+         * @param url defines the location of the file to load
+         */
+        constructor(
+            /**
+             * Defines the name of the task
+             */
+            public name: string,
+            /**
+             * Defines the location of the file to load
+             */
+            public url: string) {
             super(name);
             super(name);
         }
         }
 
 
+        /**
+         * Execute the current task
+         * @param scene defines the scene where you want your assets to be loaded
+         * @param onSuccess is a callback called when the task is successfully executed
+         * @param onError is a callback called if an error occurs
+         */
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
             scene._loadFile(this.url, (data) => {
             scene._loadFile(this.url, (data) => {
                 this.data = data as ArrayBuffer;
                 this.data = data as ArrayBuffer;
@@ -152,16 +372,47 @@ module BABYLON {
         }
         }
     }
     }
 
 
+    /**
+     * Define a task used by {BABYLON.AssetsManager} to load images
+     */
     export class ImageAssetTask extends AbstractAssetTask {
     export class ImageAssetTask extends AbstractAssetTask {
+        /**
+         * Gets the loaded images
+         */
         public image: HTMLImageElement;
         public image: HTMLImageElement;
 
 
+        /**
+         * Callback called when the task is successful
+         */
         public onSuccess: (task: ImageAssetTask) => void;
         public onSuccess: (task: ImageAssetTask) => void;
+        /**
+         * Callback called when the task is successful
+         */
         public onError: (task: ImageAssetTask, message?: string, exception?: any) => void;
         public onError: (task: ImageAssetTask, message?: string, exception?: any) => void;
 
 
-        constructor(public name: string, public url: string) {
+        /**
+         * Creates a new ImageAssetTask
+         * @param name defines the name of the task
+         * @param url defines the location of the image to load
+         */
+        constructor(
+            /**
+             * Defines the name of the task
+             */
+            public name: string,
+            /**
+             * Defines the location of the image to load
+             */
+            public url: string) {
             super(name);
             super(name);
         }
         }
 
 
+        /**
+         * Execute the current task
+         * @param scene defines the scene where you want your assets to be loaded
+         * @param onSuccess is a callback called when the task is successfully executed
+         * @param onError is a callback called if an error occurs
+         */
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
             var img = new Image();
             var img = new Image();
 
 
@@ -180,20 +431,72 @@ module BABYLON {
         }
         }
     }
     }
 
 
+    /**
+     * Defines the interface used by texture loading tasks
+     */
     export interface ITextureAssetTask<TEX extends BaseTexture> {
     export interface ITextureAssetTask<TEX extends BaseTexture> {
+        /**
+         * Gets the loaded texture
+         */
         texture: TEX;
         texture: TEX;
     }
     }
 
 
+    /**
+     * Define a task used by {BABYLON.AssetsManager} to load 2D textures
+     */
     export class TextureAssetTask extends AbstractAssetTask implements ITextureAssetTask<Texture> {
     export class TextureAssetTask extends AbstractAssetTask implements ITextureAssetTask<Texture> {
+        /**
+         * Gets the loaded texture
+         */
         public texture: Texture;
         public texture: Texture;
 
 
+        /**
+         * Callback called when the task is successful
+         */
         public onSuccess: (task: TextureAssetTask) => void;
         public onSuccess: (task: TextureAssetTask) => void;
+        /**
+         * Callback called when the task is successful
+         */
         public onError: (task: TextureAssetTask, message?: string, exception?: any) => void;
         public onError: (task: TextureAssetTask, message?: string, exception?: any) => void;
 
 
-        constructor(public name: string, public url: string, public noMipmap?: boolean, public invertY?: boolean, public samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE) {
+        /**
+         * Creates a new TextureAssetTask object
+         * @param name defines the name of the task
+         * @param url defines the location of the file to load
+         * @param noMipmap defines if mipmap should not be generated (default is false)
+         * @param invertY defines if texture must be inverted on Y axis (default is false)
+         * @param samplingMode defines the sampling mode to use (default is BABYLON.Texture.TRILINEAR_SAMPLINGMODE)
+         */
+        constructor(
+            /**
+             * Defines the name of the task
+             */
+            public name: string,
+            /**
+             * Defines the location of the file to load
+             */
+            public url: string,
+            /**
+             * Defines if mipmap should not be generated (default is false)
+             */
+            public noMipmap?: boolean,
+            /**
+             * Defines if texture must be inverted on Y axis (default is false)
+             */
+            public invertY?: boolean,
+            /**
+             * Defines the sampling mode to use (default is BABYLON.Texture.TRILINEAR_SAMPLINGMODE)
+             */
+            public samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE) {
             super(name);
             super(name);
         }
         }
 
 
+        /**
+         * Execute the current task
+         * @param scene defines the scene where you want your assets to be loaded
+         * @param onSuccess is a callback called when the task is successfully executed
+         * @param onError is a callback called if an error occurs
+         */
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
 
 
             var onload = () => {
             var onload = () => {
@@ -208,16 +511,62 @@ module BABYLON {
         }
         }
     }
     }
 
 
+    /**
+     * Define a task used by {BABYLON.AssetsManager} to load cube textures
+     */
     export class CubeTextureAssetTask extends AbstractAssetTask implements ITextureAssetTask<CubeTexture> {
     export class CubeTextureAssetTask extends AbstractAssetTask implements ITextureAssetTask<CubeTexture> {
+        /**
+         * Gets the loaded texture
+         */
         public texture: CubeTexture;
         public texture: CubeTexture;
 
 
+        /**
+         * Callback called when the task is successful
+         */
         public onSuccess: (task: CubeTextureAssetTask) => void;
         public onSuccess: (task: CubeTextureAssetTask) => void;
+        /**
+         * Callback called when the task is successful
+         */
         public onError: (task: CubeTextureAssetTask, message?: string, exception?: any) => void;
         public onError: (task: CubeTextureAssetTask, message?: string, exception?: any) => void;
 
 
-        constructor(public name: string, public url: string, public extensions?: string[], public noMipmap?: boolean, public files?: string[]) {
+        /**
+         * Creates a new CubeTextureAssetTask
+         * @param name defines the name of the task
+         * @param url defines the location of the files to load (You have to specify the folder where the files are + filename with no extension)
+         * @param extensions defines the extensions to use to load files (["_px", "_py", "_pz", "_nx", "_ny", "_nz"] by default)
+         * @param noMipmap defines if mipmaps should not be generated (default is false)
+         * @param files defines the explicit list of files (undefined by default)
+         */
+        constructor(
+            /**
+             * Defines the name of the task
+             */
+            public name: string,
+            /**
+             * Defines the location of the files to load (You have to specify the folder where the files are + filename with no extension)
+             */
+            public url: string,
+            /**
+             * Defines the extensions to use to load files (["_px", "_py", "_pz", "_nx", "_ny", "_nz"] by default)
+             */
+            public extensions?: string[],
+            /**
+             * Defines if mipmaps should not be generated (default is false)
+             */
+            public noMipmap?: boolean,
+            /**
+             * Defines the explicit list of files (undefined by default)
+             */
+            public files?: string[]) {
             super(name);
             super(name);
         }
         }
 
 
+        /**
+         * Execute the current task
+         * @param scene defines the scene where you want your assets to be loaded
+         * @param onSuccess is a callback called when the task is successfully executed
+         * @param onError is a callback called if an error occurs
+         */
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
         public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
 
 
             var onload = () => {
             var onload = () => {
@@ -232,16 +581,72 @@ module BABYLON {
         }
         }
     }
     }
 
 
+    /**
+     * Define a task used by {BABYLON.AssetsManager} to load HDR cube textures
+     */
     export class HDRCubeTextureAssetTask extends AbstractAssetTask implements ITextureAssetTask<HDRCubeTexture> {
     export class HDRCubeTextureAssetTask extends AbstractAssetTask implements ITextureAssetTask<HDRCubeTexture> {
+        /**
+         * Gets the loaded texture
+         */
         public texture: HDRCubeTexture;
         public texture: HDRCubeTexture;
 
 
+        /**
+         * Callback called when the task is successful
+         */
         public onSuccess: (task: HDRCubeTextureAssetTask) => void;
         public onSuccess: (task: HDRCubeTextureAssetTask) => void;
+        /**
+         * Callback called when the task is successful
+         */
         public onError: (task: HDRCubeTextureAssetTask, message?: string, exception?: any) => void;
         public onError: (task: HDRCubeTextureAssetTask, message?: string, exception?: any) => void;
 
 
-        constructor(public name: string, public url: string, public size?: number, public noMipmap = false, public generateHarmonics = true, public useInGammaSpace = false, public usePMREMGenerator = false) {
+        /**
+         * Creates a new HDRCubeTextureAssetTask object
+         * @param name defines the name of the task
+         * @param url defines the location of the file to load
+         * @param size defines the desired size (the more it increases the longer the generation will be) If the size is omitted this implies you are using a preprocessed cubemap.
+         * @param noMipmap defines if mipmaps should not be generated (default is false)
+         * @param generateHarmonics specifies whether you want to extract the polynomial harmonics during the generation process (default is true)
+         * @param useInGammaSpace specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space) (default is false)
+         * @param usePMREMGenerator specifies whether or not to generate the CubeMap through CubeMapGen to avoid seams issue at run time (default is false)
+         */
+        constructor(
+            /**
+             * Defines the name of the task
+             */
+            public name: string,
+            /**
+             * Defines the location of the file to load
+             */
+            public url: string,
+            /**
+             * Defines the desired size (the more it increases the longer the generation will be) If the size is omitted this implies you are using a preprocessed cubemap.
+             */
+            public size?: number,
+            /**
+             * Defines if mipmaps should not be generated (default is false)
+             */
+            public noMipmap = false,
+            /**
+             * Specifies whether you want to extract the polynomial harmonics during the generation process (default is true)
+             */
+            public generateHarmonics = true,
+            /**
+             * Specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space) (default is false)
+             */
+            public useInGammaSpace = false,
+            /**
+             * Specifies whether or not to generate the CubeMap through CubeMapGen to avoid seams issue at run time (default is false)
+             */
+            public usePMREMGenerator = false) {
             super(name);
             super(name);
         }
         }
 
 
+        /**
+         * Execute the current task
+         * @param scene defines the scene where you want your assets to be loaded
+         * @param onSuccess is a callback called when the task is successfully executed
+         * @param onError is a callback called if an error occurs
+         */
         public run(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
         public run(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
 
 
             var onload = () => {
             var onload = () => {
@@ -256,97 +661,204 @@ module BABYLON {
         }
         }
     }
     }
 
 
+    /**
+     * This class can be used to easily import assets into a scene
+     * @see http://doc.babylonjs.com/how_to/how_to_use_assetsmanager
+     */
     export class AssetsManager {
     export class AssetsManager {
         private _scene: Scene;
         private _scene: Scene;
         private _isLoading = false;
         private _isLoading = false;
 
 
-        protected tasks = new Array<AbstractAssetTask>();
-        protected waitingTasksCount = 0;
+        protected _tasks = new Array<AbstractAssetTask>();
+        protected _waitingTasksCount = 0;
+        protected _totalTasksCount = 0;
 
 
+        /**
+         * Callback called when all tasks are processed
+         */
         public onFinish: (tasks: AbstractAssetTask[]) => void;
         public onFinish: (tasks: AbstractAssetTask[]) => void;
+
+        /**
+         * Callback called when a task is successful
+         */
         public onTaskSuccess: (task: AbstractAssetTask) => void;
         public onTaskSuccess: (task: AbstractAssetTask) => void;
+
+        /**
+         * Callback called when a task had an error
+         */
         public onTaskError: (task: AbstractAssetTask) => void;
         public onTaskError: (task: AbstractAssetTask) => void;
-        public onProgress: (remainingCount: number, totalCount: number, task: AbstractAssetTask) => void;
 
 
-        //Observables
+        /**
+         * Callback called when a task is done (whatever the result is)
+         */
+        public onProgress: (remainingCount: number, totalCount: number, task: AbstractAssetTask) => void;
 
 
+        /**
+         * Observable called when all tasks are processed
+         */
         public onTaskSuccessObservable = new Observable<AbstractAssetTask>();
         public onTaskSuccessObservable = new Observable<AbstractAssetTask>();
+
+        /**
+         * Observable called when a task had an error
+         */
         public onTaskErrorObservable = new Observable<AbstractAssetTask>();
         public onTaskErrorObservable = new Observable<AbstractAssetTask>();
+
+        /**
+         * Observable called when a task is successful
+         */
         public onTasksDoneObservable = new Observable<AbstractAssetTask[]>();
         public onTasksDoneObservable = new Observable<AbstractAssetTask[]>();
+
+        /**
+         * Observable called when a task is done (whatever the result is)
+         */
         public onProgressObservable = new Observable<IAssetsProgressEvent>();
         public onProgressObservable = new Observable<IAssetsProgressEvent>();
 
 
+        /**
+         * Gets or sets a boolean defining if the {BABYLON.AssetsManager} should use the default loading screen
+         * @see http://doc.babylonjs.com/how_to/creating_a_custom_loading_screen
+         */
         public useDefaultLoadingScreen = true;
         public useDefaultLoadingScreen = true;
 
 
+        /**
+         * Creates a new AssetsManager
+         * @param scene defines the scene to work on
+         */
         constructor(scene: Scene) {
         constructor(scene: Scene) {
             this._scene = scene;
             this._scene = scene;
         }
         }
 
 
+        /**
+         * Add a {BABYLON.MeshAssetTask} to the list of active tasks
+         * @param taskName defines the name of the new task
+         * @param meshesNames defines the name of meshes to load
+         * @param rootUrl defines the root url to use to locate files
+         * @param sceneFilename defines the filename of the scene file
+         * @returns a new {BABYLON.MeshAssetTask} object
+         */
         public addMeshTask(taskName: string, meshesNames: any, rootUrl: string, sceneFilename: string): MeshAssetTask {
         public addMeshTask(taskName: string, meshesNames: any, rootUrl: string, sceneFilename: string): MeshAssetTask {
             var task = new MeshAssetTask(taskName, meshesNames, rootUrl, sceneFilename);
             var task = new MeshAssetTask(taskName, meshesNames, rootUrl, sceneFilename);
-            this.tasks.push(task);
+            this._tasks.push(task);
 
 
             return task;
             return task;
         }
         }
 
 
+        /**
+         * Add a {BABYLON.TextFileAssetTask} to the list of active tasks
+         * @param taskName defines the name of the new task
+         * @param url defines the url of the file to load
+         * @returns a new {BABYLON.TextFileAssetTask} object
+         */
         public addTextFileTask(taskName: string, url: string): TextFileAssetTask {
         public addTextFileTask(taskName: string, url: string): TextFileAssetTask {
             var task = new TextFileAssetTask(taskName, url);
             var task = new TextFileAssetTask(taskName, url);
-            this.tasks.push(task);
+            this._tasks.push(task);
 
 
             return task;
             return task;
         }
         }
 
 
+        /**
+         * Add a {BABYLON.BinaryFileAssetTask} to the list of active tasks
+         * @param taskName defines the name of the new task
+         * @param url defines the url of the file to load
+         * @returns a new {BABYLON.BinaryFileAssetTask} object
+         */
         public addBinaryFileTask(taskName: string, url: string): BinaryFileAssetTask {
         public addBinaryFileTask(taskName: string, url: string): BinaryFileAssetTask {
             var task = new BinaryFileAssetTask(taskName, url);
             var task = new BinaryFileAssetTask(taskName, url);
-            this.tasks.push(task);
+            this._tasks.push(task);
 
 
             return task;
             return task;
         }
         }
 
 
+        /**
+         * Add a {BABYLON.ImageAssetTask} to the list of active tasks
+         * @param taskName defines the name of the new task
+         * @param url defines the url of the file to load
+         * @returns a new {BABYLON.ImageAssetTask} object
+         */
         public addImageTask(taskName: string, url: string): ImageAssetTask {
         public addImageTask(taskName: string, url: string): ImageAssetTask {
             var task = new ImageAssetTask(taskName, url);
             var task = new ImageAssetTask(taskName, url);
-            this.tasks.push(task);
+            this._tasks.push(task);
 
 
             return task;
             return task;
         }
         }
 
 
+        /**
+         * Add a {BABYLON.TextureAssetTask} to the list of active tasks
+         * @param taskName defines the name of the new task
+         * @param url defines the url of the file to load
+         * @param noMipmap defines if the texture must not receive mipmaps (false by default)
+         * @param invertY defines if you want to invert Y axis of the loaded texture (false by default)
+         * @param samplingMode defines the sampling mode to use (BABYLON.Texture.TRILINEAR_SAMPLINGMODE by default)
+         * @returns a new {BABYLON.TextureAssetTask} object
+         */
         public addTextureTask(taskName: string, url: string, noMipmap?: boolean, invertY?: boolean, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE): TextureAssetTask {
         public addTextureTask(taskName: string, url: string, noMipmap?: boolean, invertY?: boolean, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE): TextureAssetTask {
             var task = new TextureAssetTask(taskName, url, noMipmap, invertY, samplingMode);
             var task = new TextureAssetTask(taskName, url, noMipmap, invertY, samplingMode);
-            this.tasks.push(task);
+            this._tasks.push(task);
 
 
             return task;
             return task;
         }
         }
 
 
-
-        public addCubeTextureTask(name: string, url: string, extensions?: string[], noMipmap?: boolean, files?: string[]): CubeTextureAssetTask {
-            var task = new CubeTextureAssetTask(name, url, extensions, noMipmap, files);
-            this.tasks.push(task);
+        /**
+         * Add a {BABYLON.CubeTextureAssetTask} to the list of active tasks
+         * @param taskName defines the name of the new task
+         * @param url defines the url of the file to load
+         * @param extensions defines the extension to use to load the cube map (can be null)
+         * @param noMipmap defines if the texture must not receive mipmaps (false by default)
+         * @param files defines the list of files to load (can be null)
+         * @returns a new {BABYLON.CubeTextureAssetTask} object
+         */
+        public addCubeTextureTask(taskName: string, url: string, extensions?: string[], noMipmap?: boolean, files?: string[]): CubeTextureAssetTask {
+            var task = new CubeTextureAssetTask(taskName, url, extensions, noMipmap, files);
+            this._tasks.push(task);
 
 
             return task;
             return task;
         }
         }
 
 
-        public addHDRCubeTextureTask(name: string, url: string, size?: number, noMipmap = false, generateHarmonics = true, useInGammaSpace = false, usePMREMGenerator = false): HDRCubeTextureAssetTask {
-            var task = new HDRCubeTextureAssetTask(name, url, size, noMipmap, generateHarmonics, useInGammaSpace, usePMREMGenerator);
-            this.tasks.push(task);
+        /**
+         * 
+         * Add a {BABYLON.HDRCubeTextureAssetTask} to the list of active tasks
+         * @param taskName defines the name of the new task
+         * @param url defines the url of the file to load
+         * @param size defines the size you want for the cubemap (can be null)
+         * @param noMipmap defines if the texture must not receive mipmaps (false by default)
+         * @param generateHarmonics defines if you want to automatically generate (true by default)
+         * @param useInGammaSpace defines if the texture must be considered in gamma space (false by default)
+         * @param usePMREMGenerator is a reserved parameter and must be set to false or ignored
+         * @returns a new {BABYLON.HDRCubeTextureAssetTask} object
+         */
+        public addHDRCubeTextureTask(taskName: string, url: string, size?: number, noMipmap = false, generateHarmonics = true, useInGammaSpace = false, usePMREMGenerator = false): HDRCubeTextureAssetTask {
+            var task = new HDRCubeTextureAssetTask(taskName, url, size, noMipmap, generateHarmonics, useInGammaSpace, usePMREMGenerator);
+            this._tasks.push(task);
 
 
             return task;
             return task;
         }
         }
 
 
         private _decreaseWaitingTasksCount(task: AbstractAssetTask): void {
         private _decreaseWaitingTasksCount(task: AbstractAssetTask): void {
-            this.waitingTasksCount--;
+            this._waitingTasksCount--;
 
 
             try {
             try {
+                if (task.taskState === AssetTaskState.DONE) {
+                    // Let's remove successfull tasks
+                    Tools.SetImmediate(() => {
+                        let index = this._tasks.indexOf(task);
+
+                        if (index > -1) {
+                            this._tasks.splice(index, 1);
+                        }
+                    });
+                }
+
                 if (this.onProgress) {
                 if (this.onProgress) {
                     this.onProgress(
                     this.onProgress(
-                        this.waitingTasksCount,
-                        this.tasks.length,
+                        this._waitingTasksCount,
+                        this._totalTasksCount,
                         task
                         task
                     );
                     );
                 }
                 }
 
 
                 this.onProgressObservable.notifyObservers(
                 this.onProgressObservable.notifyObservers(
                     new AssetsProgressEvent(
                     new AssetsProgressEvent(
-                        this.waitingTasksCount,
-                        this.tasks.length,
+                        this._waitingTasksCount,
+                        this._totalTasksCount,
                         task
                         task
                     )
                     )
                 );
                 );
@@ -355,13 +867,13 @@ module BABYLON {
                 console.log(e);
                 console.log(e);
             }
             }
 
 
-            if (this.waitingTasksCount === 0) {
+            if (this._waitingTasksCount === 0) {
                 try {
                 try {
                     if (this.onFinish) {
                     if (this.onFinish) {
-                        this.onFinish(this.tasks);
+                        this.onFinish(this._tasks);
                     }
                     }
 
 
-                    this.onTasksDoneObservable.notifyObservers(this.tasks);
+                    this.onTasksDoneObservable.notifyObservers(this._tasks);
                 } catch (e) {
                 } catch (e) {
                     Tools.Error("Error running tasks-done callbacks.");
                     Tools.Error("Error running tasks-done callbacks.");
                     console.log(e);
                     console.log(e);
@@ -387,10 +899,8 @@ module BABYLON {
             }
             }
 
 
             let error = (message?: string, exception?: any) => {
             let error = (message?: string, exception?: any) => {
-                task.errorObject = task.errorObject || {
-                    message: message,
-                    exception: exception
-                }
+                task._setErrorObject(message, exception);
+
                 if (this.onTaskError) {
                 if (this.onTaskError) {
                     this.onTaskError(task);
                     this.onTaskError(task);
                 }
                 }
@@ -401,25 +911,33 @@ module BABYLON {
             task.run(this._scene, done, error);
             task.run(this._scene, done, error);
         }
         }
 
 
+        /**
+         * Reset the {BABYLON.AssetsManager} and remove all tasks
+         * @return the current instance of the {BABYLON.AssetsManager}
+         */
         public reset(): AssetsManager {
         public reset(): AssetsManager {
             this._isLoading = false;
             this._isLoading = false;
-            this.tasks = new Array<AbstractAssetTask>();
+            this._tasks = new Array<AbstractAssetTask>();
             return this;
             return this;
         }
         }
 
 
+        /**
+         * Start the loading process
+         * @return the current instance of the {BABYLON.AssetsManager}
+         */
         public load(): AssetsManager {
         public load(): AssetsManager {
             if (this._isLoading) {
             if (this._isLoading) {
                 return this;
                 return this;
             }
             }
             this._isLoading = true;
             this._isLoading = true;
-            this.waitingTasksCount = this.tasks.length;
+            this._waitingTasksCount = this._tasks.length;
+            this._totalTasksCount = this._tasks.length;
 
 
-            if (this.waitingTasksCount === 0) {
+            if (this._waitingTasksCount === 0) {
                 if (this.onFinish) {
                 if (this.onFinish) {
-                    this.onFinish(this.tasks);
+                    this.onFinish(this._tasks);
                 }
                 }
-                this.onTasksDoneObservable.notifyObservers(this.tasks);
-                this._isLoading = false;
+                this.onTasksDoneObservable.notifyObservers(this._tasks);
                 return this;
                 return this;
             }
             }
 
 
@@ -427,8 +945,8 @@ module BABYLON {
                 this._scene.getEngine().displayLoadingUI();
                 this._scene.getEngine().displayLoadingUI();
             }
             }
 
 
-            for (var index = 0; index < this.tasks.length; index++) {
-                var task = this.tasks[index];
+            for (var index = 0; index < this._tasks.length; index++) {
+                var task = this._tasks[index];
                 this._runTask(task);
                 this._runTask(task);
             }
             }
 
 

+ 20 - 0
src/Tools/babylon.tools.ts

@@ -1014,6 +1014,26 @@
             Tools.EncodeScreenshotCanvasData(successCallback, mimeType);
             Tools.EncodeScreenshotCanvasData(successCallback, mimeType);
         }
         }
 
 
+        /**
+         * Generates an image screenshot from the specified camera.
+         *
+         * @param engine The engine to use for rendering
+         * @param camera The camera to use for rendering
+         * @param size This parameter can be set to a single number or to an object with the
+         * following (optional) properties: precision, width, height. If a single number is passed,
+         * it will be used for both width and height. If an object is passed, the screenshot size
+         * will be derived from the parameters. The precision property is a multiplier allowing
+         * rendering at a higher or lower resolution.
+         * @param successCallback The callback receives a single parameter which contains the
+         * screenshot as a string of base64-encoded characters. This string can be assigned to the
+         * src parameter of an <img> to display it.
+         * @param mimeType The MIME type of the screenshot image (default: image/png).
+         * Check your browser for supported MIME types.
+         * @param samples Texture samples (default: 1)
+         * @param antialiasing Whether antialiasing should be turned on or not (default: false)
+         * @param fileName A name for for the downloaded file.
+         * @constructor
+         */
         public static CreateScreenshotUsingRenderTarget(engine: Engine, camera: Camera, size: any, successCallback?: (data: string) => void, mimeType: string = "image/png", samples: number = 1, antialiasing: boolean = false, fileName?: string): void {
         public static CreateScreenshotUsingRenderTarget(engine: Engine, camera: Camera, size: any, successCallback?: (data: string) => void, mimeType: string = "image/png", samples: number = 1, antialiasing: boolean = false, fileName?: string): void {
             var width: number;
             var width: number;
             var height: number;
             var height: number;

+ 5 - 1
src/babylon.mixins.ts

@@ -164,4 +164,8 @@ interface EXT_disjoint_timer_query {
     endQueryEXT(target: number): void;
     endQueryEXT(target: number): void;
     getQueryObjectEXT(query: WebGLQuery, target: number): any;
     getQueryObjectEXT(query: WebGLQuery, target: number): any;
     deleteQueryEXT(query: WebGLQuery): void;
     deleteQueryEXT(query: WebGLQuery): void;
-}
+}
+
+interface WebGLUniformLocation {
+    _currentState: any;
+}

+ 1 - 0
tests/validation/integration.js

@@ -35,6 +35,7 @@ xhr.addEventListener("load", function () {
 
 
                 it(test.title, function (done) {
                 it(test.title, function (done) {
                     this.timeout(240000);
                     this.timeout(240000);
+                    this.retries(3);
 
 
                     try {
                     try {
                         runTest(index, function(result, screenshot) {
                         runTest(index, function(result, screenshot) {

+ 69 - 38
tests/validation/validation.js

@@ -135,12 +135,18 @@ function processCurrentScene(test, resultCanvas, result, renderImage, index, wai
 
 
         currentScene.useConstantAnimationDeltaTime = true;
         currentScene.useConstantAnimationDeltaTime = true;
         engine.runRenderLoop(function () {
         engine.runRenderLoop(function () {
-            currentScene.render();
-            renderCount--;
+            try {
+                currentScene.render();
+                renderCount--;
 
 
-            if (renderCount === 0) {
-                engine.stopRenderLoop();
-                evaluate(test, resultCanvas, result, renderImage, index, waitRing, done);
+                if (renderCount === 0) {
+                    engine.stopRenderLoop();
+                    evaluate(test, resultCanvas, result, renderImage, index, waitRing, done);
+                }
+            }
+            catch (e) {
+                console.error(e);
+                done(false);
             }
             }
         });
         });
 
 
@@ -203,7 +209,12 @@ function runTest(index, done) {
         BABYLON.SceneLoader.Load(config.root + test.sceneFolder, test.sceneFilename, engine, function (newScene) {
         BABYLON.SceneLoader.Load(config.root + test.sceneFolder, test.sceneFilename, engine, function (newScene) {
             currentScene = newScene;
             currentScene = newScene;
             processCurrentScene(test, resultCanvas, result, renderImage, index, waitRing, done);
             processCurrentScene(test, resultCanvas, result, renderImage, index, waitRing, done);
-        });
+        },
+            null,
+            function (loadedScene, msg) {
+                console.error(msg);
+                done(false);
+            });
     }
     }
     else if (test.playgroundId) {
     else if (test.playgroundId) {
         var snippetUrl = "//babylonjs-api2.azurewebsites.net/snippets";
         var snippetUrl = "//babylonjs-api2.azurewebsites.net/snippets";
@@ -211,17 +222,27 @@ function runTest(index, done) {
         var xmlHttp = new XMLHttpRequest();
         var xmlHttp = new XMLHttpRequest();
         xmlHttp.onreadystatechange = function () {
         xmlHttp.onreadystatechange = function () {
             if (xmlHttp.readyState === 4) {
             if (xmlHttp.readyState === 4) {
-                var snippet = JSON.parse(xmlHttp.responseText)[0];
-                var code = JSON.parse(snippet.jsonPayload).code.toString();
-                code = code.replace(/\/textures\//g, pgRoot + "/textures/");
-                code = code.replace(/"textures\//g, "\"" + pgRoot + "/textures/");
-                code = code.replace(/\/scenes\//g, pgRoot + "/scenes/");
-                code = code.replace(/"scenes\//g, "\"" + pgRoot + "/scenes/");
-
-                currentScene = eval(code + "\r\ncreateScene(engine)");
-                processCurrentScene(test, resultCanvas, result, renderImage, index, waitRing, done);
+                try {
+                    xmlHttp.onreadystatechange = null;
+                    var snippet = JSON.parse(xmlHttp.responseText)[0];
+                    var code = JSON.parse(snippet.jsonPayload).code.toString();
+                    code = code.replace(/\/textures\//g, pgRoot + "/textures/");
+                    code = code.replace(/"textures\//g, "\"" + pgRoot + "/textures/");
+                    code = code.replace(/\/scenes\//g, pgRoot + "/scenes/");
+                    code = code.replace(/"scenes\//g, "\"" + pgRoot + "/scenes/");
+                    currentScene = eval(code + "\r\ncreateScene(engine)");
+                    processCurrentScene(test, resultCanvas, result, renderImage, index, waitRing, done);
+                }
+                catch (e) {
+                    console.error(e);
+                    done(false);
+                }
             }
             }
         }
         }
+        xmlHttp.onerror = function () {
+            console.error("Network error during test load.");
+            done(false);
+        }
 
 
         xmlHttp.open("GET", snippetUrl + test.playgroundId.replace(/#/g, "/"));
         xmlHttp.open("GET", snippetUrl + test.playgroundId.replace(/#/g, "/"));
         xmlHttp.send();
         xmlHttp.send();
@@ -236,35 +257,45 @@ function runTest(index, done) {
 
 
         request.onreadystatechange = () => {
         request.onreadystatechange = () => {
             if (request.readyState === 4) {
             if (request.readyState === 4) {
-                request.onreadystatechange = null;
-
-                var scriptToRun = request.responseText.replace(/..\/..\/assets\//g, config.root + "/Assets/");
-                scriptToRun = scriptToRun.replace(/..\/..\/Assets\//g, config.root + "/Assets/");
-                scriptToRun = scriptToRun.replace(/\/assets\//g, config.root + "/Assets/");
-                scriptToRun = scriptToRun.replace(/\/Assets\//g, config.root + "/Assets/");
-
-                if (test.replace) {
-                    var split = test.replace.split(",");
-                    for (var i = 0; i < split.length; i += 2) {
-                        var source = split[i].trim();
-                        var destination = split[i + 1].trim();
-                        scriptToRun = scriptToRun.replace(source, destination);
+                try {
+                    request.onreadystatechange = null;
+
+                    var scriptToRun = request.responseText.replace(/..\/..\/assets\//g, config.root + "/Assets/");
+                    scriptToRun = scriptToRun.replace(/..\/..\/Assets\//g, config.root + "/Assets/");
+                    scriptToRun = scriptToRun.replace(/\/assets\//g, config.root + "/Assets/");
+                    scriptToRun = scriptToRun.replace(/\/Assets\//g, config.root + "/Assets/");
+
+                    if (test.replace) {
+                        var split = test.replace.split(",");
+                        for (var i = 0; i < split.length; i += 2) {
+                            var source = split[i].trim();
+                            var destination = split[i + 1].trim();
+                            scriptToRun = scriptToRun.replace(source, destination);
+                        }
                     }
                     }
-                }
 
 
-                if (test.replaceUrl) {
-                    var split = test.replaceUrl.split(",");
-                    for (var i = 0; i < split.length; i++) {
-                        var source = split[i].trim();
-                        var regex = new RegExp(source, "g");
-                        scriptToRun = scriptToRun.replace(regex, config.root + test.rootPath + source);
+                    if (test.replaceUrl) {
+                        var split = test.replaceUrl.split(",");
+                        for (var i = 0; i < split.length; i++) {
+                            var source = split[i].trim();
+                            var regex = new RegExp(source, "g");
+                            scriptToRun = scriptToRun.replace(regex, config.root + test.rootPath + source);
+                        }
                     }
                     }
-                }
 
 
-                currentScene = eval(scriptToRun + test.functionToCall + "(engine)");
-                processCurrentScene(test, resultCanvas, result, renderImage, index, waitRing, done);
+                    currentScene = eval(scriptToRun + test.functionToCall + "(engine)");
+                    processCurrentScene(test, resultCanvas, result, renderImage, index, waitRing, done);
+                }
+                catch (e) {
+                    console.error(e);
+                    done(false);
+                }
             }
             }
         };
         };
+        request.onerror = function () {
+            console.error("Network error during test load.");
+            done(false);
+        }
 
 
         request.send(null);
         request.send(null);