Преглед на файлове

Merge pull request #340 from simonferquel/master

Fixed node hierarchy where certain nodes are not game object (but purely abstract nodes)
David Catuhe преди 10 години
родител
ревизия
9cc26bfa6b
променени са 46 файла, в които са добавени 638 реда и са изтрити 1028 реда
  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");