Bläddra i källkod

Merge pull request #340 from simonferquel/master

Fixed node hierarchy where certain nodes are not game object (but purely abstract nodes)
David Catuhe 10 år sedan
förälder
incheckning
9cc26bfa6b
46 ändrade filer med 638 tillägg och 1028 borttagningar
  1. 3 3
      Babylon/Actions/babylon.actionManager.js
  2. 6 51
      Babylon/Animations/babylon.animation.js
  3. 2 3
      Babylon/Lights/Shadows/babylon.shadowGenerator.js
  4. 0 4
      Babylon/Lights/babylon.directionalLight.js
  5. 0 4
      Babylon/Lights/babylon.light.js
  6. 0 4
      Babylon/Lights/babylon.pointLight.js
  7. 0 5
      Babylon/Lights/babylon.spotLight.js
  8. 0 10
      Babylon/Loading/Plugins/babylon.babylonFileLoader.js
  9. 2 2
      Babylon/Loading/babylon.sceneLoader.js
  10. 14 13
      Babylon/Materials/babylon.effect.js
  11. 0 5
      Babylon/Materials/babylon.material.js
  12. 37 65
      Babylon/Materials/babylon.shaderMaterial.js
  13. 113 136
      Babylon/Materials/babylon.standardMaterial.js
  14. 51 69
      Babylon/Materials/textures/Procedurals/babylon.customProceduralTexture.js
  15. 6 43
      Babylon/Materials/textures/Procedurals/babylon.proceduralTexture.js
  16. 80 166
      Babylon/Materials/textures/Procedurals/babylon.standardProceduralTexture.js
  17. 1 1
      Babylon/Materials/textures/babylon.baseTexture.js
  18. 1 1
      Babylon/Materials/textures/babylon.renderTargetTexture.js
  19. 0 2
      Babylon/Materials/textures/babylon.texture.js
  20. 0 54
      Babylon/Math/babylon.math.js
  21. 2 12
      Babylon/Mesh/babylon.InstancedMesh.js
  22. 4 45
      Babylon/Mesh/babylon.abstractMesh.js
  23. 5 10
      Babylon/Mesh/babylon.geometry.js
  24. 34 93
      Babylon/Mesh/babylon.mesh.js
  25. 2 2
      Babylon/Mesh/babylon.vertexBuffer.js
  26. 7 8
      Babylon/Particles/babylon.particleSystem.js
  27. 0 2
      Babylon/Physics/Plugins/babylon.oimoJSPlugin.js
  28. 5 5
      Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.js
  29. 2 2
      Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.js
  30. 1 1
      Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.js
  31. 1 3
      Babylon/Rendering/babylon.boundingBoxRenderer.js
  32. 5 6
      Babylon/Rendering/babylon.outlineRenderer.js
  33. 12 13
      Babylon/Rendering/babylon.renderingGroup.js
  34. 9 2
      Babylon/Rendering/babylon.renderingManager.js
  35. 3 3
      Babylon/Sprites/babylon.spriteManager.js
  36. 0 82
      Babylon/Tools/babylon.sceneOptimizer.js
  37. 4 44
      Babylon/Tools/babylon.tools.js
  38. 3 0
      Exporters/3ds Max/BabylonExport.Entities/BabylonLight.cs
  39. BIN
      Exporters/3ds Max/Max2Babylon-0.11.0.zip
  40. BIN
      Exporters/3ds Max/Max2Babylon-0.12.0.zip
  41. 9 11
      Exporters/3ds Max/Max2Babylon/BabylonPropertiesActionItem.cs
  42. 35 2
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Camera.cs
  43. 37 1
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Light.cs
  44. 134 34
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs
  45. 2 2
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.cs
  46. 6 4
      Exporters/3ds Max/Max2Babylon/Forms/ObjectPropertiesForm.cs

+ 3 - 3
Babylon/Actions/babylon.actionManager.js

@@ -8,9 +8,9 @@
             this.meshUnderPointer = meshUnderPointer;
             this.sourceEvent = sourceEvent;
         }
-        ActionEvent.CreateNew = function (source, evt) {
+        ActionEvent.CreateNew = function (source) {
             var scene = source.getScene();
-            return new ActionEvent(source, scene.pointerX, scene.pointerY, scene.meshUnderPointer, evt);
+            return new ActionEvent(source, scene.pointerX, scene.pointerY, scene.meshUnderPointer);
         };
 
         ActionEvent.CreateNewFromScene = function (scene, evt) {
@@ -202,7 +202,7 @@
                 var action = this.actions[index];
 
                 if (action.trigger === trigger) {
-                    if (trigger === ActionManager.OnKeyUpTrigger || trigger === ActionManager.OnKeyDownTrigger) {
+                    if (trigger == ActionManager.OnKeyUpTrigger || trigger == ActionManager.OnKeyDownTrigger) {
                         var parameter = action.getTriggerParameter();
 
                         if (parameter) {

+ 6 - 51
Babylon/Animations/babylon.animation.js

@@ -14,37 +14,6 @@
             this.dataType = dataType;
             this.loopMode = loopMode === undefined ? Animation.ANIMATIONLOOPMODE_CYCLE : loopMode;
         }
-        Animation.CreateAndStartAnimation = function (name, mesh, tartgetProperty, framePerSecond, totalFrame, from, to, loopMode) {
-            var dataType = undefined;
-
-            if (!isNaN(parseFloat(from)) && isFinite(from)) {
-                dataType = Animation.ANIMATIONTYPE_FLOAT;
-            } else if (from instanceof BABYLON.Quaternion) {
-                dataType = Animation.ANIMATIONTYPE_QUATERNION;
-            } else if (from instanceof BABYLON.Vector3) {
-                dataType = Animation.ANIMATIONTYPE_VECTOR3;
-            } else if (from instanceof BABYLON.Vector2) {
-                dataType = Animation.ANIMATIONTYPE_VECTOR2;
-            } else if (from instanceof BABYLON.Color3) {
-                dataType = Animation.ANIMATIONTYPE_COLOR3;
-            }
-
-            if (dataType == undefined) {
-                return;
-            }
-
-            var animation = new Animation(name, tartgetProperty, framePerSecond, dataType, loopMode);
-
-            var keys = [];
-            keys.push({ frame: 0, value: from });
-            keys.push({ frame: totalFrame, value: to });
-            animation.setKeys(keys);
-
-            mesh.animations.push(animation);
-
-            mesh.getScene().beginAnimation(mesh, 0, totalFrame, (animation.loopMode == 1));
-        };
-
         // Methods
         Animation.prototype.isStopped = function () {
             return this._stopped;
@@ -54,14 +23,6 @@
             return this._keys;
         };
 
-        Animation.prototype.getEasingFunction = function () {
-            return this._easingFunction;
-        };
-
-        Animation.prototype.setEasingFunction = function (easingFunction) {
-            this._easingFunction = easingFunction;
-        };
-
         Animation.prototype.floatInterpolateFunction = function (startValue, endValue, gradient) {
             return startValue + (endValue - startValue) * gradient;
         };
@@ -104,19 +65,11 @@
             this.currentFrame = currentFrame;
 
             for (var key = 0; key < this._keys.length; key++) {
-                // for each frame, we need the key just before the frame superior
                 if (this._keys[key + 1].frame >= currentFrame) {
                     var startValue = this._keys[key].value;
                     var endValue = this._keys[key + 1].value;
-
-                    // gradient : percent of currentFrame between the frame inf and the frame sup
                     var gradient = (currentFrame - this._keys[key].frame) / (this._keys[key + 1].frame - this._keys[key].frame);
 
-                    // check for easingFunction and correction of gradient
-                    if (this._easingFunction != null) {
-                        gradient = this._easingFunction.ease(gradient);
-                    }
-
                     switch (this.dataType) {
                         case Animation.ANIMATIONTYPE_FLOAT:
                             switch (loopMode) {
@@ -190,11 +143,16 @@
                 this._stopped = true;
                 return false;
             }
+
             var returnValue = true;
 
             // Adding a start key at frame 0 if missing
             if (this._keys[0].frame != 0) {
-                var newKey = { frame: 0, value: this._keys[0].value };
+                var newKey = {
+                    frame: 0,
+                    value: this._keys[0].value
+                };
+
                 this._keys.splice(0, 0, newKey);
             }
 
@@ -209,8 +167,6 @@
             // Compute ratio
             var range = to - from;
             var offsetValue;
-
-            // ratio represents the frame delta between from and to
             var ratio = delay * (this.framePerSecond * speedRatio) / 1000.0;
 
             if (ratio > range && !loop) {
@@ -219,7 +175,6 @@
             } else {
                 // Get max value if required
                 var highLimitValue = 0;
-
                 if (this.loopMode != Animation.ANIMATIONLOOPMODE_CYCLE) {
                     var keyOffset = to.toString() + from.toString();
                     if (!this._offsetsCache[keyOffset]) {

+ 2 - 3
Babylon/Lights/Shadows/babylon.shadowGenerator.js

@@ -55,7 +55,7 @@
                     }
 
                     // Bones
-                    var useBones = mesh.skeleton && scene.skeletonsEnabled && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind);
+                    var useBones = mesh.skeleton && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind);
 
                     if (useBones) {
                         _this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
@@ -163,7 +163,6 @@
             var attribs = [BABYLON.VertexBuffer.PositionKind];
 
             var mesh = subMesh.getMesh();
-            var scene = mesh.getScene();
             var material = subMesh.getMaterial();
 
             // Alpha test
@@ -180,7 +179,7 @@
             }
 
             // Bones
-            if (mesh.skeleton && scene.skeletonsEnabled && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
+            if (mesh.skeleton && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
                 attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
                 attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
                 defines.push("#define BONES");

+ 0 - 4
Babylon/Lights/babylon.directionalLight.js

@@ -14,10 +14,6 @@ var BABYLON;
 
             this.position = direction.scale(-1);
         }
-        DirectionalLight.prototype.getAbsolutePosition = function () {
-            return this._transformedPosition ? this._transformedPosition : this.position;
-        };
-
         DirectionalLight.prototype.setDirectionToTarget = function (target) {
             this.direction = BABYLON.Vector3.Normalize(target.subtract(this.position));
             return this.direction;

+ 0 - 4
Babylon/Lights/babylon.light.js

@@ -25,10 +25,6 @@ var BABYLON;
             return this._shadowGenerator;
         };
 
-        Light.prototype.getAbsolutePosition = function () {
-            return BABYLON.Vector3.Zero();
-        };
-
         Light.prototype.transferToEffect = function (effect, uniformName0, uniformName1) {
         };
 

+ 0 - 4
Babylon/Lights/babylon.pointLight.js

@@ -12,10 +12,6 @@ var BABYLON;
             _super.call(this, name, scene);
             this.position = position;
         }
-        PointLight.prototype.getAbsolutePosition = function () {
-            return this._transformedPosition ? this._transformedPosition : this.position;
-        };
-
         PointLight.prototype.transferToEffect = function (effect, positionUniformName) {
             if (this.parent && this.parent.getWorldMatrix) {
                 if (!this._transformedPosition) {

+ 0 - 5
Babylon/Lights/babylon.spotLight.js

@@ -15,10 +15,6 @@ var BABYLON;
             this.angle = angle;
             this.exponent = exponent;
         }
-        SpotLight.prototype.getAbsolutePosition = function () {
-            return this._transformedPosition ? this._transformedPosition : this.position;
-        };
-
         SpotLight.prototype.setDirectionToTarget = function (target) {
             this.direction = BABYLON.Vector3.Normalize(target.subtract(this.position));
             return this.direction;
@@ -31,7 +27,6 @@ var BABYLON;
                 if (!this._transformedDirection) {
                     this._transformedDirection = BABYLON.Vector3.Zero();
                 }
-
                 if (!this._transformedPosition) {
                     this._transformedPosition = BABYLON.Vector3.Zero();
                 }

+ 0 - 10
Babylon/Loading/Plugins/babylon.babylonFileLoader.js

@@ -407,8 +407,6 @@
                 camera = new BABYLON.GamepadCamera(parsedCamera.name, position, scene);
             } else if (parsedCamera.type === "OculusCamera") {
                 camera = new BABYLON.OculusCamera(parsedCamera.name, position, scene);
-            } else if (parsedCamera.type === "OculusGamepadCamera") {
-                camera = new BABYLON.OculusGamepadCamera(parsedCamera.name, position, scene);
             } else if (parsedCamera.type === "TouchCamera") {
                 camera = new BABYLON.TouchCamera(parsedCamera.name, position, scene);
             } else if (parsedCamera.type === "VirtualJoysticksCamera") {
@@ -649,18 +647,10 @@
             mesh.showBoundingBox = parsedMesh.showBoundingBox;
             mesh.showSubMeshesBoundingBox = parsedMesh.showSubMeshesBoundingBox;
 
-            if (parsedMesh.applyFog !== undefined) {
-                mesh.applyFog = parsedMesh.applyFog;
-            }
-
             if (parsedMesh.pickable !== undefined) {
                 mesh.isPickable = parsedMesh.pickable;
             }
 
-            if (parsedMesh.alphaIndex !== undefined) {
-                mesh.alphaIndex = parsedMesh.alphaIndex;
-            }
-
             mesh.receiveShadows = parsedMesh.receiveShadows;
 
             mesh.billboardMode = parsedMesh.billboardMode;

+ 2 - 2
Babylon/Loading/babylon.sceneLoader.js

@@ -64,14 +64,14 @@
                     try  {
                         if (!plugin.importMesh(meshesNames, scene, data, rootUrl, meshes, particleSystems, skeletons)) {
                             if (onerror) {
-                                onerror(scene, 'unable to load the scene');
+                                onerror(scene);
                             }
 
                             return;
                         }
                     } catch (e) {
                         if (onerror) {
-                            onerror(scene, e);
+                            onerror(scene);
                         }
 
                         return;

+ 14 - 13
Babylon/Materials/babylon.effect.js

@@ -143,8 +143,8 @@
             }
 
             // Is in local store ?
-            if (Effect.ShadersStore[vertex + "VertexShader"]) {
-                callback(Effect.ShadersStore[vertex + "VertexShader"]);
+            if (BABYLON.Effect.ShadersStore[vertex + "VertexShader"]) {
+                callback(BABYLON.Effect.ShadersStore[vertex + "VertexShader"]);
                 return;
             }
 
@@ -169,13 +169,13 @@
             }
 
             // Is in local store ?
-            if (Effect.ShadersStore[fragment + "PixelShader"]) {
-                callback(Effect.ShadersStore[fragment + "PixelShader"]);
+            if (BABYLON.Effect.ShadersStore[fragment + "PixelShader"]) {
+                callback(BABYLON.Effect.ShadersStore[fragment + "PixelShader"]);
                 return;
             }
 
-            if (Effect.ShadersStore[fragment + "FragmentShader"]) {
-                callback(Effect.ShadersStore[fragment + "FragmentShader"]);
+            if (BABYLON.Effect.ShadersStore[fragment + "FragmentShader"]) {
+                callback(BABYLON.Effect.ShadersStore[fragment + "FragmentShader"]);
                 return;
             }
 
@@ -208,6 +208,7 @@
                         index--;
                     }
                 }
+
                 engine.bindSamplers(this);
 
                 this._isReady = true;
@@ -339,7 +340,7 @@
         };
 
         Effect.prototype.setVector2 = function (uniformName, vector2) {
-            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] === vector2.x && this._valueCache[uniformName][1] === vector2.y)
+            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == vector2.x && this._valueCache[uniformName][1] == vector2.y)
                 return this;
 
             this._cacheFloat2(uniformName, vector2.x, vector2.y);
@@ -349,7 +350,7 @@
         };
 
         Effect.prototype.setFloat2 = function (uniformName, x, y) {
-            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] === x && this._valueCache[uniformName][1] === y)
+            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == x && this._valueCache[uniformName][1] == y)
                 return this;
 
             this._cacheFloat2(uniformName, x, y);
@@ -359,7 +360,7 @@
         };
 
         Effect.prototype.setVector3 = function (uniformName, vector3) {
-            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] === vector3.x && this._valueCache[uniformName][1] === vector3.y && this._valueCache[uniformName][2] === vector3.z)
+            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == vector3.x && this._valueCache[uniformName][1] == vector3.y && this._valueCache[uniformName][2] == vector3.z)
                 return this;
 
             this._cacheFloat3(uniformName, vector3.x, vector3.y, vector3.z);
@@ -370,7 +371,7 @@
         };
 
         Effect.prototype.setFloat3 = function (uniformName, x, y, z) {
-            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] === x && this._valueCache[uniformName][1] === y && this._valueCache[uniformName][2] === z)
+            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == x && this._valueCache[uniformName][1] == y && this._valueCache[uniformName][2] == z)
                 return this;
 
             this._cacheFloat3(uniformName, x, y, z);
@@ -380,7 +381,7 @@
         };
 
         Effect.prototype.setFloat4 = function (uniformName, x, y, z, w) {
-            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] === x && this._valueCache[uniformName][1] === y && this._valueCache[uniformName][2] === z && this._valueCache[uniformName][3] === w)
+            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == x && this._valueCache[uniformName][1] == y && this._valueCache[uniformName][2] == z && this._valueCache[uniformName][3] == w)
                 return this;
 
             this._cacheFloat4(uniformName, x, y, z, w);
@@ -390,7 +391,7 @@
         };
 
         Effect.prototype.setColor3 = function (uniformName, color3) {
-            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] === color3.r && this._valueCache[uniformName][1] === color3.g && this._valueCache[uniformName][2] === color3.b)
+            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == color3.r && this._valueCache[uniformName][1] == color3.g && this._valueCache[uniformName][2] == color3.b)
                 return this;
 
             this._cacheFloat3(uniformName, color3.r, color3.g, color3.b);
@@ -400,7 +401,7 @@
         };
 
         Effect.prototype.setColor4 = function (uniformName, color3, alpha) {
-            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] === color3.r && this._valueCache[uniformName][1] === color3.g && this._valueCache[uniformName][2] === color3.b && this._valueCache[uniformName][3] === alpha)
+            if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == color3.r && this._valueCache[uniformName][1] == color3.g && this._valueCache[uniformName][2] == color3.b && this._valueCache[uniformName][3] == alpha)
                 return this;
 
             this._cacheFloat4(uniformName, color3.r, color3.g, color3.b, alpha);

+ 0 - 5
Babylon/Materials/babylon.material.js

@@ -114,11 +114,6 @@
         };
 
         Material.prototype.bind = function (world, mesh) {
-            this._scene._cachedMaterial = this;
-
-            if (this.onBind) {
-                this.onBind(this);
-            }
         };
 
         Material.prototype.bindOnlyWorldMatrix = function (world) {

+ 37 - 65
Babylon/Materials/babylon.shaderMaterial.js

@@ -102,100 +102,72 @@ var BABYLON;
         };
 
         ShaderMaterial.prototype.isReady = function () {
-            var scene = this.getScene();
-            var engine = scene.getEngine();
+            var engine = this.getScene().getEngine();
 
-            if (!this.checkReadyOnEveryCall) {
-                if (this._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }
-
-            var previousEffect = this._effect;
             this._effect = engine.createEffect(this._shaderPath, this._options.attributes, this._options.uniforms, this._options.samplers, "", null, this.onCompiled, this.onError);
 
             if (!this._effect.isReady()) {
                 return false;
             }
 
-            if (previousEffect !== this._effect) {
-                scene.resetCachedMaterial();
-            }
-
-            this._renderId = scene.getRenderId();
-
             return true;
         };
 
-        ShaderMaterial.prototype.bindOnlyWorldMatrix = function (world) {
-            var scene = this.getScene();
-
+        ShaderMaterial.prototype.bind = function (world) {
+            // Std values
             if (this._options.uniforms.indexOf("world") !== -1) {
                 this._effect.setMatrix("world", world);
             }
 
+            if (this._options.uniforms.indexOf("view") !== -1) {
+                this._effect.setMatrix("view", this.getScene().getViewMatrix());
+            }
+
             if (this._options.uniforms.indexOf("worldView") !== -1) {
-                world.multiplyToRef(scene.getViewMatrix(), this._cachedWorldViewMatrix);
+                world.multiplyToRef(this.getScene().getViewMatrix(), this._cachedWorldViewMatrix);
                 this._effect.setMatrix("worldView", this._cachedWorldViewMatrix);
             }
 
-            if (this._options.uniforms.indexOf("worldViewProjection") !== -1) {
-                this._effect.setMatrix("worldViewProjection", world.multiply(scene.getTransformMatrix()));
+            if (this._options.uniforms.indexOf("projection") !== -1) {
+                this._effect.setMatrix("projection", this.getScene().getProjectionMatrix());
             }
-        };
-
-        ShaderMaterial.prototype.bind = function (world) {
-            // Std values
-            this.bindOnlyWorldMatrix(world);
-
-            if (this.getScene().getCachedMaterial() !== this) {
-                if (this._options.uniforms.indexOf("view") !== -1) {
-                    this._effect.setMatrix("view", this.getScene().getViewMatrix());
-                }
-
-                if (this._options.uniforms.indexOf("projection") !== -1) {
-                    this._effect.setMatrix("projection", this.getScene().getProjectionMatrix());
-                }
-
-                if (this._options.uniforms.indexOf("viewProjection") !== -1) {
-                    this._effect.setMatrix("viewProjection", this.getScene().getTransformMatrix());
-                }
 
-                for (var name in this._textures) {
-                    this._effect.setTexture(name, this._textures[name]);
-                }
+            if (this._options.uniforms.indexOf("worldViewProjection") !== -1) {
+                this._effect.setMatrix("worldViewProjection", world.multiply(this.getScene().getTransformMatrix()));
+            }
 
-                for (name in this._floats) {
-                    this._effect.setFloat(name, this._floats[name]);
-                }
+            for (var name in this._textures) {
+                this._effect.setTexture(name, this._textures[name]);
+            }
 
-                for (name in this._floatsArrays) {
-                    this._effect.setArray(name, this._floatsArrays[name]);
-                }
+            for (name in this._floats) {
+                this._effect.setFloat(name, this._floats[name]);
+            }
 
-                for (name in this._colors3) {
-                    this._effect.setColor3(name, this._colors3[name]);
-                }
+            for (name in this._floatsArrays) {
+                this._effect.setArray(name, this._floatsArrays[name]);
+            }
 
-                for (name in this._colors4) {
-                    var color = this._colors4[name];
-                    this._effect.setFloat4(name, color.r, color.g, color.b, color.a);
-                }
+            for (name in this._colors3) {
+                this._effect.setColor3(name, this._colors3[name]);
+            }
 
-                for (name in this._vectors2) {
-                    this._effect.setVector2(name, this._vectors2[name]);
-                }
+            for (name in this._colors4) {
+                var color = this._colors4[name];
+                this._effect.setFloat4(name, color.r, color.g, color.b, color.a);
+            }
 
-                for (name in this._vectors3) {
-                    this._effect.setVector3(name, this._vectors3[name]);
-                }
+            for (name in this._vectors2) {
+                this._effect.setVector2(name, this._vectors2[name]);
+            }
 
-                for (name in this._matrices) {
-                    this._effect.setMatrix(name, this._matrices[name]);
-                }
+            for (name in this._vectors3) {
+                this._effect.setVector3(name, this._vectors3[name]);
             }
 
-            _super.prototype.bind.call(this, world, null);
+            for (name in this._matrices) {
+                this._effect.setMatrix(name, this._matrices[name]);
+            }
         };
 
         ShaderMaterial.prototype.dispose = function (forceDisposeEffect) {

+ 113 - 136
Babylon/Materials/babylon.standardMaterial.js

@@ -88,7 +88,7 @@ var BABYLON;
 
             // Textures
             if (scene.texturesEnabled) {
-                if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
+                if (this.diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
                     if (!this.diffuseTexture.isReady()) {
                         return false;
                     } else {
@@ -96,7 +96,7 @@ var BABYLON;
                     }
                 }
 
-                if (this.ambientTexture && StandardMaterial.AmbientTextureEnabled) {
+                if (this.ambientTexture && BABYLON.StandardMaterial.AmbientTextureEnabled) {
                     if (!this.ambientTexture.isReady()) {
                         return false;
                     } else {
@@ -104,7 +104,7 @@ var BABYLON;
                     }
                 }
 
-                if (this.opacityTexture && StandardMaterial.OpacityTextureEnabled) {
+                if (this.opacityTexture && BABYLON.StandardMaterial.OpacityTextureEnabled) {
                     if (!this.opacityTexture.isReady()) {
                         return false;
                     } else {
@@ -116,7 +116,7 @@ var BABYLON;
                     }
                 }
 
-                if (this.reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
+                if (this.reflectionTexture && BABYLON.StandardMaterial.ReflectionTextureEnabled) {
                     if (!this.reflectionTexture.isReady()) {
                         return false;
                     } else {
@@ -125,7 +125,7 @@ var BABYLON;
                     }
                 }
 
-                if (this.emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
+                if (this.emissiveTexture && BABYLON.StandardMaterial.EmissiveTextureEnabled) {
                     if (!this.emissiveTexture.isReady()) {
                         return false;
                     } else {
@@ -133,7 +133,7 @@ var BABYLON;
                     }
                 }
 
-                if (this.specularTexture && StandardMaterial.SpecularTextureEnabled) {
+                if (this.specularTexture && BABYLON.StandardMaterial.SpecularTextureEnabled) {
                     if (!this.specularTexture.isReady()) {
                         return false;
                     } else {
@@ -143,7 +143,7 @@ var BABYLON;
                 }
             }
 
-            if (scene.getEngine().getCaps().standardDerivatives && this.bumpTexture && StandardMaterial.BumpTextureEnabled) {
+            if (scene.getEngine().getCaps().standardDerivatives && this.bumpTexture && BABYLON.StandardMaterial.BumpTextureEnabled) {
                 if (!this.bumpTexture.isReady()) {
                     return false;
                 } else {
@@ -171,12 +171,12 @@ var BABYLON;
             }
 
             // Point size
-            if (this.pointsCloud || scene.forcePointsCloud) {
+            if (this.pointsCloud) {
                 defines.push("#define POINTSIZE");
             }
 
             // Fog
-            if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
+            if (scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
                 defines.push("#define FOG");
                 fallbacks.addFallback(1, "FOG");
             }
@@ -270,43 +270,41 @@ var BABYLON;
                     }
 
                     lightIndex++;
-                    if (lightIndex === maxSimultaneousLights)
+                    if (lightIndex == maxSimultaneousLights)
                         break;
                 }
             }
 
-            if (StandardMaterial.FresnelEnabled) {
-                // Fresnel
-                if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled || this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled || this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled || this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
-                    var fresnelRank = 1;
+            // Fresnel
+            if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled || this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled || this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled || this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
+                var fresnelRank = 1;
 
-                    if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
-                        defines.push("#define DIFFUSEFRESNEL");
-                        fallbacks.addFallback(fresnelRank, "DIFFUSEFRESNEL");
-                        fresnelRank++;
-                    }
-
-                    if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
-                        defines.push("#define OPACITYFRESNEL");
-                        fallbacks.addFallback(fresnelRank, "OPACITYFRESNEL");
-                        fresnelRank++;
-                    }
+                if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
+                    defines.push("#define DIFFUSEFRESNEL");
+                    fallbacks.addFallback(fresnelRank, "DIFFUSEFRESNEL");
+                    fresnelRank++;
+                }
 
-                    if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
-                        defines.push("#define REFLECTIONFRESNEL");
-                        fallbacks.addFallback(fresnelRank, "REFLECTIONFRESNEL");
-                        fresnelRank++;
-                    }
+                if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
+                    defines.push("#define OPACITYFRESNEL");
+                    fallbacks.addFallback(fresnelRank, "OPACITYFRESNEL");
+                    fresnelRank++;
+                }
 
-                    if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
-                        defines.push("#define EMISSIVEFRESNEL");
-                        fallbacks.addFallback(fresnelRank, "EMISSIVEFRESNEL");
-                        fresnelRank++;
-                    }
+                if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
+                    defines.push("#define REFLECTIONFRESNEL");
+                    fallbacks.addFallback(fresnelRank, "REFLECTIONFRESNEL");
+                    fresnelRank++;
+                }
 
-                    defines.push("#define FRESNEL");
-                    fallbacks.addFallback(fresnelRank - 1, "FRESNEL");
+                if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
+                    defines.push("#define EMISSIVEFRESNEL");
+                    fallbacks.addFallback(fresnelRank, "EMISSIVEFRESNEL");
+                    fresnelRank++;
                 }
+
+                defines.push("#define FRESNEL");
+                fallbacks.addFallback(fresnelRank - 1, "FRESNEL");
             }
 
             // Attribs
@@ -320,7 +318,7 @@ var BABYLON;
                     attribs.push(BABYLON.VertexBuffer.UV2Kind);
                     defines.push("#define UV2");
                 }
-                if (mesh.useVertexColors && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
+                if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                     defines.push("#define VERTEXCOLOR");
 
@@ -328,7 +326,7 @@ var BABYLON;
                         defines.push("#define VERTEXALPHA");
                     }
                 }
-                if (mesh.skeleton && scene.skeletonsEnabled && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
+                if (mesh.skeleton && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
                     attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
                     attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
                     defines.push("#define BONES");
@@ -349,11 +347,9 @@ var BABYLON;
 
             // Get correct effect
             var join = defines.join("\n");
-            if (this._cachedDefines !== join) {
+            if (this._cachedDefines != join) {
                 this._cachedDefines = join;
 
-                scene.resetCachedMaterial();
-
                 // Legacy browser patch
                 var shaderName = "default";
                 if (!scene.getEngine().getCaps().standardDerivatives) {
@@ -404,118 +400,92 @@ var BABYLON;
             this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
             // Bones
-            if (mesh.skeleton && scene.skeletonsEnabled && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
+            if (mesh.skeleton && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
                 this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
             }
 
-            if (scene.getCachedMaterial() !== this) {
-                if (StandardMaterial.FresnelEnabled) {
-                    // Fresnel
-                    if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
-                        this._effect.setColor4("diffuseLeftColor", this.diffuseFresnelParameters.leftColor, this.diffuseFresnelParameters.power);
-                        this._effect.setColor4("diffuseRightColor", this.diffuseFresnelParameters.rightColor, this.diffuseFresnelParameters.bias);
-                    }
-
-                    if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
-                        this._effect.setColor4("opacityParts", new BABYLON.Color3(this.opacityFresnelParameters.leftColor.toLuminance(), this.opacityFresnelParameters.rightColor.toLuminance(), this.opacityFresnelParameters.bias), this.opacityFresnelParameters.power);
-                    }
-
-                    if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
-                        this._effect.setColor4("reflectionLeftColor", this.reflectionFresnelParameters.leftColor, this.reflectionFresnelParameters.power);
-                        this._effect.setColor4("reflectionRightColor", this.reflectionFresnelParameters.rightColor, this.reflectionFresnelParameters.bias);
-                    }
-
-                    if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
-                        this._effect.setColor4("emissiveLeftColor", this.emissiveFresnelParameters.leftColor, this.emissiveFresnelParameters.power);
-                        this._effect.setColor4("emissiveRightColor", this.emissiveFresnelParameters.rightColor, this.emissiveFresnelParameters.bias);
-                    }
-                }
-
-                // Textures
-                if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                    this._effect.setTexture("diffuseSampler", this.diffuseTexture);
-
-                    this._effect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
-                    this._effect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
-                }
+            // Fresnel
+            if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
+                this._effect.setColor4("diffuseLeftColor", this.diffuseFresnelParameters.leftColor, this.diffuseFresnelParameters.power);
+                this._effect.setColor4("diffuseRightColor", this.diffuseFresnelParameters.rightColor, this.diffuseFresnelParameters.bias);
+            }
 
-                if (this.ambientTexture && StandardMaterial.AmbientTextureEnabled) {
-                    this._effect.setTexture("ambientSampler", this.ambientTexture);
+            if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
+                this._effect.setColor4("opacityParts", new BABYLON.Color3(this.opacityFresnelParameters.leftColor.toLuminance(), this.opacityFresnelParameters.rightColor.toLuminance(), this.opacityFresnelParameters.bias), this.opacityFresnelParameters.power);
+            }
 
-                    this._effect.setFloat2("vAmbientInfos", this.ambientTexture.coordinatesIndex, this.ambientTexture.level);
-                    this._effect.setMatrix("ambientMatrix", this.ambientTexture.getTextureMatrix());
-                }
+            if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
+                this._effect.setColor4("reflectionLeftColor", this.reflectionFresnelParameters.leftColor, this.reflectionFresnelParameters.power);
+                this._effect.setColor4("reflectionRightColor", this.reflectionFresnelParameters.rightColor, this.reflectionFresnelParameters.bias);
+            }
 
-                if (this.opacityTexture && StandardMaterial.OpacityTextureEnabled) {
-                    this._effect.setTexture("opacitySampler", this.opacityTexture);
+            if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
+                this._effect.setColor4("emissiveLeftColor", this.emissiveFresnelParameters.leftColor, this.emissiveFresnelParameters.power);
+                this._effect.setColor4("emissiveRightColor", this.emissiveFresnelParameters.rightColor, this.emissiveFresnelParameters.bias);
+            }
 
-                    this._effect.setFloat2("vOpacityInfos", this.opacityTexture.coordinatesIndex, this.opacityTexture.level);
-                    this._effect.setMatrix("opacityMatrix", this.opacityTexture.getTextureMatrix());
-                }
+            // Textures
+            if (this.diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
+                this._effect.setTexture("diffuseSampler", this.diffuseTexture);
 
-                if (this.reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
-                    if (this.reflectionTexture.isCube) {
-                        this._effect.setTexture("reflectionCubeSampler", this.reflectionTexture);
-                    } else {
-                        this._effect.setTexture("reflection2DSampler", this.reflectionTexture);
-                    }
+                this._effect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
+                this._effect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
+            }
 
-                    this._effect.setMatrix("reflectionMatrix", this.reflectionTexture.getReflectionTextureMatrix());
-                    this._effect.setFloat3("vReflectionInfos", this.reflectionTexture.coordinatesMode, this.reflectionTexture.level, this.reflectionTexture.isCube ? 1 : 0);
-                }
+            if (this.ambientTexture && BABYLON.StandardMaterial.AmbientTextureEnabled) {
+                this._effect.setTexture("ambientSampler", this.ambientTexture);
 
-                if (this.emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
-                    this._effect.setTexture("emissiveSampler", this.emissiveTexture);
+                this._effect.setFloat2("vAmbientInfos", this.ambientTexture.coordinatesIndex, this.ambientTexture.level);
+                this._effect.setMatrix("ambientMatrix", this.ambientTexture.getTextureMatrix());
+            }
 
-                    this._effect.setFloat2("vEmissiveInfos", this.emissiveTexture.coordinatesIndex, this.emissiveTexture.level);
-                    this._effect.setMatrix("emissiveMatrix", this.emissiveTexture.getTextureMatrix());
-                }
+            if (this.opacityTexture && BABYLON.StandardMaterial.OpacityTextureEnabled) {
+                this._effect.setTexture("opacitySampler", this.opacityTexture);
 
-                if (this.specularTexture && StandardMaterial.SpecularTextureEnabled) {
-                    this._effect.setTexture("specularSampler", this.specularTexture);
+                this._effect.setFloat2("vOpacityInfos", this.opacityTexture.coordinatesIndex, this.opacityTexture.level);
+                this._effect.setMatrix("opacityMatrix", this.opacityTexture.getTextureMatrix());
+            }
 
-                    this._effect.setFloat2("vSpecularInfos", this.specularTexture.coordinatesIndex, this.specularTexture.level);
-                    this._effect.setMatrix("specularMatrix", this.specularTexture.getTextureMatrix());
+            if (this.reflectionTexture && BABYLON.StandardMaterial.ReflectionTextureEnabled) {
+                if (this.reflectionTexture.isCube) {
+                    this._effect.setTexture("reflectionCubeSampler", this.reflectionTexture);
+                } else {
+                    this._effect.setTexture("reflection2DSampler", this.reflectionTexture);
                 }
 
-                if (this.bumpTexture && scene.getEngine().getCaps().standardDerivatives && StandardMaterial.BumpTextureEnabled) {
-                    this._effect.setTexture("bumpSampler", this.bumpTexture);
+                this._effect.setMatrix("reflectionMatrix", this.reflectionTexture.getReflectionTextureMatrix());
+                this._effect.setFloat3("vReflectionInfos", this.reflectionTexture.coordinatesMode, this.reflectionTexture.level, this.reflectionTexture.isCube ? 1 : 0);
+            }
 
-                    this._effect.setFloat2("vBumpInfos", this.bumpTexture.coordinatesIndex, 1.0 / this.bumpTexture.level);
-                    this._effect.setMatrix("bumpMatrix", this.bumpTexture.getTextureMatrix());
-                }
+            if (this.emissiveTexture && BABYLON.StandardMaterial.EmissiveTextureEnabled) {
+                this._effect.setTexture("emissiveSampler", this.emissiveTexture);
 
-                // Clip plane
-                if (scene.clipPlane) {
-                    var clipPlane = scene.clipPlane;
-                    this._effect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
-                }
+                this._effect.setFloat2("vEmissiveInfos", this.emissiveTexture.coordinatesIndex, this.emissiveTexture.level);
+                this._effect.setMatrix("emissiveMatrix", this.emissiveTexture.getTextureMatrix());
+            }
 
-                // Point size
-                if (this.pointsCloud) {
-                    this._effect.setFloat("pointSize", this.pointSize);
-                }
+            if (this.specularTexture && BABYLON.StandardMaterial.SpecularTextureEnabled) {
+                this._effect.setTexture("specularSampler", this.specularTexture);
 
-                // Colors
-                scene.ambientColor.multiplyToRef(this.ambientColor, this._globalAmbientColor);
+                this._effect.setFloat2("vSpecularInfos", this.specularTexture.coordinatesIndex, this.specularTexture.level);
+                this._effect.setMatrix("specularMatrix", this.specularTexture.getTextureMatrix());
+            }
 
-                // Scaling down color according to emissive
-                this._scaledSpecular.r = this.specularColor.r * BABYLON.Tools.Clamp(1.0 - this.emissiveColor.r);
-                this._scaledSpecular.g = this.specularColor.g * BABYLON.Tools.Clamp(1.0 - this.emissiveColor.g);
-                this._scaledSpecular.b = this.specularColor.b * BABYLON.Tools.Clamp(1.0 - this.emissiveColor.b);
+            if (this.bumpTexture && scene.getEngine().getCaps().standardDerivatives && BABYLON.StandardMaterial.BumpTextureEnabled) {
+                this._effect.setTexture("bumpSampler", this.bumpTexture);
 
-                this._effect.setVector3("vEyePosition", scene.activeCamera.position);
-                this._effect.setColor3("vAmbientColor", this._globalAmbientColor);
-                this._effect.setColor4("vSpecularColor", this._scaledSpecular, this.specularPower);
-                this._effect.setColor3("vEmissiveColor", this.emissiveColor);
+                this._effect.setFloat2("vBumpInfos", this.bumpTexture.coordinatesIndex, this.bumpTexture.level);
+                this._effect.setMatrix("bumpMatrix", this.bumpTexture.getTextureMatrix());
             }
 
-            // Scaling down color according to emissive
-            this._scaledDiffuse.r = this.diffuseColor.r * BABYLON.Tools.Clamp(1.0 - this.emissiveColor.r);
-            this._scaledDiffuse.g = this.diffuseColor.g * BABYLON.Tools.Clamp(1.0 - this.emissiveColor.g);
-            this._scaledDiffuse.b = this.diffuseColor.b * BABYLON.Tools.Clamp(1.0 - this.emissiveColor.b);
+            // Colors
+            scene.ambientColor.multiplyToRef(this.ambientColor, this._globalAmbientColor);
 
-            this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+            this._effect.setVector3("vEyePosition", scene.activeCamera.position);
+            this._effect.setColor3("vAmbientColor", this._globalAmbientColor);
+            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+            this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+            this._effect.setColor3("vEmissiveColor", this.emissiveColor);
 
             if (scene.lightsEnabled) {
                 var lightIndex = 0;
@@ -561,23 +531,31 @@ var BABYLON;
 
                     lightIndex++;
 
-                    if (lightIndex === maxSimultaneousLights)
+                    if (lightIndex == maxSimultaneousLights)
                         break;
                 }
             }
 
+            if (scene.clipPlane) {
+                var clipPlane = scene.clipPlane;
+                this._effect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
+            }
+
             // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE || this.reflectionTexture) {
+            if (scene.fogMode !== BABYLON.Scene.FOGMODE_NONE || this.reflectionTexture) {
                 this._effect.setMatrix("view", scene.getViewMatrix());
             }
 
             // Fog
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
+            if (scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
                 this._effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
                 this._effect.setColor3("vFogColor", scene.fogColor);
             }
 
-            _super.prototype.bind.call(this, world, mesh);
+            // Point size
+            if (this.pointsCloud) {
+                this._effect.setFloat("pointSize", this.pointSize);
+            }
         };
 
         StandardMaterial.prototype.getAnimatables = function () {
@@ -647,7 +625,7 @@ var BABYLON;
         };
 
         StandardMaterial.prototype.clone = function (name) {
-            var newStandardMaterial = new StandardMaterial(name, this.getScene());
+            var newStandardMaterial = new BABYLON.StandardMaterial(name, this.getScene());
 
             // Base material
             newStandardMaterial.checkReadyOnEveryCall = this.checkReadyOnEveryCall;
@@ -694,7 +672,6 @@ var BABYLON;
         StandardMaterial.EmissiveTextureEnabled = true;
         StandardMaterial.SpecularTextureEnabled = true;
         StandardMaterial.BumpTextureEnabled = true;
-        StandardMaterial.FresnelEnabled = true;
         return StandardMaterial;
     })(BABYLON.Material);
     BABYLON.StandardMaterial = StandardMaterial;

+ 51 - 69
Babylon/Materials/textures/Procedurals/babylon.customProceduralTexture.js

@@ -9,43 +9,42 @@ var BABYLON;
     var CustomProceduralTexture = (function (_super) {
         __extends(CustomProceduralTexture, _super);
         function CustomProceduralTexture(name, texturePath, size, scene, fallbackTexture, generateMipMaps) {
-            _super.call(this, name, size, null, scene, fallbackTexture, generateMipMaps);
-            this._animate = true;
+            _super.call(this, name, size, "empty", scene, fallbackTexture, generateMipMaps);
+            this._generateTime = true;
             this._time = 0;
+            this._shaderLoaded = false;
+
             this._texturePath = texturePath;
 
-            //Try to load json
+            //readJson
             this.loadJson(texturePath);
-            this.refreshRate = 1;
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
         }
         CustomProceduralTexture.prototype.loadJson = function (jsonUrl) {
             var _this = this;
-            var that = this;
-
             function noConfigFile() {
-                BABYLON.Tools.Log("No config file found in " + jsonUrl + " trying to use ShaderStore or DOM element");
-                try  {
-                    that.setFragment(that._texturePath);
-                } catch (ex) {
-                    BABYLON.Tools.Error("No json or ShaderStore or DOM element found for CustomProceduralTexture");
-                }
+                BABYLON.Tools.Log("No config file found in " + jsonUrl);
             }
 
+            var that = this;
             var configFileUrl = jsonUrl + "/config.json";
+
             var xhr = new XMLHttpRequest();
 
             xhr.open("GET", configFileUrl, true);
             xhr.addEventListener("load", function () {
                 if (xhr.status === 200 || BABYLON.Tools.ValidateXHRData(xhr, 1)) {
                     try  {
-                        _this._config = JSON.parse(xhr.response);
-
-                        _this.updateShaderUniforms();
-                        _this.updateTextures();
-                        _this.setFragment(_this._texturePath + "/custom");
-
-                        _this._animate = _this._config.animate;
-                        _this.refreshRate = _this._config.refreshrate;
+                        that._config = JSON.parse(xhr.response);
+                        that.updateShaderUniforms();
+                        that.setFragment(jsonUrl + "/custom");
+                        that._generateTime = that._config.generateTime;
+                        if (that._generateTime)
+                            _this.refreshRate = 1;
+                        that._shaderLoaded = true;
+                        that.render();
                     } catch (ex) {
                         noConfigFile();
                     }
@@ -61,28 +60,16 @@ var BABYLON;
             try  {
                 xhr.send();
             } catch (ex) {
-                BABYLON.Tools.Error("CustomProceduralTexture: Error on XHR send request.");
-            }
-        };
-
-        CustomProceduralTexture.prototype.isReady = function () {
-            if (!_super.prototype.isReady.call(this)) {
-                return false;
+                BABYLON.Tools.Error("Error on XHR send request.");
             }
-
-            for (var name in this._textures) {
-                var texture = this._textures[name];
-
-                if (!texture.isReady()) {
-                    return false;
-                }
-            }
-
-            return true;
         };
 
         CustomProceduralTexture.prototype.render = function (useCameraPostProcess) {
-            if (this._animate) {
+            //if config and shader not loaded, do not render
+            if (!this._shaderLoaded)
+                return;
+
+            if (this._generateTime) {
                 this._time += this.getScene().getAnimationRatio() * 0.03;
                 this.updateShaderUniforms();
             }
@@ -90,46 +77,41 @@ var BABYLON;
             _super.prototype.render.call(this, useCameraPostProcess);
         };
 
-        CustomProceduralTexture.prototype.updateTextures = function () {
-            for (var i = 0; i < this._config.sampler2Ds.length; i++) {
-                this.setTexture(this._config.sampler2Ds[i].sample2Dname, new BABYLON.Texture(this._texturePath + "/" + this._config.sampler2Ds[i].textureRelativeUrl, this.getScene()));
+        CustomProceduralTexture.prototype.updateShaderUniforms = function () {
+            for (var i = 0; i < this._config.texture2Ds.length; i++) {
+                this.setTexture(this._config.texture2Ds[i].textureName, new BABYLON.Texture(this._texturePath + "/" + this._config.texture2Ds[i].textureRelativeUrl, this.getScene()));
             }
-        };
 
-        CustomProceduralTexture.prototype.updateShaderUniforms = function () {
-            if (this._config) {
-                for (var j = 0; j < this._config.uniforms.length; j++) {
-                    var uniform = this._config.uniforms[j];
-
-                    switch (uniform.type) {
-                        case "float":
-                            this.setFloat(uniform.name, uniform.value);
-                            break;
-                        case "color3":
-                            this.setColor3(uniform.name, new BABYLON.Color3(uniform.r, uniform.g, uniform.b));
-                            break;
-                        case "color4":
-                            this.setColor4(uniform.name, new BABYLON.Color4(uniform.r, uniform.g, uniform.b, uniform.a));
-                            break;
-                        case "vector2":
-                            this.setVector2(uniform.name, new BABYLON.Vector2(uniform.x, uniform.y));
-                            break;
-                        case "vector3":
-                            this.setVector3(uniform.name, new BABYLON.Vector3(uniform.x, uniform.y, uniform.z));
-                            break;
-                    }
+            for (var j = 0; j < this._config.uniforms.length; j++) {
+                var uniform = this._config.uniforms[j];
+
+                switch (uniform.type) {
+                    case "float":
+                        this.setFloat(uniform.name, uniform.value);
+                        break;
+                    case "color3":
+                        this.setColor3(uniform.name, new BABYLON.Color3(uniform.r, uniform.g, uniform.b));
+                        break;
+                    case "color4":
+                        this.setColor4(uniform.name, new BABYLON.Color4(uniform.r, uniform.g, uniform.b, uniform.a));
+                        break;
+                    case "vector2":
+                        this.setVector2(uniform.name, new BABYLON.Vector2(uniform.x, uniform.y));
+                        break;
+                    case "vector3":
+                        this.setVector3(uniform.name, new BABYLON.Vector3(uniform.x, uniform.y, uniform.z));
+                        break;
                 }
             }
-
-            this.setFloat("time", this._time);
         };
 
-        Object.defineProperty(CustomProceduralTexture.prototype, "animate", {
+        Object.defineProperty(CustomProceduralTexture.prototype, "generateTime", {
             get: function () {
-                return this._animate;
+                return this.generateTime;
             },
             set: function (value) {
-                this._animate = value;
+                this.generateTime = value;
+                this.updateShaderUniforms();
             },
             enumerable: true,
             configurable: true

+ 6 - 43
Babylon/Materials/textures/Procedurals/babylon.proceduralTexture.js

@@ -9,7 +9,6 @@ var BABYLON;
     var ProceduralTexture = (function (_super) {
         __extends(ProceduralTexture, _super);
         function ProceduralTexture(name, size, fragment, scene, fallbackTexture, generateMipMaps) {
-            if (typeof generateMipMaps === "undefined") { generateMipMaps = true; }
             _super.call(this, null, scene, !generateMipMaps);
             this._currentRefreshId = -1;
             this._refreshRate = 1;
@@ -25,7 +24,6 @@ var BABYLON;
             this._vectors2 = new Array();
             this._vectors3 = new Array();
             this._matrices = new Array();
-            this._fallbackTextureUsed = false;
 
             scene._proceduralTextures.push(this);
 
@@ -34,7 +32,7 @@ var BABYLON;
             this._size = size;
             this._generateMipMaps = generateMipMaps;
 
-            this.setFragment(fragment);
+            this._fragment = fragment;
 
             this._fallbackTexture = fallbackTexture;
 
@@ -61,42 +59,15 @@ var BABYLON;
 
             this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
         }
-        ProceduralTexture.prototype.reset = function () {
-            if (this._effect === undefined) {
-                return;
-            }
-            var engine = this.getScene().getEngine();
-            engine._releaseEffect(this._effect);
-        };
-
         ProceduralTexture.prototype.isReady = function () {
             var _this = this;
             var engine = this.getScene().getEngine();
-            var shaders;
 
-            if (!this._fragment) {
-                return false;
-            }
-
-            if (this._fallbackTextureUsed) {
-                return true;
-            }
-
-            if (this._fragment.fragmentElement !== undefined) {
-                shaders = { vertex: "procedural", fragmentElement: this._fragment.fragmentElement };
-            } else {
-                shaders = { vertex: "procedural", fragment: this._fragment };
-            }
-
-            this._effect = engine.createEffect(shaders, ["position"], this._uniforms, this._samplers, "", null, null, function () {
+            this._effect = engine.createEffect({ vertex: "procedural", fragment: this._fragment }, ["position"], this._uniforms, this._samplers, "", null, null, function () {
                 _this.releaseInternalTexture();
 
-                if (_this._fallbackTexture) {
-                    _this._texture = _this._fallbackTexture._texture;
-                    _this._texture.references++;
-                }
-
-                _this._fallbackTextureUsed = true;
+                _this._texture = _this._fallbackTexture._texture;
+                _this._texture.references++;
             });
 
             return this._effect.isReady();
@@ -129,16 +100,12 @@ var BABYLON;
                 return false;
             }
 
-            if (this._fallbackTextureUsed) {
-                return false;
-            }
-
             if (this._currentRefreshId === -1) {
                 this._currentRefreshId = 1;
                 return true;
             }
 
-            if (this.refreshRate === this._currentRefreshId) {
+            if (this.refreshRate == this._currentRefreshId) {
                 this._currentRefreshId = 1;
                 return true;
             }
@@ -152,10 +119,6 @@ var BABYLON;
         };
 
         ProceduralTexture.prototype.resize = function (size, generateMipMaps) {
-            if (this._fallbackTextureUsed) {
-                return;
-            }
-
             this.releaseInternalTexture();
             this._texture = this.getScene().getEngine().createRenderTargetTexture(size, generateMipMaps);
         };
@@ -282,7 +245,7 @@ var BABYLON;
 
         ProceduralTexture.prototype.clone = function () {
             var textureSize = this.getSize();
-            var newTexture = new ProceduralTexture(this.name, textureSize.width, this._fragment, this.getScene(), this._fallbackTexture, this._generateMipMaps);
+            var newTexture = new BABYLON.ProceduralTexture(this.name, textureSize.width, this._fragment, this.getScene(), this._fallbackTexture, this._generateMipMaps);
 
             // Base texture
             newTexture.hasAlpha = this.hasAlpha;

+ 80 - 166
Babylon/Materials/textures/Procedurals/babylon.standardProceduralTexture.js

@@ -12,7 +12,10 @@ var BABYLON;
             _super.call(this, name, size, "wood", scene, fallbackTexture, generateMipMaps);
             this._ampScale = 100.0;
             this._woodColor = new BABYLON.Color3(0.32, 0.17, 0.09);
+
             this.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
             this.refreshRate = 0;
         }
         WoodProceduralTexture.prototype.updateShaderUniforms = function () {
@@ -56,23 +59,27 @@ var BABYLON;
             this._time = 0.0;
             this._speed = new BABYLON.Vector2(0.5, 0.3);
             this._shift = 1.6;
+            this._alpha = 1.0;
             this._autoGenerateTime = true;
-            this._alphaThreshold = 0.5;
+
             this._fireColors = FireProceduralTexture.RedFireColors;
             this.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
             this.refreshRate = 1;
         }
         FireProceduralTexture.prototype.updateShaderUniforms = function () {
-            this.setFloat("time", this._time);
+            this.setFloat("iGlobalTime", this._time);
             this.setVector2("speed", this._speed);
             this.setFloat("shift", this._shift);
-            this.setColor3("c1", this._fireColors[0]);
-            this.setColor3("c2", this._fireColors[1]);
-            this.setColor3("c3", this._fireColors[2]);
-            this.setColor3("c4", this._fireColors[3]);
-            this.setColor3("c5", this._fireColors[4]);
-            this.setColor3("c6", this._fireColors[5]);
-            this.setFloat("alphaThreshold", this._alphaThreshold);
+            this.setFloat("alpha", this._alpha);
+
+            this.setColor3("c1", new BABYLON.Color3(this._fireColors[0][0], this._fireColors[0][1], this._fireColors[0][2]));
+            this.setColor3("c2", new BABYLON.Color3(this._fireColors[1][0], this._fireColors[1][1], this._fireColors[1][2]));
+            this.setColor3("c3", new BABYLON.Color3(this._fireColors[2][0], this._fireColors[2][1], this._fireColors[2][2]));
+            this.setColor3("c4", new BABYLON.Color3(this._fireColors[3][0], this._fireColors[3][1], this._fireColors[3][2]));
+            this.setColor3("c5", new BABYLON.Color3(this._fireColors[4][0], this._fireColors[4][1], this._fireColors[4][2]));
+            this.setColor3("c6", new BABYLON.Color3(this._fireColors[5][0], this._fireColors[5][1], this._fireColors[5][2]));
         };
 
         FireProceduralTexture.prototype.render = function (useCameraPostProcess) {
@@ -80,18 +87,19 @@ var BABYLON;
                 this._time += this.getScene().getAnimationRatio() * 0.03;
                 this.updateShaderUniforms();
             }
+
             _super.prototype.render.call(this, useCameraPostProcess);
         };
 
         Object.defineProperty(FireProceduralTexture, "PurpleFireColors", {
             get: function () {
                 return [
-                    new BABYLON.Color3(0.5, 0.0, 1.0),
-                    new BABYLON.Color3(0.9, 0.0, 1.0),
-                    new BABYLON.Color3(0.2, 0.0, 1.0),
-                    new BABYLON.Color3(1.0, 0.9, 1.0),
-                    new BABYLON.Color3(0.1, 0.1, 1.0),
-                    new BABYLON.Color3(0.9, 0.9, 1.0)
+                    [0.5, 0.0, 1.0],
+                    [0.9, 0.0, 1.0],
+                    [0.2, 0.0, 1.0],
+                    [1.0, 0.9, 1.0],
+                    [0.1, 0.1, 1.0],
+                    [0.9, 0.9, 1.0]
                 ];
             },
             enumerable: true,
@@ -101,12 +109,12 @@ var BABYLON;
         Object.defineProperty(FireProceduralTexture, "GreenFireColors", {
             get: function () {
                 return [
-                    new BABYLON.Color3(0.5, 1.0, 0.0),
-                    new BABYLON.Color3(0.5, 1.0, 0.0),
-                    new BABYLON.Color3(0.3, 0.4, 0.0),
-                    new BABYLON.Color3(0.5, 1.0, 0.0),
-                    new BABYLON.Color3(0.2, 0.0, 0.0),
-                    new BABYLON.Color3(0.5, 1.0, 0.0)
+                    [0.5, 1.0, 0.0],
+                    [0.5, 1.0, 0.0],
+                    [0.3, 0.4, 0.0],
+                    [0.5, 1.0, 0.0],
+                    [0.2, 0.0, 0.0],
+                    [0.5, 1.0, 0.0]
                 ];
             },
             enumerable: true,
@@ -116,12 +124,12 @@ var BABYLON;
         Object.defineProperty(FireProceduralTexture, "RedFireColors", {
             get: function () {
                 return [
-                    new BABYLON.Color3(0.5, 0.0, 0.1),
-                    new BABYLON.Color3(0.9, 0.0, 0.0),
-                    new BABYLON.Color3(0.2, 0.0, 0.0),
-                    new BABYLON.Color3(1.0, 0.9, 0.0),
-                    new BABYLON.Color3(0.1, 0.1, 0.1),
-                    new BABYLON.Color3(0.9, 0.9, 0.9)
+                    [0.5, 0.0, 0.1],
+                    [0.9, 0.0, 0.0],
+                    [0.2, 0.0, 0.0],
+                    [1.0, 0.9, 0.0],
+                    [0.1, 0.1, 0.1],
+                    [0.9, 0.9, 0.9]
                 ];
             },
             enumerable: true,
@@ -131,12 +139,12 @@ var BABYLON;
         Object.defineProperty(FireProceduralTexture, "BlueFireColors", {
             get: function () {
                 return [
-                    new BABYLON.Color3(0.1, 0.0, 0.5),
-                    new BABYLON.Color3(0.0, 0.0, 0.5),
-                    new BABYLON.Color3(0.1, 0.0, 0.2),
-                    new BABYLON.Color3(0.0, 0.0, 1.0),
-                    new BABYLON.Color3(0.1, 0.2, 0.3),
-                    new BABYLON.Color3(0.0, 0.2, 0.9)
+                    [0.1, 0.0, 0.5],
+                    [0.0, 0.0, 0.5],
+                    [0.1, 0.0, 0.2],
+                    [0.0, 0.0, 1.0],
+                    [0.1, 0.2, 0.3],
+                    [0.0, 0.2, 0.9]
                 ];
             },
             enumerable: true,
@@ -195,12 +203,12 @@ var BABYLON;
         });
 
 
-        Object.defineProperty(FireProceduralTexture.prototype, "alphaThreshold", {
+        Object.defineProperty(FireProceduralTexture.prototype, "alpha", {
             get: function () {
-                return this._alphaThreshold;
+                return this._alpha;
             },
             set: function (value) {
-                this._alphaThreshold = value;
+                this._alpha = value;
                 this.updateShaderUniforms();
             },
             enumerable: true,
@@ -217,8 +225,12 @@ var BABYLON;
             _super.call(this, name, size, "cloud", scene, fallbackTexture, generateMipMaps);
             this._skyColor = new BABYLON.Color3(0.15, 0.68, 1.0);
             this._cloudColor = new BABYLON.Color3(1, 1, 1);
+
             this.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
             this.refreshRate = 0;
+            // https://www.shadertoy.com/view/XsjSRt
         }
         CloudProceduralTexture.prototype.updateShaderUniforms = function () {
             this.setColor3("skyColor", this._skyColor);
@@ -258,80 +270,34 @@ var BABYLON;
         __extends(GrassProceduralTexture, _super);
         function GrassProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             _super.call(this, name, size, "grass", scene, fallbackTexture, generateMipMaps);
-            this._herb1 = new BABYLON.Color3(0.29, 0.38, 0.02);
-            this._herb2 = new BABYLON.Color3(0.36, 0.49, 0.09);
-            this._herb3 = new BABYLON.Color3(0.51, 0.6, 0.28);
-            this._groundColor = new BABYLON.Color3(1, 1, 1);
-
-            this._grassColors = [
-                new BABYLON.Color3(0.29, 0.38, 0.02),
-                new BABYLON.Color3(0.36, 0.49, 0.09),
-                new BABYLON.Color3(0.51, 0.6, 0.28)
-            ];
 
-            this.updateShaderUniforms();
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
             this.refreshRate = 0;
         }
-        GrassProceduralTexture.prototype.updateShaderUniforms = function () {
-            this.setColor3("herb1Color", this._grassColors[0]);
-            this.setColor3("herb2Color", this._grassColors[1]);
-            this.setColor3("herb3Color", this._grassColors[2]);
-            this.setColor3("groundColor", this._groundColor);
-        };
-
-        Object.defineProperty(GrassProceduralTexture.prototype, "grassColors", {
-            get: function () {
-                return this._grassColors;
-            },
-            set: function (value) {
-                this._grassColors = value;
-                this.updateShaderUniforms();
-            },
-            enumerable: true,
-            configurable: true
-        });
-
-
-        Object.defineProperty(GrassProceduralTexture.prototype, "groundColor", {
-            get: function () {
-                return this._groundColor;
-            },
-            set: function (value) {
-                this.groundColor = value;
-                this.updateShaderUniforms();
-            },
-            enumerable: true,
-            configurable: true
-        });
-
         return GrassProceduralTexture;
     })(BABYLON.ProceduralTexture);
     BABYLON.GrassProceduralTexture = GrassProceduralTexture;
 
+    var RockProceduralTexture = (function (_super) {
+        __extends(RockProceduralTexture, _super);
+        function RockProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, name, size, "rock", scene, fallbackTexture, generateMipMaps);
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
+        }
+        return RockProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.RockProceduralTexture = RockProceduralTexture;
+
     var RoadProceduralTexture = (function (_super) {
         __extends(RoadProceduralTexture, _super);
         function RoadProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             _super.call(this, name, size, "road", scene, fallbackTexture, generateMipMaps);
-            this._roadColor = new BABYLON.Color3(0.53, 0.53, 0.53);
-            this.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
             this.refreshRate = 0;
         }
-        RoadProceduralTexture.prototype.updateShaderUniforms = function () {
-            this.setColor3("roadColor", this._roadColor);
-        };
-
-        Object.defineProperty(RoadProceduralTexture.prototype, "roadColor", {
-            get: function () {
-                return this._roadColor;
-            },
-            set: function (value) {
-                this._roadColor = value;
-                this.updateShaderUniforms();
-            },
-            enumerable: true,
-            configurable: true
-        });
-
         return RoadProceduralTexture;
     })(BABYLON.ProceduralTexture);
     BABYLON.RoadProceduralTexture = RoadProceduralTexture;
@@ -342,16 +308,15 @@ var BABYLON;
             _super.call(this, name, size, "brick", scene, fallbackTexture, generateMipMaps);
             this._numberOfBricksHeight = 15;
             this._numberOfBricksWidth = 5;
-            this._jointColor = new BABYLON.Color3(0.72, 0.72, 0.72);
-            this._brickColor = new BABYLON.Color3(0.77, 0.47, 0.40);
+
             this.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
             this.refreshRate = 0;
         }
         BrickProceduralTexture.prototype.updateShaderUniforms = function () {
             this.setFloat("numberOfBricksHeight", this._numberOfBricksHeight);
             this.setFloat("numberOfBricksWidth", this._numberOfBricksWidth);
-            this.setColor3("brickColor", this._brickColor);
-            this.setColor3("jointColor", this._jointColor);
         };
 
         Object.defineProperty(BrickProceduralTexture.prototype, "numberOfBricksHeight", {
@@ -383,32 +348,6 @@ var BABYLON;
             configurable: true
         });
 
-
-        Object.defineProperty(BrickProceduralTexture.prototype, "jointColor", {
-            get: function () {
-                return this._jointColor;
-            },
-            set: function (value) {
-                this._jointColor = value;
-                this.updateShaderUniforms();
-            },
-            enumerable: true,
-            configurable: true
-        });
-
-
-        Object.defineProperty(BrickProceduralTexture.prototype, "brickColor", {
-            get: function () {
-                return this._brickColor;
-            },
-            set: function (value) {
-                this._brickColor = value;
-                this.updateShaderUniforms();
-            },
-            enumerable: true,
-            configurable: true
-        });
-
         return BrickProceduralTexture;
     })(BABYLON.ProceduralTexture);
     BABYLON.BrickProceduralTexture = BrickProceduralTexture;
@@ -417,67 +356,42 @@ var BABYLON;
         __extends(MarbleProceduralTexture, _super);
         function MarbleProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             _super.call(this, name, size, "marble", scene, fallbackTexture, generateMipMaps);
-            this._numberOfTilesHeight = 3;
-            this._numberOfTilesWidth = 3;
-            this._amplitude = 9.0;
-            this._marbleColor = new BABYLON.Color3(0.77, 0.47, 0.40);
-            this._jointColor = new BABYLON.Color3(0.72, 0.72, 0.72);
+            this._numberOfBricksHeight = 3;
+            this._numberOfBricksWidth = 3;
+
             this.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
             this.refreshRate = 0;
         }
         MarbleProceduralTexture.prototype.updateShaderUniforms = function () {
-            this.setFloat("numberOfTilesHeight", this._numberOfTilesHeight);
-            this.setFloat("numberOfTilesWidth", this._numberOfTilesWidth);
-            this.setFloat("amplitude", this._amplitude);
-            this.setColor3("marbleColor", this._marbleColor);
-            this.setColor3("jointColor", this._jointColor);
+            this.setFloat("numberOfBricksHeight", this._numberOfBricksHeight);
+            this.setFloat("numberOfBricksWidth", this._numberOfBricksWidth);
         };
 
-        Object.defineProperty(MarbleProceduralTexture.prototype, "numberOfTilesHeight", {
-            get: function () {
-                return this._numberOfTilesHeight;
-            },
-            set: function (value) {
-                this._numberOfTilesHeight = value;
-                this.updateShaderUniforms();
-            },
-            enumerable: true,
-            configurable: true
-        });
-
-
-        Object.defineProperty(MarbleProceduralTexture.prototype, "numberOfTilesWidth", {
+        Object.defineProperty(MarbleProceduralTexture.prototype, "numberOfBricksHeight", {
             get: function () {
-                return this._numberOfTilesWidth;
-            },
-            set: function (value) {
-                this._numberOfTilesWidth = value;
-                this.updateShaderUniforms();
+                return this._numberOfBricksHeight;
             },
             enumerable: true,
             configurable: true
         });
 
-
-        Object.defineProperty(MarbleProceduralTexture.prototype, "jointColor", {
-            get: function () {
-                return this._jointColor;
-            },
+        Object.defineProperty(MarbleProceduralTexture.prototype, "cloudColor", {
             set: function (value) {
-                this._jointColor = value;
+                this._numberOfBricksHeight = value;
                 this.updateShaderUniforms();
             },
             enumerable: true,
             configurable: true
         });
 
-
-        Object.defineProperty(MarbleProceduralTexture.prototype, "marbleColor", {
+        Object.defineProperty(MarbleProceduralTexture.prototype, "numberOfBricksWidth", {
             get: function () {
-                return this._marbleColor;
+                return this._numberOfBricksWidth;
             },
             set: function (value) {
-                this._marbleColor = value;
+                this._numberOfBricksHeight = value;
                 this.updateShaderUniforms();
             },
             enumerable: true,

+ 1 - 1
Babylon/Materials/textures/babylon.baseTexture.js

@@ -116,7 +116,7 @@
             this._texture.references--;
 
             // Final reference ?
-            if (this._texture.references === 0) {
+            if (this._texture.references == 0) {
                 var index = texturesCache.indexOf(this._texture);
                 texturesCache.splice(index, 1);
 

+ 1 - 1
Babylon/Materials/textures/babylon.renderTargetTexture.js

@@ -135,7 +135,7 @@ var BABYLON;
 
                         for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
                             var subMesh = mesh.subMeshes[subIndex];
-                            scene._activeVertices += subMesh.indexCount;
+                            scene._activeVertices += subMesh.verticesCount;
                             this._renderingManager.dispatch(subMesh);
                         }
                     }

+ 0 - 2
Babylon/Materials/textures/babylon.texture.js

@@ -133,8 +133,6 @@ var BABYLON;
                 this._projectionModeMatrix = BABYLON.Matrix.Zero();
             }
 
-            this._cachedCoordinatesMode = this.coordinatesMode;
-
             switch (this.coordinatesMode) {
                 case BABYLON.Texture.SPHERICAL_MODE:
                     BABYLON.Matrix.IdentityToRef(this._cachedTextureMatrix);

+ 0 - 54
Babylon/Math/babylon.math.js

@@ -850,21 +850,6 @@
             return Vector3.TransformCoordinates(vector, finalMatrix);
         };
 
-        Vector3.UnprojectFromTransform = function (source, viewportWidth, viewportHeight, world, transform) {
-            var matrix = world.multiply(transform);
-            matrix.invert();
-            source.x = source.x / viewportWidth * 2 - 1;
-            source.y = -(source.y / viewportHeight * 2 - 1);
-            var vector = BABYLON.Vector3.TransformCoordinates(source, matrix);
-            var num = source.x * matrix.m[3] + source.y * matrix.m[7] + source.z * matrix.m[11] + matrix.m[15];
-
-            if (BABYLON.Tools.WithinEpsilon(num, 1.0)) {
-                vector = vector.scale(1.0 / num);
-            }
-
-            return vector;
-        };
-
         Vector3.Unproject = function (source, viewportWidth, viewportHeight, world, view, projection) {
             var matrix = world.multiply(view).multiply(projection);
             matrix.invert();
@@ -2324,10 +2309,6 @@
                 var min = (minimum.x - this.origin.x) * inv;
                 var max = (maximum.x - this.origin.x) * inv;
 
-                if (max == -Infinity) {
-                    max = Infinity;
-                }
-
                 if (min > max) {
                     var temp = min;
                     min = max;
@@ -2351,10 +2332,6 @@
                 min = (minimum.y - this.origin.y) * inv;
                 max = (maximum.y - this.origin.y) * inv;
 
-                if (max == -Infinity) {
-                    max = Infinity;
-                }
-
                 if (min > max) {
                     temp = min;
                     min = max;
@@ -2378,10 +2355,6 @@
                 min = (minimum.z - this.origin.z) * inv;
                 max = (maximum.z - this.origin.z) * inv;
 
-                if (max == -Infinity) {
-                    max = Infinity;
-                }
-
                 if (min > max) {
                     temp = min;
                     min = max;
@@ -2521,32 +2494,5 @@
     })();
     BABYLON.Axis = Axis;
     ;
-
-    var BezierCurve = (function () {
-        function BezierCurve() {
-        }
-        BezierCurve.interpolate = function (t, x1, y1, x2, y2) {
-            // Extract X (which is equal to time here)
-            var f0 = 1 - 3 * x2 + 3 * x1;
-            var f1 = 3 * x2 - 6 * x1;
-            var f2 = 3 * x1;
-
-            var refinedT = t;
-            for (var i = 0; i < 5; i++) {
-                var refinedT2 = refinedT * refinedT;
-                var refinedT3 = refinedT2 * refinedT;
-
-                var x = f0 * refinedT3 + f1 * refinedT2 + f2 * refinedT;
-                var slope = 1.0 / (3.0 * f0 * refinedT2 + 2.0 * f1 * refinedT + f2);
-                refinedT -= (x - t) * slope;
-                refinedT = Math.min(1, Math.max(0, refinedT));
-            }
-
-            // Resolve cubic bezier for the given x
-            return 3 * Math.pow(1 - refinedT, 2) * refinedT * y1 + 3 * (1 - refinedT) * Math.pow(refinedT, 2) * y2 + Math.pow(refinedT, 3);
-        };
-        return BezierCurve;
-    })();
-    BABYLON.BezierCurve = BezierCurve;
 })(BABYLON || (BABYLON = {}));
 //# sourceMappingURL=babylon.math.js.map

+ 2 - 12
Babylon/Mesh/babylon.InstancedMesh.js

@@ -107,21 +107,11 @@ var BABYLON;
         };
 
         InstancedMesh.prototype._preActivate = function () {
-            if (this._currentLOD) {
-                this._currentLOD._preActivate();
-            }
+            this.sourceMesh._preActivate();
         };
 
         InstancedMesh.prototype._activate = function (renderId) {
-            if (this._currentLOD) {
-                this._currentLOD._registerInstanceForRenderId(this, renderId);
-            }
-        };
-
-        InstancedMesh.prototype.getLOD = function (camera) {
-            this._currentLOD = this.sourceMesh.getLOD(this.getScene().activeCamera, this.getBoundingInfo().boundingSphere);
-
-            return this._currentLOD;
+            this.sourceMesh._registerInstanceForRenderId(this, renderId);
         };
 
         InstancedMesh.prototype._syncSubMeshes = function () {

+ 4 - 45
Babylon/Mesh/babylon.abstractMesh.js

@@ -14,9 +14,8 @@ var BABYLON;
             this.position = new BABYLON.Vector3(0, 0, 0);
             this.rotation = new BABYLON.Vector3(0, 0, 0);
             this.scaling = new BABYLON.Vector3(1, 1, 1);
-            this.billboardMode = AbstractMesh.BILLBOARDMODE_NONE;
+            this.billboardMode = BABYLON.AbstractMesh.BILLBOARDMODE_NONE;
             this.visibility = 1.0;
-            this.alphaIndex = Number.MAX_VALUE;
             this.infiniteDistance = false;
             this.isVisible = true;
             this.isPickable = true;
@@ -30,12 +29,7 @@ var BABYLON;
             this.renderOutline = false;
             this.outlineColor = BABYLON.Color3.Red();
             this.outlineWidth = 0.02;
-            this.renderOverlay = false;
-            this.overlayColor = BABYLON.Color3.Red();
-            this.overlayAlpha = 0.5;
             this.hasVertexAlpha = false;
-            this.useVertexColors = true;
-            this.applyFog = true;
             this.useOctreeForRenderingSelection = true;
             this.useOctreeForPicking = true;
             this.useOctreeForCollisions = true;
@@ -67,7 +61,6 @@ var BABYLON;
             this._isDisposed = false;
             this._renderId = 0;
             this._intersectionsInProgress = new Array();
-            this._onAfterWorldMatrixUpdate = new Array();
 
             scene.meshes.push(this);
         }
@@ -141,10 +134,6 @@ var BABYLON;
         };
 
         AbstractMesh.prototype.getBoundingInfo = function () {
-            if (this._masterMesh) {
-                return this._masterMesh.getBoundingInfo();
-            }
-
             if (!this._boundingInfo) {
                 this._updateBoundingInfo();
             }
@@ -159,10 +148,6 @@ var BABYLON;
         };
 
         AbstractMesh.prototype.getWorldMatrix = function () {
-            if (this._masterMesh) {
-                return this._masterMesh.getWorldMatrix();
-            }
-
             if (this._currentRenderId !== this.getScene().getRenderId()) {
                 this.computeWorldMatrix();
             }
@@ -323,10 +308,6 @@ var BABYLON;
 
             this._boundingInfo._update(this.worldMatrixFromCache);
 
-            this._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);
-        };
-
-        AbstractMesh.prototype._updateSubMeshesBoundingInfo = function (matrix) {
             if (!this.subMeshes) {
                 return;
             }
@@ -334,7 +315,7 @@ var BABYLON;
             for (var subIndex = 0; subIndex < this.subMeshes.length; subIndex++) {
                 var subMesh = this.subMeshes[subIndex];
 
-                subMesh.updateBoundingInfo(matrix);
+                subMesh.updateBoundingInfo(this.worldMatrixFromCache);
             }
         };
 
@@ -423,29 +404,9 @@ var BABYLON;
             // Absolute position
             this._absolutePosition.copyFromFloats(this._worldMatrix.m[12], this._worldMatrix.m[13], this._worldMatrix.m[14]);
 
-            for (var callbackIndex = 0; callbackIndex < this._onAfterWorldMatrixUpdate.length; callbackIndex++) {
-                this._onAfterWorldMatrixUpdate[callbackIndex](this);
-            }
-
             return this._worldMatrix;
         };
 
-        /**
-        * If you'd like to be callbacked after the mesh position, rotation or scaling has been updated
-        * @param func: callback function to add
-        */
-        AbstractMesh.prototype.registerAfterWorldMatrixUpdate = function (func) {
-            this._onAfterWorldMatrixUpdate.push(func);
-        };
-
-        AbstractMesh.prototype.unregisterAfterWorldMatrixUpdate = function (func) {
-            var index = this._onAfterWorldMatrixUpdate.indexOf(func);
-
-            if (index > -1) {
-                this._onAfterWorldMatrixUpdate.splice(index, 1);
-            }
-        };
-
         AbstractMesh.prototype.setPositionWithLocalVector = function (vector3) {
             this.computeWorldMatrix();
 
@@ -552,7 +513,7 @@ var BABYLON;
             this._physicsFriction = options.friction;
             this._physicRestitution = options.restitution;
 
-            return physicsEngine._registerMesh(this, impostor, options);
+            physicsEngine._registerMesh(this, impostor, options);
         };
 
         AbstractMesh.prototype.getPhysicsImpostor = function () {
@@ -600,7 +561,7 @@ var BABYLON;
                 camera = this.getScene().activeCamera;
             }
 
-            return this.absolutePosition.subtract(camera.position).length();
+            return this.absolutePosition.subtract(camera.position);
         };
 
         AbstractMesh.prototype.applyImpulse = function (force, contactPoint) {
@@ -864,8 +825,6 @@ var BABYLON;
                 }
             }
 
-            this._onAfterWorldMatrixUpdate = [];
-
             this._isDisposed = true;
 
             // Callback

+ 5 - 10
Babylon/Mesh/babylon.geometry.js

@@ -74,14 +74,14 @@ var BABYLON;
             }
         };
 
-        Geometry.prototype.updateVerticesDataDirectly = function (kind, data, offset) {
+        Geometry.prototype.updateVerticesDataDirectly = function (kind, data) {
             var vertexBuffer = this.getVertexBuffer(kind);
 
             if (!vertexBuffer) {
                 return;
             }
 
-            vertexBuffer.updateDirectly(data, offset);
+            vertexBuffer.updateDirectly(data);
         };
 
         Geometry.prototype.updateVerticesData = function (kind, data, updateExtends) {
@@ -96,10 +96,9 @@ var BABYLON;
             if (kind === BABYLON.VertexBuffer.PositionKind) {
                 var extend;
 
-                var stride = vertexBuffer.getStrideSize();
-                this._totalVertices = data.length / stride;
-
                 if (updateExtends) {
+                    var stride = vertexBuffer.getStrideSize();
+                    this._totalVertices = data.length / stride;
                     extend = BABYLON.Tools.ExtractMinAndMax(data, 0, this._totalVertices);
                 }
 
@@ -171,7 +170,7 @@ var BABYLON;
             return result;
         };
 
-        Geometry.prototype.setIndices = function (indices, totalVertices) {
+        Geometry.prototype.setIndices = function (indices) {
             if (this._indexBuffer) {
                 this._engine._releaseBuffer(this._indexBuffer);
             }
@@ -181,10 +180,6 @@ var BABYLON;
                 this._indexBuffer = this._engine.createIndexBuffer(this._indices);
             }
 
-            if (totalVertices !== undefined) {
-                this._totalVertices = totalVertices;
-            }
-
             var meshes = this._meshes;
             var numOfMeshes = meshes.length;
 

+ 34 - 93
Babylon/Mesh/babylon.mesh.js

@@ -31,15 +31,7 @@ var BABYLON;
             this._batchCache = new _InstancesBatch();
             this._instancesBufferSize = 32 * 16 * 4;
         }
-        Object.defineProperty(Mesh.prototype, "hasLODLevels", {
-            // Methods
-            get: function () {
-                return this._LODLevels.length > 0;
-            },
-            enumerable: true,
-            configurable: true
-        });
-
+        // Methods
         Mesh.prototype._sortLODLevels = function () {
             this._LODLevels.sort(function (a, b) {
                 if (a.distance < b.distance) {
@@ -54,16 +46,11 @@ var BABYLON;
         };
 
         Mesh.prototype.addLODLevel = function (distance, mesh) {
-            if (mesh && mesh._masterMesh) {
-                BABYLON.Tools.Warn("You cannot use a mesh as LOD level twice");
-                return this;
-            }
-
             var level = new BABYLON.Internals.MeshLODLevel(distance, mesh);
             this._LODLevels.push(level);
 
             if (mesh) {
-                mesh._masterMesh = this;
+                mesh._attachedLODLevel = level;
             }
 
             this._sortLODLevels();
@@ -72,25 +59,37 @@ var BABYLON;
         };
 
         Mesh.prototype.removeLODLevel = function (mesh) {
-            for (var index = 0; index < this._LODLevels.length; index++) {
-                if (this._LODLevels[index].mesh === mesh) {
-                    this._LODLevels.splice(index, 1);
-                    if (mesh) {
-                        mesh._masterMesh = null;
+            if (mesh && !mesh._attachedLODLevel) {
+                return this;
+            }
+
+            var index;
+
+            if (mesh) {
+                index = this._LODLevels.indexOf(mesh._attachedLODLevel);
+                mesh._attachedLODLevel = null;
+
+                this._LODLevels.splice(index, 1);
+
+                this._sortLODLevels();
+            } else {
+                for (index = 0; index < this._LODLevels.length; index++) {
+                    if (this._LODLevels[index].mesh === null) {
+                        this._LODLevels.splice(index, 1);
+                        break;
                     }
                 }
             }
 
-            this._sortLODLevels();
             return this;
         };
 
-        Mesh.prototype.getLOD = function (camera, boundingSphere) {
+        Mesh.prototype.getLOD = function (camera) {
             if (!this._LODLevels || this._LODLevels.length === 0) {
                 return this;
             }
 
-            var distanceToCamera = (boundingSphere ? boundingSphere : this.getBoundingInfo().boundingSphere).centerWorld.subtract(camera.position).length();
+            var distanceToCamera = this.getBoundingInfo().boundingSphere.centerWorld.subtract(camera.position).length();
 
             if (this._LODLevels[this._LODLevels.length - 1].distance > distanceToCamera) {
                 return this;
@@ -101,8 +100,7 @@ var BABYLON;
 
                 if (level.distance < distanceToCamera) {
                     if (level.mesh) {
-                        level.mesh._preActivate();
-                        level.mesh._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);
+                        level.mesh._worldMatrix = this._worldMatrix;
                     }
                     return level.mesh;
                 }
@@ -179,7 +177,7 @@ var BABYLON;
 
         Object.defineProperty(Mesh.prototype, "isBlocked", {
             get: function () {
-                return this._masterMesh !== null && this._masterMesh !== undefined;
+                return this._attachedLODLevel !== null && this._attachedLODLevel !== undefined;
             },
             enumerable: true,
             configurable: true
@@ -309,15 +307,15 @@ var BABYLON;
             }
         };
 
-        Mesh.prototype.updateVerticesDataDirectly = function (kind, data, offset, makeItUnique) {
+        Mesh.prototype.updateVerticesDataDirectly = function (kind, data, makeItUnique) {
             if (!this._geometry) {
                 return;
             }
             if (!makeItUnique) {
-                this._geometry.updateVerticesDataDirectly(kind, data, offset);
+                this._geometry.updateVerticesDataDirectly(kind, data);
             } else {
                 this.makeGeometryUnique();
-                this.updateVerticesDataDirectly(kind, data, offset, false);
+                this.updateVerticesDataDirectly(kind, data, false);
             }
         };
 
@@ -329,7 +327,7 @@ var BABYLON;
             geometry.applyToMesh(this);
         };
 
-        Mesh.prototype.setIndices = function (indices, totalVertices) {
+        Mesh.prototype.setIndices = function (indices) {
             if (!this._geometry) {
                 var vertexData = new BABYLON.VertexData();
                 vertexData.indices = indices;
@@ -338,7 +336,7 @@ var BABYLON;
 
                 new BABYLON.Geometry(BABYLON.Geometry.RandomId(), scene, vertexData, false, this);
             } else {
-                this._geometry.setIndices(indices, totalVertices);
+                this._geometry.setIndices(indices);
             }
         };
 
@@ -443,8 +441,7 @@ var BABYLON;
         };
 
         Mesh.prototype._renderWithInstances = function (subMesh, fillMode, batch, effect, engine) {
-            var visibleInstances = batch.visibleInstances[subMesh._id];
-            var matricesCount = visibleInstances.length + 1;
+            var matricesCount = this.instances.length + 1;
             var bufferSize = matricesCount * 16 * 4;
 
             while (this._instancesBufferSize < bufferSize) {
@@ -470,6 +467,8 @@ var BABYLON;
                 instancesCount++;
             }
 
+            var visibleInstances = batch.visibleInstances[subMesh._id];
+
             if (visibleInstances) {
                 for (var instanceIndex = 0; instanceIndex < visibleInstances.length; instanceIndex++) {
                     var instance = visibleInstances[instanceIndex];
@@ -513,7 +512,7 @@ var BABYLON;
             }
 
             var engine = scene.getEngine();
-            var hardwareInstancedRendering = (engine.getCaps().instancedArrays !== null) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
+            var hardwareInstancedRendering = (engine.getCaps().instancedArrays !== null) && (batch.visibleInstances[subMesh._id] !== null);
 
             // Material
             var effectiveMaterial = subMesh.getMaterial();
@@ -527,18 +526,16 @@ var BABYLON;
             if (this.renderOutline) {
                 engine.setDepthWrite(false);
                 scene.getOutlineRenderer().render(subMesh, batch);
-                engine.setDepthWrite(savedDepthWrite);
             }
 
             effectiveMaterial._preBind();
             var effect = effectiveMaterial.getEffect();
 
             // Bind
-            var fillMode = scene.forcePointsCloud ? BABYLON.Material.PointFillMode : (scene.forceWireframe ? BABYLON.Material.WireFrameFillMode : effectiveMaterial.fillMode);
+            var fillMode = engine.forceWireframe ? BABYLON.Material.WireFrameFillMode : effectiveMaterial.fillMode;
             this._bind(subMesh, effect, fillMode);
 
             var world = this.getWorldMatrix();
-
             effectiveMaterial.bind(world, this);
 
             // Instances rendering
@@ -575,14 +572,6 @@ var BABYLON;
                 engine.setColorWrite(true);
             }
 
-            // Overlay
-            if (this.renderOverlay) {
-                var currentMode = engine.getAlphaMode();
-                engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
-                scene.getOutlineRenderer().render(subMesh, batch, true);
-                engine.setAlphaMode(currentMode);
-            }
-
             for (callbackIndex = 0; callbackIndex < this._onAfterRenderCallbacks.length; callbackIndex++) {
                 this._onAfterRenderCallbacks[callbackIndex]();
             }
@@ -1141,54 +1130,6 @@ var BABYLON;
             var minMaxVector = meshesOrMinMaxVector.min !== undefined ? meshesOrMinMaxVector : BABYLON.Mesh.MinMax(meshesOrMinMaxVector);
             return BABYLON.Vector3.Center(minMaxVector.min, minMaxVector.max);
         };
-
-        Mesh.MergeMeshes = function (meshes, disposeSource, allow32BitsIndices) {
-            if (typeof disposeSource === "undefined") { disposeSource = true; }
-            var source = meshes[0];
-            var material = source.material;
-            var scene = source.getScene();
-
-            if (!allow32BitsIndices) {
-                var totalVertices = 0;
-
-                for (var index = 0; index < meshes.length; index++) {
-                    totalVertices += meshes[index].getTotalVertices();
-
-                    if (totalVertices > 65536) {
-                        BABYLON.Tools.Warn("Cannot merge meshes because resulting mesh will have more than 65536 vertices. Please use allow32BitsIndices = true to use 32 bits indices");
-                        return null;
-                    }
-                }
-            }
-
-            // Merge
-            var vertexData = BABYLON.VertexData.ExtractFromMesh(source);
-            vertexData.transform(source.getWorldMatrix());
-
-            for (index = 1; index < meshes.length; index++) {
-                var otherVertexData = BABYLON.VertexData.ExtractFromMesh(meshes[index]);
-                otherVertexData.transform(meshes[index].getWorldMatrix());
-
-                vertexData.merge(otherVertexData);
-            }
-
-            var newMesh = new Mesh(source.name + "_merged", scene);
-
-            vertexData.applyToMesh(newMesh);
-
-            // Setting properties
-            newMesh.material = material;
-            newMesh.checkCollisions = source.checkCollisions;
-
-            // Cleaning
-            if (disposeSource) {
-                for (index = 0; index < meshes.length; index++) {
-                    meshes[index].dispose();
-                }
-            }
-
-            return newMesh;
-        };
         return Mesh;
     })(BABYLON.AbstractMesh);
     BABYLON.Mesh = Mesh;

+ 2 - 2
Babylon/Mesh/babylon.vertexBuffer.js

@@ -90,13 +90,13 @@
             this.create(data);
         };
 
-        VertexBuffer.prototype.updateDirectly = function (data, offset) {
+        VertexBuffer.prototype.updateDirectly = function (data) {
             if (!this._buffer) {
                 return;
             }
 
             if (this._updatable) {
-                this._engine.updateDynamicVertexBuffer(this._buffer, data, offset);
+                this._engine.updateDynamicVertexBuffer(this._buffer, data);
                 this._data = null;
             }
         };

+ 7 - 8
Babylon/Particles/babylon.particleSystem.js

@@ -1,7 +1,7 @@
 var BABYLON;
 (function (BABYLON) {
     var randomNumber = function (min, max) {
-        if (min === max) {
+        if (min == max) {
             return (min);
         }
 
@@ -29,7 +29,7 @@
             this.maxSize = 1;
             this.minAngularSpeed = 0;
             this.maxAngularSpeed = 0;
-            this.blendMode = ParticleSystem.BLENDMODE_ONEONE;
+            this.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;
             this.forceDepthWrite = false;
             this.gravity = BABYLON.Vector3.Zero();
             this.direction1 = new BABYLON.Vector3(0, 1.0, 0);
@@ -173,7 +173,7 @@
             }
 
             for (index = 0; index < newParticles; index++) {
-                if (this.particles.length === this._capacity) {
+                if (this.particles.length == this._capacity) {
                     break;
                 }
 
@@ -219,7 +219,7 @@
 
             // Effect
             var join = defines.join("\n");
-            if (this._cachedDefines !== join) {
+            if (this._cachedDefines != join) {
                 this._cachedDefines = join;
 
                 this._effect = this._scene.getEngine().createEffect("particles", ["position", "color", "options"], ["invView", "view", "projection", "vClipPlane", "textureMask"], ["diffuseSampler"], join);
@@ -298,7 +298,7 @@
                 this._appendParticleVertex(offset++, particle, 0, 1);
             }
             var engine = this._scene.getEngine();
-            engine.updateDynamicVertexBuffer(this._vertexBuffer, this._vertices);
+            engine.updateDynamicVertexBuffer(this._vertexBuffer, this._vertices, this.particles.length * this._vertexStrideSize);
         };
 
         ParticleSystem.prototype.render = function () {
@@ -312,7 +312,6 @@
 
             // Render
             engine.enableEffect(effect);
-            engine.setState(false);
 
             var viewMatrix = this._scene.getViewMatrix();
             effect.setTexture("diffuseSampler", this.particleTexture);
@@ -332,7 +331,7 @@
             engine.bindBuffers(this._vertexBuffer, this._indexBuffer, this._vertexDeclaration, this._vertexStrideSize, effect);
 
             // Draw order
-            if (this.blendMode === ParticleSystem.BLENDMODE_ONEONE) {
+            if (this.blendMode === BABYLON.ParticleSystem.BLENDMODE_ONEONE) {
                 engine.setAlphaMode(BABYLON.Engine.ALPHA_ADD);
             } else {
                 engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
@@ -376,7 +375,7 @@
 
         // Clone
         ParticleSystem.prototype.clone = function (name, newEmitter) {
-            var result = new ParticleSystem(name, this._capacity, this._scene);
+            var result = new BABYLON.ParticleSystem(name, this._capacity, this._scene);
 
             BABYLON.Tools.DeepCopy(this, result, ["particles"], ["_vertexDeclaration", "_vertexStrideSize"]);
 

+ 0 - 2
Babylon/Physics/Plugins/babylon.oimoJSPlugin.js

@@ -304,7 +304,6 @@ var BABYLON;
                             mesh.rotationQuaternion = new BABYLON.Quaternion(0, 0, 0, 1);
                         }
                         mesh.rotationQuaternion.fromRotationMatrix(mtx);
-                        mesh.computeWorldMatrix();
                     } else {
                         m = body.getMatrix();
                         mtx = BABYLON.Matrix.FromArray(m);
@@ -326,7 +325,6 @@ var BABYLON;
                             mesh.rotationQuaternion = new BABYLON.Quaternion(0, 0, 0, 1);
                         }
                         mesh.rotationQuaternion.fromRotationMatrix(mtx);
-                        mesh.computeWorldMatrix();
                     }
                 }
             }

+ 5 - 5
Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.js

@@ -9,12 +9,12 @@ var BABYLON;
             this._getPostProcess = getPostProcess;
 
             this._cameras = [];
-            this._indicesForCamera = [];
 
-            this._postProcesses = {};
+            this._postProcesses = [];
+            this._indicesForCamera = [];
 
-            this._renderPasses = {};
-            this._renderEffectAsPasses = {};
+            this._renderPasses = [];
+            this._renderEffectAsPasses = [];
         }
         PostProcessRenderEffect.prototype._update = function () {
             for (var renderPassName in this._renderPasses) {
@@ -49,7 +49,7 @@ var BABYLON;
         };
 
         PostProcessRenderEffect.prototype.emptyPasses = function () {
-            this._renderPasses = {};
+            this._renderPasses.length = 0;
 
             this._linkParameters();
         };

+ 2 - 2
Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.js

@@ -5,8 +5,8 @@ var BABYLON;
             this._engine = engine;
             this._name = name;
 
-            this._renderEffects = {};
-            this._renderEffectsForIsolatedPass = {};
+            this._renderEffects = [];
+            this._renderEffectsForIsolatedPass = [];
 
             this._cameras = [];
         }

+ 1 - 1
Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.js

@@ -2,7 +2,7 @@ var BABYLON;
 (function (BABYLON) {
     var PostProcessRenderPipelineManager = (function () {
         function PostProcessRenderPipelineManager() {
-            this._renderPipelines = {};
+            this._renderPipelines = new Array();
         }
         PostProcessRenderPipelineManager.prototype.addPipeline = function (renderPipeline) {
             this._renderPipelines[renderPipeline._name] = renderPipeline;

+ 1 - 3
Babylon/Rendering/babylon.boundingBoxRenderer.js

@@ -22,7 +22,7 @@
         };
 
         BoundingBoxRenderer.prototype.render = function () {
-            if (this.renderList.length === 0 || !this._colorShader.isReady()) {
+            if (this.renderList.length == 0 || !this._colorShader.isReady()) {
                 return;
             }
 
@@ -44,7 +44,6 @@
                 if (this.showBackLines) {
                     // Back
                     engine.setDepthFunctionToGreaterOrEqual();
-                    this._scene.resetCachedMaterial();
                     this._colorShader.setColor4("color", this.backColor.toColor4());
                     this._colorShader.bind(worldMatrix);
 
@@ -54,7 +53,6 @@
 
                 // Front
                 engine.setDepthFunctionToLess();
-                this._scene.resetCachedMaterial();
                 this._colorShader.setColor4("color", this.frontColor.toColor4());
                 this._colorShader.bind(worldMatrix);
 

+ 5 - 6
Babylon/Rendering/babylon.outlineRenderer.js

@@ -4,12 +4,11 @@
         function OutlineRenderer(scene) {
             this._scene = scene;
         }
-        OutlineRenderer.prototype.render = function (subMesh, batch, useOverlay) {
-            if (typeof useOverlay === "undefined") { useOverlay = false; }
+        OutlineRenderer.prototype.render = function (subMesh, batch) {
             var scene = this._scene;
             var engine = this._scene.getEngine();
 
-            var hardwareInstancedRendering = (engine.getCaps().instancedArrays !== null) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
+            var hardwareInstancedRendering = (engine.getCaps().instancedArrays !== null) && (batch.visibleInstances !== null);
 
             if (!this.isReady(subMesh, hardwareInstancedRendering)) {
                 return;
@@ -19,12 +18,12 @@
             var material = subMesh.getMaterial();
 
             engine.enableEffect(this._effect);
-            this._effect.setFloat("offset", useOverlay ? 0 : mesh.outlineWidth);
-            this._effect.setColor4("color", useOverlay ? mesh.overlayColor : mesh.outlineColor, useOverlay ? mesh.overlayAlpha : 1.0);
+            this._effect.setFloat("offset", mesh.outlineWidth);
+            this._effect.setColor3("color", mesh.outlineColor);
             this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
             // Bones
-            var useBones = mesh.skeleton && scene.skeletonsEnabled && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind);
+            var useBones = mesh.skeleton && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind);
             if (useBones) {
                 this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
             }

+ 12 - 13
Babylon/Rendering/babylon.renderingGroup.js

@@ -8,9 +8,9 @@
             this._alphaTestSubMeshes = new BABYLON.SmartArray(256);
             this._scene = scene;
         }
-        RenderingGroup.prototype.render = function (customRenderFunction) {
+        RenderingGroup.prototype.render = function (customRenderFunction, beforeTransparents) {
             if (customRenderFunction) {
-                customRenderFunction(this._opaqueSubMeshes, this._alphaTestSubMeshes, this._transparentSubMeshes);
+                customRenderFunction(this._opaqueSubMeshes, this._alphaTestSubMeshes, this._transparentSubMeshes, beforeTransparents);
                 return true;
             }
 
@@ -25,6 +25,7 @@
 
             for (subIndex = 0; subIndex < this._opaqueSubMeshes.length; subIndex++) {
                 submesh = this._opaqueSubMeshes.data[subIndex];
+                this._activeVertices += submesh.verticesCount;
 
                 submesh.render();
             }
@@ -33,31 +34,26 @@
             engine.setAlphaTesting(true);
             for (subIndex = 0; subIndex < this._alphaTestSubMeshes.length; subIndex++) {
                 submesh = this._alphaTestSubMeshes.data[subIndex];
+                this._activeVertices += submesh.verticesCount;
 
                 submesh.render();
             }
             engine.setAlphaTesting(false);
 
+            if (beforeTransparents) {
+                beforeTransparents();
+            }
+
             // Transparent
             if (this._transparentSubMeshes.length) {
                 for (subIndex = 0; subIndex < this._transparentSubMeshes.length; subIndex++) {
                     submesh = this._transparentSubMeshes.data[subIndex];
-                    submesh._alphaIndex = submesh.getMesh().alphaIndex;
                     submesh._distanceToCamera = submesh.getBoundingInfo().boundingSphere.centerWorld.subtract(this._scene.activeCamera.position).length();
                 }
 
                 var sortedArray = this._transparentSubMeshes.data.slice(0, this._transparentSubMeshes.length);
 
                 sortedArray.sort(function (a, b) {
-                    // Alpha index first
-                    if (a._alphaIndex > b._alphaIndex) {
-                        return 1;
-                    }
-                    if (a._alphaIndex < b._alphaIndex) {
-                        return -1;
-                    }
-
-                    // Then distance to camera
                     if (a._distanceToCamera < b._distanceToCamera) {
                         return 1;
                     }
@@ -72,6 +68,7 @@
                 engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
                 for (subIndex = 0; subIndex < sortedArray.length; subIndex++) {
                     submesh = sortedArray[subIndex];
+                    this._activeVertices += submesh.verticesCount;
 
                     submesh.render();
                 }
@@ -91,7 +88,9 @@
             var mesh = subMesh.getMesh();
 
             if (material.needAlphaBlending() || mesh.visibility < 1.0 || mesh.hasVertexAlpha) {
-                this._transparentSubMeshes.push(subMesh);
+                if (material.alpha > 0 || mesh.visibility < 1.0) {
+                    this._transparentSubMeshes.push(subMesh);
+                }
             } else if (material.needAlphaTesting()) {
                 this._alphaTestSubMeshes.push(subMesh);
             } else {

+ 9 - 2
Babylon/Rendering/babylon.renderingManager.js

@@ -56,17 +56,24 @@
         };
 
         RenderingManager.prototype.render = function (customRenderFunction, activeMeshes, renderParticles, renderSprites) {
+            var _this = this;
             for (var index = 0; index < BABYLON.RenderingManager.MAX_RENDERINGGROUPS; index++) {
                 this._depthBufferAlreadyCleaned = false;
                 var renderingGroup = this._renderingGroups[index];
 
                 if (renderingGroup) {
                     this._clearDepthBuffer();
-                    if (!renderingGroup.render(customRenderFunction)) {
+                    if (!renderingGroup.render(customRenderFunction, function () {
+                        if (renderSprites) {
+                            _this._renderSprites(index);
+                        }
+                    })) {
                         this._renderingGroups.splice(index, 1);
                     }
+                } else if (renderSprites) {
+                    this._renderSprites(index);
                 }
-                this._renderSprites(index);
+
                 if (renderParticles) {
                     this._renderParticles(index, activeMeshes);
                 }

+ 3 - 3
Babylon/Sprites/babylon.spriteManager.js

@@ -103,12 +103,12 @@
                 this._appendSpriteVertex(offset++, sprite, 1, 1, rowSize);
                 this._appendSpriteVertex(offset++, sprite, 0, 1, rowSize);
             }
-            engine.updateDynamicVertexBuffer(this._vertexBuffer, this._vertices);
+            engine.updateDynamicVertexBuffer(this._vertexBuffer, this._vertices, max * this._vertexStrideSize);
 
             // Render
             var effect = this._effectBase;
 
-            if (this._scene.fogEnabled && this._scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
+            if (this._scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
                 effect = this._effectFog;
             }
 
@@ -122,7 +122,7 @@
             effect.setFloat2("textureInfos", this.cellSize / baseSize.width, this.cellSize / baseSize.height);
 
             // Fog
-            if (this._scene.fogEnabled && this._scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
+            if (this._scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
                 effect.setFloat4("vFogInfos", this._scene.fogMode, this._scene.fogStart, this._scene.fogEnd, this._scene.fogDensity);
                 effect.setColor3("vFogColor", this._scene.fogColor);
             }

+ 0 - 82
Babylon/Tools/babylon.sceneOptimizer.js

@@ -140,85 +140,6 @@ var BABYLON;
     })(SceneOptimization);
     BABYLON.RenderTargetsOptimization = RenderTargetsOptimization;
 
-    var MergeMeshesOptimization = (function (_super) {
-        __extends(MergeMeshesOptimization, _super);
-        function MergeMeshesOptimization() {
-            _super.apply(this, arguments);
-            var _this = this;
-            this._canBeMerged = function (abstractMesh) {
-                if (!(abstractMesh instanceof BABYLON.Mesh)) {
-                    return false;
-                }
-
-                var mesh = abstractMesh;
-
-                if (!mesh.isVisible || !mesh.isEnabled()) {
-                    return false;
-                }
-
-                if (mesh.instances.length > 0) {
-                    return false;
-                }
-
-                if (mesh.skeleton || mesh.hasLODLevels) {
-                    return false;
-                }
-
-                return true;
-            };
-            this.apply = function (scene) {
-                var globalPool = scene.meshes.slice(0);
-                var globalLength = globalPool.length;
-
-                for (var index = 0; index < globalLength; index++) {
-                    var currentPool = new Array();
-                    var current = globalPool[index];
-
-                    // Checks
-                    if (!_this._canBeMerged(current)) {
-                        continue;
-                    }
-
-                    currentPool.push(current);
-
-                    for (var subIndex = index + 1; subIndex < globalLength; subIndex++) {
-                        var otherMesh = globalPool[subIndex];
-
-                        if (!_this._canBeMerged(otherMesh)) {
-                            continue;
-                        }
-
-                        if (otherMesh.material !== current.material) {
-                            continue;
-                        }
-
-                        if (otherMesh.checkCollisions !== current.checkCollisions) {
-                            continue;
-                        }
-
-                        currentPool.push(otherMesh);
-                        globalLength--;
-
-                        globalPool.splice(subIndex, 1);
-
-                        subIndex--;
-                    }
-
-                    if (currentPool.length < 2) {
-                        continue;
-                    }
-
-                    // Merge meshes
-                    BABYLON.Mesh.MergeMeshes(currentPool);
-                }
-
-                return true;
-            };
-        }
-        return MergeMeshesOptimization;
-    })(SceneOptimization);
-    BABYLON.MergeMeshesOptimization = MergeMeshesOptimization;
-
     // Options
     var SceneOptimizerOptions = (function () {
         function SceneOptimizerOptions(targetFrameRate, trackerDuration) {
@@ -232,7 +153,6 @@ var BABYLON;
             var result = new SceneOptimizerOptions(targetFrameRate);
 
             var priority = 0;
-            result.optimizations.push(new MergeMeshesOptimization(priority));
             result.optimizations.push(new ShadowsOptimization(priority));
             result.optimizations.push(new LensFlaresOptimization(priority));
 
@@ -252,7 +172,6 @@ var BABYLON;
             var result = new SceneOptimizerOptions(targetFrameRate);
 
             var priority = 0;
-            result.optimizations.push(new MergeMeshesOptimization(priority));
             result.optimizations.push(new ShadowsOptimization(priority));
             result.optimizations.push(new LensFlaresOptimization(priority));
 
@@ -280,7 +199,6 @@ var BABYLON;
             var result = new SceneOptimizerOptions(targetFrameRate);
 
             var priority = 0;
-            result.optimizations.push(new MergeMeshesOptimization(priority));
             result.optimizations.push(new ShadowsOptimization(priority));
             result.optimizations.push(new LensFlaresOptimization(priority));
 

+ 4 - 44
Babylon/Tools/babylon.tools.js

@@ -280,17 +280,6 @@
         };
 
         // Misc.
-        Tools.Clamp = function (value, min, max) {
-            if (typeof min === "undefined") { min = 0; }
-            if (typeof max === "undefined") { max = 1; }
-            return Math.min(max, Math.max(min, value));
-        };
-
-        Tools.Format = function (value, decimals) {
-            if (typeof decimals === "undefined") { decimals = 2; }
-            return value.toFixed(decimals);
-        };
-
         Tools.CheckExtends = function (v, min, max) {
             if (v.x < min.x)
                 min.x = v.x;
@@ -608,64 +597,36 @@
             configurable: true
         });
 
-        Tools._AddLogEntry = function (entry) {
-            Tools._LogCache = entry + Tools._LogCache;
-
-            if (Tools.OnNewCacheEntry) {
-                Tools.OnNewCacheEntry(entry);
-            }
-        };
-
         Tools._FormatMessage = function (message) {
             var padStr = function (i) {
                 return (i < 10) ? "0" + i : "" + i;
             };
 
             var date = new Date();
-            return "[" + padStr(date.getHours()) + ":" + padStr(date.getMinutes()) + ":" + padStr(date.getSeconds()) + "]: " + message;
+            return "BJS - [" + padStr(date.getHours()) + ":" + padStr(date.getMinutes()) + ":" + padStr(date.getSeconds()) + "]: " + message;
         };
 
         Tools._LogDisabled = function (message) {
             // nothing to do
         };
         Tools._LogEnabled = function (message) {
-            var formattedMessage = Tools._FormatMessage(message);
-            console.log("BJS - " + formattedMessage);
-
-            var entry = "<div style='color:white'>" + formattedMessage + "</div><br>";
-            Tools._AddLogEntry(entry);
+            console.log(Tools._FormatMessage(message));
         };
 
         Tools._WarnDisabled = function (message) {
             // nothing to do
         };
         Tools._WarnEnabled = function (message) {
-            var formattedMessage = Tools._FormatMessage(message);
-            console.warn("BJS - " + formattedMessage);
-
-            var entry = "<div style='color:orange'>" + formattedMessage + "</div><br>";
-            Tools._AddLogEntry(entry);
+            console.warn(Tools._FormatMessage(message));
         };
 
         Tools._ErrorDisabled = function (message) {
             // nothing to do
         };
         Tools._ErrorEnabled = function (message) {
-            var formattedMessage = Tools._FormatMessage(message);
-            console.error("BJS - " + formattedMessage);
-
-            var entry = "<div style='color:red'>" + formattedMessage + "</div><br>";
-            Tools._AddLogEntry(entry);
+            console.error(Tools._FormatMessage(message));
         };
 
-        Object.defineProperty(Tools, "LogCache", {
-            get: function () {
-                return Tools._LogCache;
-            },
-            enumerable: true,
-            configurable: true
-        });
-
         Object.defineProperty(Tools, "LogLevels", {
             set: function (level) {
                 if ((level & Tools.MessageLogLevel) === Tools.MessageLogLevel) {
@@ -814,7 +775,6 @@
         Tools._MessageLogLevel = 1;
         Tools._WarningLogLevel = 2;
         Tools._ErrorLogLevel = 4;
-        Tools._LogCache = "";
 
         Tools.Log = Tools._LogEnabled;
 

+ 3 - 0
Exporters/3ds Max/BabylonExport.Entities/BabylonLight.cs

@@ -62,6 +62,9 @@ namespace BabylonExport.Entities
         [DataMember]
         public BabylonAnimation[] animations { get; set; }
 
+        [DataMember]
+        public string parentId { get; set; }
+
         public BabylonLight()
         {
             diffuse = new[] {1.0f, 1.0f, 1.0f};

BIN
Exporters/3ds Max/Max2Babylon-0.11.0.zip


BIN
Exporters/3ds Max/Max2Babylon-0.12.0.zip


+ 9 - 11
Exporters/3ds Max/Max2Babylon/BabylonPropertiesActionItem.cs

@@ -27,14 +27,7 @@ namespace Max2Babylon
                 }
             }
 
-            if (firstNode.ObjectRef != null && firstNode.ObjectRef.Eval(0).Obj.SuperClassID == SClass_ID.Geomobject)
-            {
-                using (var frm = new ObjectPropertiesForm())
-                {
-                    frm.ShowDialog();
-                    return true;
-                }
-            }
+           
 
             if (firstNode.ObjectRef != null && firstNode.ObjectRef.Eval(0).Obj.SuperClassID == SClass_ID.Light)
             {
@@ -44,10 +37,15 @@ namespace Max2Babylon
                     return true;
                 }
             }
+           
+            // consider non-recognized objects as meshes so they can be animated intermediate nodes
+            using (var frm = new ObjectPropertiesForm())
+            {
+                frm.ShowDialog();
+                return true;
+            }
+            
 
-            Loader.Core.PushPrompt("Selected entity does not have Babylon.js specific properties");
-
-            return true;
         }
 
         public override int Id_

+ 35 - 2
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Camera.cs

@@ -1,12 +1,13 @@
 using System.Collections.Generic;
 using Autodesk.Max;
 using BabylonExport.Entities;
+using System.Linq;
 
 namespace Max2Babylon
 {
     partial class BabylonExporter
     {
-        private void ExportCamera(IIGameNode cameraNode, BabylonScene babylonScene)
+        private void ExportCamera(IIGameScene scene,  IIGameNode cameraNode, BabylonScene babylonScene)
         {
             if (cameraNode.MaxNode.GetBoolProperty("babylonjs_noexport"))
             {
@@ -22,7 +23,24 @@ namespace Max2Babylon
             babylonCamera.id = cameraNode.MaxNode.GetGuid().ToString();
             if (cameraNode.NodeParent != null)
             {
-                babylonCamera.parentId = cameraNode.NodeParent.MaxNode.GetGuid().ToString();
+                var parentType = cameraNode.NodeParent.IGameObject.IGameType;
+                var parentId = cameraNode.NodeParent.MaxNode.GetGuid().ToString();
+                switch (parentType)
+                {
+                    case Autodesk.Max.IGameObject.ObjectTypes.Light:
+                    case Autodesk.Max.IGameObject.ObjectTypes.Mesh:
+                    case Autodesk.Max.IGameObject.ObjectTypes.Camera:
+                        break;
+
+
+                    default:
+                        if (!babylonScene.MeshesList.Where(m => m.id == parentId).Any())
+                        {
+                            ExportMesh(scene, cameraNode.NodeParent, babylonScene);
+                        }
+                        break;
+                }
+                babylonCamera.parentId = parentId;
             }
 
             babylonCamera.fov = Tools.ConvertFov(maxCamera.GetFOV(0, Tools.Forever));
@@ -57,6 +75,11 @@ namespace Max2Babylon
 
             // Position
             var wm = cameraNode.GetLocalTM(0);
+            if (cameraNode.NodeParent != null)
+            {
+                var parentWorld = cameraNode.NodeParent.GetObjectTM(0);
+                wm.MultiplyBy(parentWorld.Inverse);
+            }
             var position = wm.Translation;
             babylonCamera.position = new float[] { position.X, position.Y, position.Z };
 
@@ -78,6 +101,11 @@ namespace Max2Babylon
             ExportVector3Animation("position", animations, key =>
             {
                 var tm = cameraNode.GetLocalTM(key);
+                if (cameraNode.NodeParent != null)
+                {
+                    var parentWorld = cameraNode.NodeParent.GetObjectTM(key);
+                    tm.MultiplyBy(parentWorld.Inverse);
+                }
                 var translation = tm.Translation;
                 return new float[] { translation.X, translation.Y, translation.Z };
             });
@@ -87,6 +115,11 @@ namespace Max2Babylon
                 ExportVector3Animation("target", animations, key =>
                 {
                     var tm = cameraNode.GetLocalTM(key);
+                    if (cameraNode.NodeParent != null)
+                    {
+                        var parentWorld = cameraNode.NodeParent.GetObjectTM(key);
+                        tm.MultiplyBy(parentWorld.Inverse);
+                    }
                     var translation = tm.Translation;
                     var dir = tm.GetRow(3);
                     return new float[] { translation.X - dir.X, translation.Y - dir.Y, translation.Z - dir.Z };

+ 37 - 1
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Light.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using Autodesk.Max;
 using BabylonExport.Entities;
+using System.Linq;
 
 namespace Max2Babylon
 {
@@ -24,7 +25,7 @@ namespace Max2Babylon
             babylonScene.LightsList.Add(babylonLight);
         }
 
-        private void ExportLight(IIGameNode lightNode, BabylonScene babylonScene)
+        private void ExportLight(IIGameScene scene, IIGameNode lightNode, BabylonScene babylonScene)
         {
             if (lightNode.MaxNode.GetBoolProperty("babylonjs_noexport"))
             {
@@ -38,8 +39,28 @@ namespace Max2Babylon
             RaiseMessage(lightNode.Name, 1);
             babylonLight.name = lightNode.Name;
             babylonLight.id = lightNode.MaxNode.GetGuid().ToString();
+            if (lightNode.NodeParent != null)
+            {
+                var parentType = lightNode.NodeParent.IGameObject.IGameType;
+                var parentId = lightNode.NodeParent.MaxNode.GetGuid().ToString();
+                switch (parentType)
+                {
+                    case Autodesk.Max.IGameObject.ObjectTypes.Light:
+                    case Autodesk.Max.IGameObject.ObjectTypes.Mesh:
+                    case Autodesk.Max.IGameObject.ObjectTypes.Camera:
+                        break;
 
 
+                    default:
+                        if (!babylonScene.MeshesList.Where(m => m.id == parentId).Any())
+                        {
+                            ExportMesh(scene, lightNode.NodeParent, babylonScene);
+                        }
+                        break;
+                }
+                babylonLight.parentId = parentId;
+            }
+
             // Type
 
             var maxLight = (lightNode.MaxNode.ObjectRef as ILightObject);
@@ -81,6 +102,11 @@ namespace Max2Babylon
 
             // Position
             var wm = lightNode.GetObjectTM(0);
+            if (lightNode.NodeParent != null)
+            {
+                var parentWorld = lightNode.NodeParent.GetObjectTM(0);
+                wm.MultiplyBy(parentWorld.Inverse);
+            }
             var position = wm.Translation;
             babylonLight.position = new float[] { position.X, position.Y, position.Z };
 
@@ -156,6 +182,11 @@ namespace Max2Babylon
             ExportVector3Animation("position", animations, key =>
             {
                 var mat = lightNode.GetObjectTM(key);
+                if (lightNode.NodeParent != null)
+                {
+                    var parentWorld = lightNode.NodeParent.GetObjectTM(key);
+                    mat.MultiplyBy(parentWorld.Inverse);
+                }
                 var pos = mat.Translation;
                 return new float[] { pos.X, pos.Y, pos.Z };
             });
@@ -163,6 +194,11 @@ namespace Max2Babylon
             ExportVector3Animation("direction", animations, key =>
             {
                 var wmLight = lightNode.GetObjectTM(key);
+                if (lightNode.NodeParent != null)
+                {
+                    var parentWorld = lightNode.NodeParent.GetObjectTM(key);
+                    wmLight.MultiplyBy(parentWorld.Inverse);
+                }
                 var positionLight = wmLight.Translation;
                 var lightTarget = gameLight.LightTarget;
                 if (lightTarget != null)

+ 134 - 34
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs

@@ -4,11 +4,64 @@ using System.Linq;
 using Autodesk.Max;
 using BabylonExport.Entities;
 using System.Runtime.InteropServices;
+using System.Threading.Tasks;
 
 namespace Max2Babylon
 {
     partial class BabylonExporter
     {
+        Dictionary<IIGameSkin, List<int>> skinSortedBones = new Dictionary<IIGameSkin, List<int>>();
+        List<int> SortBones(IIGameSkin skin)
+        {
+            List<int> boneIds = new List<int>();
+            Dictionary<int, IIGameNode> boneIndex = new Dictionary<int, IIGameNode>();
+            for (var index = 0; index < skin.TotalSkinBoneCount; index++)
+            {
+                var bone = skin.GetIGameBone(index, false);
+                if (bone == null)
+                {
+                    // non bone in skeletton
+                    boneIds.Add(-2);
+
+                }
+                else
+                {
+                    boneIds.Add(bone.NodeID);
+                    boneIndex[bone.NodeID] = bone;
+                }
+            }
+            while (true)
+            {
+                bool foundMisMatch = false;
+                for (int i = 0; i < boneIds.Count; ++i)
+                {
+                    var id = boneIds[i];
+                    if (id == -2)
+                    {
+                        continue;
+                    }
+                    var parent = boneIndex[id].NodeParent;
+                    if (parent != null)
+                    {
+                        var parentId = parent.NodeID;
+                        if (boneIds.IndexOf(parentId) > i)
+                        {
+                            boneIds.RemoveAt(i);
+                            boneIds.Insert(boneIds.IndexOf(parentId) + 1, id);
+                            foundMisMatch = true;
+                            break;
+                        }
+                    }
+                }
+                if (!foundMisMatch)
+                {
+                    break;
+                }
+            }
+            return boneIds;
+
+        }
+
         private int bonesCount;
         private void ExportMesh(IIGameScene scene, IIGameNode meshNode, BabylonScene babylonScene)
         {
@@ -37,7 +90,26 @@ namespace Max2Babylon
             babylonMesh.id = meshNode.MaxNode.GetGuid().ToString();
             if (meshNode.NodeParent != null)
             {
-                babylonMesh.parentId = meshNode.NodeParent.MaxNode.GetGuid().ToString();
+
+                // parent node type (if a known object type, export it as an empty mesh, so it can be in the scene hierarchy)
+                var parentType = meshNode.NodeParent.IGameObject.IGameType;
+                var parentId = meshNode.NodeParent.MaxNode.GetGuid().ToString();
+                switch (parentType)
+                {
+                    case Autodesk.Max.IGameObject.ObjectTypes.Light:
+                    case Autodesk.Max.IGameObject.ObjectTypes.Mesh:
+                    case Autodesk.Max.IGameObject.ObjectTypes.Camera:
+                        break;
+
+
+                    default:
+                        if (!babylonScene.MeshesList.Where(m => m.id == parentId).Any())
+                        {
+                            ExportMesh(scene, meshNode.NodeParent, babylonScene);
+                        }
+                        break;
+                }
+                babylonMesh.parentId = parentId;
             }
 
             // Misc.
@@ -56,18 +128,27 @@ namespace Max2Babylon
             var skin = gameMesh.IGameSkin;
             var unskinnedMesh = gameMesh;
             IGMatrix skinInitPoseMatrix = Loader.Global.GMatrix.Create(Loader.Global.Matrix3.Create(true));
+            List<int> boneIds = null;
             if (isSkinned)
             {
                 bonesCount = skin.TotalSkinBoneCount;
                 skins.Add(skin);
+
                 skinnedNodes.Add(meshNode);
                 babylonMesh.skeletonId = skins.IndexOf(skin);
                 skin.GetInitSkinTM(skinInitPoseMatrix);
+                boneIds = SortBones(skin);
+                skinSortedBones[skin] = boneIds;
             }
 
             // Position / rotation / scaling
             {
                 var localTM = meshNode.GetObjectTM(0);
+                if (meshNode.NodeParent != null)
+                {
+                    var parentWorld = meshNode.NodeParent.GetObjectTM(0);
+                    localTM.MultiplyBy(parentWorld.Inverse);
+                }
 
                 var meshTrans = localTM.Translation;
                 var meshRotation = localTM.Rotation;
@@ -125,13 +206,13 @@ namespace Max2Babylon
                     IntPtr indexer = new IntPtr(i);
                     var channelNum = mappingChannels[indexer];
                     if (channelNum == 1)
-                    {
+                {
                         hasUV = true;
-                    }
+                }
                     else if (channelNum == 2)
-                    {
+                {
                         hasUV2 = true;
-                    }
+                }
                 }
                 var hasColor = unskinnedMesh.NumberOfColorVerts > 0;
                 var hasAlpha = unskinnedMesh.GetNumberOfMapVerts(-2) > 0;
@@ -151,7 +232,7 @@ namespace Max2Babylon
                 var subMeshes = new List<BabylonSubMesh>();
                 var indexStart = 0;
 
-
+                
                 for (int i = 0; i < multiMatsCount; ++i)
                 {
                     if (meshNode.NodeMaterial == null)
@@ -173,7 +254,7 @@ namespace Max2Babylon
                         for (int j = 0; j < unskinnedMesh.NumberOfFaces; ++j)
                         {
                             var face = unskinnedMesh.GetFace(j);
-                            ExtractFace(skin, unskinnedMesh, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face);
+                            ExtractFace(skin, unskinnedMesh, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds);
                         }
                     }
                     else
@@ -185,10 +266,10 @@ namespace Max2Babylon
                             var face = materialFaces[faceIndexer];
 
                             Marshal.FreeHGlobal(faceIndexer);
-                            ExtractFace(skin, unskinnedMesh, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face);
+                            ExtractFace(skin, unskinnedMesh, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds);
                         }
                     }
-
+                    
                     if (indexCount != 0)
                     {
 
@@ -298,7 +379,7 @@ namespace Max2Babylon
             // Animations
             var animations = new List<BabylonAnimation>();
             GenerateCoordinatesAnimations(meshNode, animations);
-
+            
 
             if (!ExportFloatController(meshNode.MaxNode.VisController, "visibility", animations))
             {
@@ -318,11 +399,11 @@ namespace Max2Babylon
             babylonScene.MeshesList.Add(babylonMesh);
         }
 
-        private void ExtractFace(IIGameSkin skin, IIGameMesh unskinnedMesh, List<GlobalVertex> vertices, List<int> indices, bool hasUV, bool hasUV2, bool hasColor, bool hasAlpha, List<GlobalVertex>[] verticesAlreadyExported, ref int indexCount, ref int minVertexIndex, ref int maxVertexIndex, IFaceEx face)
+        private void ExtractFace(IIGameSkin skin, IIGameMesh unskinnedMesh, List<GlobalVertex> vertices, List<int> indices, bool hasUV, bool hasUV2, bool hasColor, bool hasAlpha, List<GlobalVertex>[] verticesAlreadyExported, ref int indexCount, ref int minVertexIndex, ref int maxVertexIndex, IFaceEx face, List<int> boneIds)
         {
-            var a = CreateGlobalVertex(unskinnedMesh, face, 0, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin);
-            var b = CreateGlobalVertex(unskinnedMesh, face, 2, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin);
-            var c = CreateGlobalVertex(unskinnedMesh, face, 1, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin);
+            var a = CreateGlobalVertex(unskinnedMesh, face, 0, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
+            var b = CreateGlobalVertex(unskinnedMesh, face, 2, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
+            var c = CreateGlobalVertex(unskinnedMesh, face, 1, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
             indices.Add(a);
             indices.Add(b);
             indices.Add(c);
@@ -363,34 +444,53 @@ namespace Max2Babylon
         }
 
         public static void GenerateCoordinatesAnimations(IIGameNode meshNode, List<BabylonAnimation> animations)
-        {
-            ExportVector3Animation("position", animations, key =>
             {
+
+                ExportVector3Animation("position", animations, key =>
+                {
                 var worldMatrix = meshNode.GetObjectTM(key);
+                if (meshNode.NodeParent != null)
+                {
+                    var parentWorld = meshNode.NodeParent.GetObjectTM(key);
+                    worldMatrix.MultiplyBy(parentWorld.Inverse);
+                }
                 var trans = worldMatrix.Translation;
                 return new float[] { trans.X, trans.Y, trans.Z };
-            });
+                });
 
-            ExportQuaternionAnimation("rotationQuaternion", animations, key =>
-            {
-                var worldMatrix = meshNode.GetObjectTM(key);
+
+                ExportQuaternionAnimation("rotationQuaternion", animations, key =>
+                {
+                    var worldMatrix = meshNode.GetObjectTM(key);
+                if (meshNode.NodeParent != null)
+                {
+                    var parentWorld = meshNode.NodeParent.GetObjectTM(key);
+                    worldMatrix.MultiplyBy(parentWorld.Inverse);
+                }
 
 
+                    var rot = worldMatrix.Rotation;
+                    return new float[] { rot.X, rot.Y, rot.Z, -rot.W };
+                });
 
-                var rot = worldMatrix.Rotation;
-                return new float[] { rot.X, rot.Y, rot.Z, -rot.W };
-            });
 
-            ExportVector3Animation("scaling", animations, key =>
-            {
-                var worldMatrix = meshNode.GetObjectTM(key);
-                var scale = worldMatrix.Scaling;
+                ExportVector3Animation("scaling", animations, key =>
+                {
+                    var worldMatrix = meshNode.GetObjectTM(key);
+                if (meshNode.NodeParent != null)
+                {
+                    var parentWorld = meshNode.NodeParent.GetObjectTM(key);
+                    worldMatrix.MultiplyBy(parentWorld.Inverse);
+                }
+                    var scale = worldMatrix.Scaling;
+
+                    return new float[] { scale.X, scale.Y, scale.Z };
+                });
 
-                return new float[] { scale.X, scale.Y, scale.Z };
-            });
         }
 
-        int CreateGlobalVertex(IIGameMesh mesh, IFaceEx face, int facePart, List<GlobalVertex> vertices, bool hasUV, bool hasUV2, bool hasColor, bool hasAlpha, List<GlobalVertex>[] verticesAlreadyExported, IIGameSkin skin)
+
+        int CreateGlobalVertex(IIGameMesh mesh, IFaceEx face, int facePart, List<GlobalVertex> vertices, bool hasUV, bool hasUV2, bool hasColor, bool hasAlpha, List<GlobalVertex>[] verticesAlreadyExported, IIGameSkin skin, List<int> boneIds)
         {
             var vertexIndex = (int)face.Vert[facePart];
 
@@ -457,25 +557,25 @@ namespace Max2Babylon
 
                 if (nbBones > 0)
                 {
-                    bone0 = skin.GetBoneIndex(skin.GetBone(vertexIndex, 0), false);
+                    bone0 = boneIds.IndexOf(skin.GetIGameBone(vertexIndex, 0).NodeID);
                     weight0 = skin.GetWeight(vertexIndex, 0);
                 }
 
                 if (nbBones > 1)
                 {
-                    bone1 = skin.GetBoneIndex(skin.GetBone(vertexIndex, 1), false);
+                    bone1 = boneIds.IndexOf(skin.GetIGameBone(vertexIndex, 1).NodeID);
                     weight1 = skin.GetWeight(vertexIndex, 1);
                 }
 
                 if (nbBones > 2)
                 {
-                    bone2 = skin.GetBoneIndex(skin.GetBone(vertexIndex, 2), false);
+                    bone2 = boneIds.IndexOf(skin.GetIGameBone(vertexIndex, 2).NodeID);
                     weight2 = skin.GetWeight(vertexIndex, 2);
                 }
 
                 if (nbBones > 3)
                 {
-                    bone3 = skin.GetBoneIndex(skin.GetBone(vertexIndex, 3), false);
+                    bone3 = boneIds.IndexOf(skin.GetIGameBone(vertexIndex, 3).NodeID);
                 }
 
                 if (nbBones == 0)

+ 2 - 2
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.cs

@@ -140,7 +140,7 @@ namespace Max2Babylon
                 var indexer = new IntPtr(ix);
                 var cameraNode = camerasTab[indexer];
                 Marshal.FreeHGlobal(indexer);
-                ExportCamera(cameraNode, babylonScene);
+                ExportCamera(gameScene, cameraNode, babylonScene);
 
                 if (mainCamera == null && babylonScene.CamerasList.Count > 0)
                 {
@@ -228,7 +228,7 @@ namespace Max2Babylon
             var lightNodes = gameScene.GetIGameNodeByType(Autodesk.Max.IGameObject.ObjectTypes.Light);
             for (var i = 0; i < lightNodes.Count; ++i)
             {
-                ExportLight(lightNodes[new IntPtr(i)], babylonScene);
+                ExportLight(gameScene, lightNodes[new IntPtr(i)], babylonScene);
                 CheckCancelled();
             }
 

+ 6 - 4
Exporters/3ds Max/Max2Babylon/Forms/ObjectPropertiesForm.cs

@@ -37,10 +37,12 @@ namespace Max2Babylon
             {
                 var node = Loader.Core.GetSelNode(index);
 
-                if (node.ObjectRef != null && node.ObjectRef.Eval(0).Obj.SuperClassID == SClass_ID.Geomobject)
-                {
-                    objects.Add(node);
-                }
+                //if (node.ObjectRef != null && node.ObjectRef.Eval(0).Obj.SuperClassID == SClass_ID.Geomobject)
+                //{
+
+                // handle "virtual objects" // todo : differentiate them and remove mesh specific settings (keep only animation settings)
+                objects.Add(node);
+                //}
             }
 
             Tools.PrepareCheckBox(chkNoExport, objects, "babylonjs_noexport");