Prechádzať zdrojové kódy

Merge remote-tracking branch 'remotes/BabylonJS/master' into ourOwnBabylonJS

Gwenaël Hagenmuller 11 rokov pred
rodič
commit
161cb6348c

+ 4 - 2
Babylon/Cameras/babylon.arcRotateCamera.js

@@ -259,7 +259,8 @@ var BABYLON = BABYLON || {};
         canvas.addEventListener("MSGestureChange", this._onGesture, false);
         window.addEventListener("keydown", this._onKeyDown, false);
         window.addEventListener("keyup", this._onKeyUp, false);
-        window.addEventListener('mousewheel', this._wheel, false);
+        window.addEventListener('mousewheel', this._wheel, false); //Chrome, Safari, Opera, IE
+        window.addEventListener('DOMMouseScroll', this._wheel, false); //Firefox
         window.addEventListener("blur", this._onLostFocus, false);
     };
 
@@ -277,7 +278,8 @@ var BABYLON = BABYLON || {};
         canvas.removeEventListener("MSGestureChange", this._onGesture);
         window.removeEventListener("keydown", this._onKeyDown);
         window.removeEventListener("keyup", this._onKeyUp);
-        window.removeEventListener('mousewheel', this._wheel);
+        window.removeEventListener('mousewheel', this._wheel); //Chrome, Safari, Opera, IE
+        window.removeEventListener('DOMMouseScroll', this._wheel); //Firefox
         window.removeEventListener("blur", this._onLostFocus);
 
         this._MSGestureHandler = null;

+ 3 - 2
Babylon/Cameras/babylon.camera.js

@@ -271,7 +271,7 @@ var BABYLON = BABYLON || {};
 
         if (!this.parent
             || !this.parent.getWorldMatrix
-            || (!this.hasNewParent() && this.parent.isSynchronized())) {
+            || this.isSynchronized()) {
             return this._computedViewMatrix;
         }
 
@@ -290,9 +290,10 @@ var BABYLON = BABYLON || {};
     
     BABYLON.Camera.prototype._computeViewMatrix = function (force) {
         if (!force && this._isSynchronizedViewMatrix()) {
+            this._currentRenderId = this._scene.getRenderId();
             return this._computedViewMatrix;
         }
-        this._syncChildFlag();
+
         this._computedViewMatrix = this._getViewMatrix();
         return this._computedViewMatrix;
     };

+ 23 - 0
Babylon/Collisions/babylon.pickingInfo.js

@@ -11,4 +11,27 @@ var BABYLON = BABYLON || {};
     BABYLON.PickingInfo.prototype.distance = 0;
     BABYLON.PickingInfo.prototype.pickedPoint = null;
     BABYLON.PickingInfo.prototype.pickedMesh = null;
+    BABYLON.PickingInfo.prototype.bu = 0;
+    BABYLON.PickingInfo.prototype.bv = 0;
+    BABYLON.PickingInfo.prototype.faceId = -1;
+
+    // Methods
+    BABYLON.PickingInfo.prototype.getNormal = function() {
+        if (!this.pickedMesh) {
+            return null;
+        }
+
+        var indices = this.pickedMesh.getIndices();
+        var normals = this.pickedMesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
+
+        var normal0 = BABYLON.Vector3.FromArray(normals , indices[this.faceId]);
+        var normal1 = BABYLON.Vector3.FromArray(normals, indices[this.faceId + 1]);
+        var normal2 = BABYLON.Vector3.FromArray(normals, indices[this.faceId + 2]);
+
+        normal0 = normal0.scale(this.bu);
+        normal1 = normal1.scale(this.bv);
+        normal2 = normal2.scale(1.0 - this.bu - this.bv);
+
+        return new BABYLON.Vector3(normal0.x + normal1.x + normal2.x, normal0.y + normal1.y + normal2.y, normal0.z + normal1.z + normal2.z);
+    };
 })();

+ 1 - 1
Babylon/Lights/babylon.light.js

@@ -37,7 +37,7 @@ var BABYLON = BABYLON || {};
     };
 
     BABYLON.Light.prototype.getWorldMatrix = function () {
-        this._syncChildFlag();
+        this._currentRenderId = this._scene.getRenderId();
 
         var worldMatrix = this._getWorldMatrix();
 

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 729 - 740
Babylon/Tools/babylon.sceneLoader.js


+ 90 - 0
Babylon/Loading/babylon.sceneLoader.js

@@ -0,0 +1,90 @@
+"use strict";
+
+var BABYLON = BABYLON || {};
+
+(function () {
+    BABYLON.SceneLoader = {
+        _registeredPlugins: [],
+
+        _getPluginForFilename: function (sceneFilename) {
+            var dotPosition = sceneFilename.lastIndexOf(".");
+            var extension = sceneFilename.substring(dotPosition).toLowerCase();
+
+            for (var index = 0; index < this._registeredPlugins.length; index++) {
+                var plugin = this._registeredPlugins[index];
+
+                if (plugin.extensions.indexOf(extension) !== -1) {
+                    return plugin;
+                }
+            }
+
+            throw new Error("No plugin found to load this file: " + sceneFilename);
+        },
+
+        // Public functions
+        RegisterPlugin: function (plugin) {
+            plugin.extensions = plugin.extensions.toLowerCase();
+            this._registeredPlugins.push(plugin);
+        },
+
+        ImportMesh: function (meshesNames, rootUrl, sceneFilename, scene, onsuccess, progressCallBack, onerror) {
+            // Checking if a manifest file has been set for this scene and if offline mode has been requested
+            var database = new BABYLON.Database(rootUrl + sceneFilename);
+            scene.database = database;
+
+            var plugin = this._getPluginForFilename(sceneFilename);
+
+            BABYLON.Tools.LoadFile(rootUrl + sceneFilename, function (data) {
+                var meshes = [];
+                var particleSystems = [];
+                var skeletons = [];
+
+                if (!plugin.importMesh(meshesNames, scene, data, rootUrl, meshes, particleSystems, skeletons)) {
+                    if (onerror) {
+                        onerror(scene);
+                    }
+
+                    return;
+                }
+
+                if (onsuccess) {
+                    onsuccess(meshes, particleSystems, skeletons);
+                }
+            }, progressCallBack, database);
+        },
+
+        Load: function (rootUrl, sceneFilename, engine, onsuccess, progressCallBack, onerror) {
+
+            var plugin = this._getPluginForFilename(sceneFilename);
+            var database;
+
+            var loadSceneFromData = function (data) {
+                var scene = new BABYLON.Scene(engine);
+                scene.database = database;
+
+                if (!plugin.load(scene, data, rootUrl)) {
+                    if (onerror) {
+                        onerror(scene);
+                    }
+
+                    return;
+                }
+
+                if (onsuccess) {
+                    onsuccess(scene);
+                }
+            };
+
+            if (rootUrl.indexOf("file:") === -1) {
+                // Checking if a manifest file has been set for this scene and if offline mode has been requested
+                database = new BABYLON.Database(rootUrl + sceneFilename);
+
+                BABYLON.Tools.LoadFile(rootUrl + sceneFilename, loadSceneFromData, progressCallBack, database);
+            }
+                // Loading file from disk via input file or drag'n'drop
+            else {
+                BABYLON.Tools.ReadFile(sceneFilename, loadSceneFromData, progressCallBack);
+            }
+        }
+    };
+})();

+ 3 - 3
Babylon/Materials/babylon.standardMaterial.js

@@ -229,10 +229,10 @@ var BABYLON = BABYLON || {};
         if (this._cachedDefines != join) {
             this._cachedDefines = join;
 
-            // IE patch
+            // Legacy browser patch
             var shaderName = "default";
-            if (BABYLON.Tools.isIE()) {
-                shaderName = "iedefault";
+            if (!this._scene.getEngine().getCaps().standardDerivatives) {
+                shaderName = "legacydefault";
             }
 
             this._effect = this._scene.getEngine().createEffect(shaderName,

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

@@ -8,6 +8,7 @@ var BABYLON = BABYLON || {};
         this._scene.textures.push(this);
 
         this.name = name;
+        this._size = size;
         this._generateMipMaps = generateMipMaps;
 
         this._texture = scene.getEngine().createRenderTargetTexture(size, generateMipMaps);

+ 16 - 0
Babylon/Math/babylon.axis.js

@@ -0,0 +1,16 @@
+"use strict";
+
+var BABYLON = BABYLON || {};
+
+(function () {
+    BABYLON.Space = {
+        LOCAL: 0,
+        WORLD: 1
+    };
+
+    BABYLON.Axis =  {
+        X: new BABYLON.Vector3(1, 0, 0),
+        Y: new BABYLON.Vector3(0, 1, 0),
+        Z: new BABYLON.Vector3(0, 0, 1)
+    };
+})();

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1962 - 1933
Babylon/Tools/babylon.math.js


+ 70 - 73
Babylon/Mesh/babylon.mesh.js

@@ -96,6 +96,40 @@ var BABYLON = BABYLON || {};
         return this._worldMatrix;
     };
 
+    BABYLON.Mesh.prototype.rotate = function (axis, amount, space) {
+        if (!this.rotationQuaternion) {
+            this.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);
+            this.rotation = BABYLON.Vector3.Zero();
+        }
+
+        if (!space || space == BABYLON.Space.LOCAL) {
+            var rotationQuaternion = BABYLON.Quaternion.RotationAxis(axis, amount);
+            this.rotationQuaternion = this.rotationQuaternion.multiply(rotationQuaternion);
+        }
+        else {
+            if (this.parent) {
+                var invertParentWorldMatrix = this.parent.getWorldMatrix().clone();
+                invertParentWorldMatrix.invert();
+
+                axis = BABYLON.Vector3.TransformNormal(axis, invertParentWorldMatrix);
+            }
+            var rotationQuaternion = BABYLON.Quaternion.RotationAxis(axis, amount);
+            this.rotationQuaternion = rotationQuaternion.multiply(this.rotationQuaternion);
+        }
+    };
+
+    BABYLON.Mesh.prototype.translate = function (axis, distance, space) {
+        var displacementVector = axis.scale(distance);
+
+        if (!space || space == BABYLON.Space.LOCAL) {
+            var tempV3 = this.getPositionExpressedInLocalSpace().add(displacementVector);
+            this.setPositionWithLocalVector(tempV3);
+        }
+        else {
+            this.setAbsolutePosition(this.getAbsolutePosition().add(displacementVector));
+        }
+    };
+
     BABYLON.Mesh.prototype.getAbsolutePosition = function () {
         this.computeWorldMatrix();
         return this._absolutePosition;
@@ -124,43 +158,18 @@ var BABYLON = BABYLON || {};
             absolutePositionZ = absolutePosition.z;
         }
 
-        // worldMatrix = pivotMatrix * scalingMatrix * rotationMatrix * translateMatrix * parentWorldMatrix
-        // => translateMatrix = invertRotationMatrix * invertScalingMatrix * invertPivotMatrix * worldMatrix * invertParentWorldMatrix
-
-        // get this matrice before the other ones since
-        // that will update them if they have to be updated
-
-        var worldMatrix = this.getWorldMatrix().clone();
-
-        worldMatrix.m[12] = absolutePositionX;
-        worldMatrix.m[13] = absolutePositionY;
-        worldMatrix.m[14] = absolutePositionZ;
-
-        var invertRotationMatrix = this._localRotation.clone();
-        invertRotationMatrix.invert();
-
-        var invertScalingMatrix = this._localScaling.clone();
-        invertScalingMatrix.invert();
-
-        var invertPivotMatrix = this._pivotMatrix.clone();
-        invertPivotMatrix.invert();
-
-        var translateMatrix = invertRotationMatrix.multiply(invertScalingMatrix);
-
-        translateMatrix.multiplyToRef(invertPivotMatrix, invertScalingMatrix); // reuse matrix
-        invertScalingMatrix.multiplyToRef(worldMatrix, translateMatrix);
-
         if (this.parent) {
             var invertParentWorldMatrix = this.parent.getWorldMatrix().clone();
             invertParentWorldMatrix.invert();
 
-            translateMatrix.multiplyToRef(invertParentWorldMatrix, invertScalingMatrix); // reuse matrix
-            translateMatrix = invertScalingMatrix;
-        }
+            var worldPosition = new BABYLON.Vector3(absolutePositionX, absolutePositionY, absolutePositionZ);
 
-        this.position.x = translateMatrix.m[12];
-        this.position.y = translateMatrix.m[13];
-        this.position.z = translateMatrix.m[14];
+            this.position = BABYLON.Vector3.TransformCoordinates(worldPosition, invertParentWorldMatrix);
+        } else {
+            this.position.x = absolutePositionX;
+            this.position.y = absolutePositionY;
+            this.position.z = absolutePositionZ;
+        }
     };
 
     BABYLON.Mesh.prototype.getTotalVertices = function () {
@@ -176,10 +185,12 @@ var BABYLON = BABYLON || {};
     };
 
     BABYLON.Mesh.prototype.isVerticesDataPresent = function (kind) {
-        if (!this._vertexBuffers && this._delayInfo) {
-            return this._delayInfo.indexOf(kind) !== -1;
+        if (!this._vertexBuffers) {
+            if (this._delayInfo) {
+                return this._delayInfo.indexOf(kind) !== -1;
+            }
+            return false;
         }
-
         return this._vertexBuffers[kind] !== undefined;
     };
 
@@ -273,7 +284,7 @@ var BABYLON = BABYLON || {};
         if (property === "rotation") {
             this.rotationQuaternion = null;
         }
-        this._syncChildFlag();
+        this._currentRenderId = -1;
     };
 
     BABYLON.Mesh.prototype.refreshBoundingInfo = function () {
@@ -314,10 +325,10 @@ var BABYLON = BABYLON || {};
 
     BABYLON.Mesh.prototype.computeWorldMatrix = function (force) {
         if (!force && (this._currentRenderId == this._scene.getRenderId() || this.isSynchronized(true))) {
+            this._currentRenderId = this._scene.getRenderId();
             return this._worldMatrix;
         }
 
-        this._syncChildFlag();
         this._cache.position.copyFrom(this.position);
         this._cache.scaling.copyFrom(this.scaling);
         this._cache.pivotMatrixUpdated = false;
@@ -336,9 +347,13 @@ var BABYLON = BABYLON || {};
         }
 
         // Translation
-        if (this.infiniteDistance) {
+        if (this.infiniteDistance && !this.parent) {
             var camera = this._scene.activeCamera;
-            BABYLON.Matrix.TranslationToRef(this.position.x + camera.position.x, this.position.y + camera.position.y, this.position.z + camera.position.z, this._localTranslation);
+            var cameraWorldMatrix = camera.getWorldMatrix();
+
+            var cameraGlobalPosition = new BABYLON.Vector3(cameraWorldMatrix.m[12], cameraWorldMatrix.m[13], cameraWorldMatrix.m[14]);
+
+            BABYLON.Matrix.TranslationToRef(this.position.x + cameraGlobalPosition.x, this.position.y + cameraGlobalPosition.y, this.position.z + cameraGlobalPosition.z, this._localTranslation);
         } else {
             BABYLON.Matrix.TranslationToRef(this.position.x, this.position.y, this.position.z, this._localTranslation);
         }
@@ -384,7 +399,7 @@ var BABYLON = BABYLON || {};
         if (this.parent && this.parent.getWorldMatrix && this.billboardMode === BABYLON.Mesh.BILLBOARDMODE_NONE) {
             this._localWorld.multiplyToRef(this.parent.getWorldMatrix(), this._worldMatrix);
         } else {
-            this._localPivotScalingRotation.multiplyToRef(this._localTranslation, this._worldMatrix);
+            this._worldMatrix.copyFrom(this._localWorld);
         }
 
         // Bounding info
@@ -576,7 +591,7 @@ var BABYLON = BABYLON || {};
             this._scene._addPendingData(this);
 
             BABYLON.Tools.LoadFile(this.delayLoadingFile, function (data) {
-                BABYLON.SceneLoader._ImportGeometry(JSON.parse(data), that);
+                that._delayLoadingFunction(JSON.parse(data), that);
                 that.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_LOADED;
                 that._scene._removePendingData(that);
             }, function () { }, this._scene.database);
@@ -615,27 +630,6 @@ var BABYLON = BABYLON || {};
     };
 
     // Geometry
-    // Deprecated: use setPositionWithLocalVector instead 
-    BABYLON.Mesh.prototype.setLocalTranslation = function (vector3) {
-        console.warn("deprecated: use setPositionWithLocalVector instead");
-        this.computeWorldMatrix();
-        var worldMatrix = this._worldMatrix.clone();
-        worldMatrix.setTranslation(BABYLON.Vector3.Zero());
-
-        this.position = BABYLON.Vector3.TransformCoordinates(vector3, worldMatrix);
-    };
-
-    // Deprecated: use getPositionExpressedInLocalSpace instead 
-    BABYLON.Mesh.prototype.getLocalTranslation = function () {
-        console.warn("deprecated: use getPositionExpressedInLocalSpace instead");
-        this.computeWorldMatrix();
-        var invWorldMatrix = this._worldMatrix.clone();
-        invWorldMatrix.setTranslation(BABYLON.Vector3.Zero());
-        invWorldMatrix.invert();
-
-        return BABYLON.Vector3.TransformCoordinates(this.position, invWorldMatrix);
-    };
-
     BABYLON.Mesh.prototype.setPositionWithLocalVector = function (vector3) {
         this.computeWorldMatrix();
 
@@ -788,7 +782,7 @@ var BABYLON = BABYLON || {};
 
         this._generatePointsArray();
 
-        var distance = Number.MAX_VALUE;
+        var intersectInfo = null;
 
         for (var index = 0; index < this.subMeshes.length; index++) {
             var subMesh = this.subMeshes[index];
@@ -797,11 +791,11 @@ var BABYLON = BABYLON || {};
             if (this.subMeshes.length > 1 && !subMesh.canIntersects(ray))
                 continue;
 
-            var currentDistance = subMesh.intersects(ray, this._positions, this._indices, fastCheck);
+            var currentIntersectInfo = subMesh.intersects(ray, this._positions, this._indices, fastCheck);
 
-            if (currentDistance > 0) {
-                if (fastCheck || currentDistance < distance) {
-                    distance = currentDistance;
+            if (currentIntersectInfo) {
+                if (fastCheck || !intersectInfo || currentIntersectInfo.distance < intersectInfo.distance) {
+                    intersectInfo = currentIntersectInfo;
 
                     if (fastCheck) {
                         break;
@@ -810,13 +804,13 @@ var BABYLON = BABYLON || {};
             }
         }
 
-        if (distance >= 0 && distance < Number.MAX_VALUE) {
+        if (intersectInfo) {
             // Get picked point
             var world = this.getWorldMatrix();
             var worldOrigin = BABYLON.Vector3.TransformCoordinates(ray.origin, world);
             var direction = ray.direction.clone();
             direction.normalize();
-            direction = direction.scale(distance);
+            direction = direction.scale(intersectInfo.distance);
             var worldDirection = BABYLON.Vector3.TransformNormal(direction, world);
 
             var pickedPoint = worldOrigin.add(worldDirection);
@@ -826,6 +820,9 @@ var BABYLON = BABYLON || {};
             pickingInfo.distance = BABYLON.Vector3.Distance(worldOrigin, pickedPoint);
             pickingInfo.pickedPoint = pickedPoint;
             pickingInfo.pickedMesh = this;
+            pickingInfo.bu = intersectInfo.bu;
+            pickingInfo.bv = intersectInfo.bv;
+            pickingInfo.faceId = intersectInfo.faceId;
             return pickingInfo;
         }
 
@@ -888,8 +885,8 @@ var BABYLON = BABYLON || {};
     // Dispose
     BABYLON.Mesh.prototype.dispose = function (doNotRecurse) {
         if (this._vertexBuffers) {
-            for (var index = 0; index < this._vertexBuffers.length; index++) {
-                this._vertexBuffers[index].dispose();
+            for (var vbKind in this._vertexBuffers) {
+                this._vertexBuffers[vbKind].dispose();
             }
             this._vertexBuffers = null;
         }
@@ -1010,7 +1007,7 @@ var BABYLON = BABYLON || {};
     };
 
     // Geometric tools
-    BABYLON.Mesh.prototype.convertToFlatShadedMesh = function() {
+    BABYLON.Mesh.prototype.convertToFlatShadedMesh = function () {
         /// <summary>Update normals and vertices to get a flat shading rendering.</summary>
         /// <summary>Warning: This may imply adding vertices to the mesh in order to get exactly 3 vertices per face</summary>
 
@@ -1240,7 +1237,7 @@ var BABYLON = BABYLON || {};
             var radius = isTop ? radiusTop : radiusBottom;
 
             if (radius == 0) {
-                return
+                return;
             }
 
             // Create cap indices.

+ 7 - 9
Babylon/Mesh/babylon.subMesh.js

@@ -87,7 +87,7 @@ var BABYLON = BABYLON || {};
     };
 
     BABYLON.SubMesh.prototype.intersects = function (ray, positions, indices, fastCheck) {
-        var distance = Number.MAX_VALUE;
+        var intersectInfo = null;
 
         // Triangles test
         for (var index = this.indexStart; index < this.indexStart + this.indexCount; index += 3) {
@@ -95,11 +95,12 @@ var BABYLON = BABYLON || {};
             var p1 = positions[indices[index + 1]];
             var p2 = positions[indices[index + 2]];
 
-            var currentDistance = ray.intersectsTriangle(p0, p1, p2);
+            var currentIntersectInfo = ray.intersectsTriangle(p0, p1, p2);
 
-            if (currentDistance > 0) {
-                if (fastCheck || currentDistance < distance) {
-                    distance = currentDistance;
+            if (currentIntersectInfo) {
+                if (fastCheck || !intersectInfo || currentIntersectInfo.distance < intersectInfo.distance) {
+                    intersectInfo = currentIntersectInfo;
+                    intersectInfo.faceId = index / 3;
 
                     if (fastCheck) {
                         break;
@@ -108,10 +109,7 @@ var BABYLON = BABYLON || {};
             }
         }
 
-        if (distance > 0 && distance < Number.MAX_VALUE)
-            return distance;
-
-        return 0;
+        return intersectInfo;
     };
 
     // Clone    

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

@@ -93,6 +93,8 @@ var BABYLON = BABYLON || {};
 
     BABYLON.ParticleSystem.prototype.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;
 
+    BABYLON.ParticleSystem.prototype.forceDepthWrite = false;
+
     // Methods   
     BABYLON.ParticleSystem.prototype.isAlive = function () {
         return this._alive;
@@ -329,6 +331,11 @@ var BABYLON = BABYLON || {};
         } else {
             engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
         }
+
+        if (this.forceDepthWrite) {
+            this.setDepthWrite(true);
+        }
+
         engine.draw(true, 0, this.particles.length * 6);
         engine.setAlphaMode(BABYLON.Engine.ALPHA_DISABLE);
 

+ 2 - 0
Babylon/Physics/babylon.physicsEngine.js

@@ -17,6 +17,8 @@ var BABYLON = BABYLON || {};
     BABYLON.PhysicsEngine.prototype._runOneStep = function (delta) {
         if (delta > 0.1) {
             delta = 0.1;
+        } else if (delta <= 0) {
+            delta = 1.0 / 60.0;
         }
 
         this._world.step(delta);

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 504 - 504
Babylon/Shaders/iedefault.fragment.fx


+ 285 - 285
Babylon/Shaders/iedefault.vertex.fx

@@ -1,286 +1,286 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
-#define MAP_EXPLICIT	0.
-#define MAP_SPHERICAL	1.
-#define MAP_PLANAR		2.
-#define MAP_CUBIC		3.
-#define MAP_PROJECTION	4.
-#define MAP_SKYBOX		5.
-
-// Attributes
-attribute vec3 position;
-attribute vec3 normal;
-#ifdef UV1
-attribute vec2 uv;
-#endif
-#ifdef UV2
-attribute vec2 uv2;
-#endif
-#ifdef VERTEXCOLOR
-attribute vec3 color;
-#endif
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
-#endif
-
-// Uniforms
-uniform mat4 world;
-uniform mat4 view;
-uniform mat4 viewProjection;
-
-#ifdef DIFFUSE
-varying vec2 vDiffuseUV;
-uniform mat4 diffuseMatrix;
-uniform vec2 vDiffuseInfos;
-#endif
-
-#ifdef AMBIENT
-varying vec2 vAmbientUV;
-uniform mat4 ambientMatrix;
-uniform vec2 vAmbientInfos;
-#endif
-
-#ifdef OPACITY
-varying vec2 vOpacityUV;
-uniform mat4 opacityMatrix;
-uniform vec2 vOpacityInfos;
-#endif
-
-#ifdef REFLECTION
-uniform vec3 vEyePosition;
-varying vec3 vReflectionUVW;
-uniform vec3 vReflectionInfos;
-uniform mat4 reflectionMatrix;
-#endif
-
-#ifdef EMISSIVE
-varying vec2 vEmissiveUV;
-uniform vec2 vEmissiveInfos;
-uniform mat4 emissiveMatrix;
-#endif
-
-#ifdef SPECULAR
-varying vec2 vSpecularUV;
-uniform vec2 vSpecularInfos;
-uniform mat4 specularMatrix;
-#endif
-
-#ifdef BUMP
-varying vec2 vBumpUV;
-uniform vec2 vBumpInfos;
-uniform mat4 bumpMatrix;
-#endif
-
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
-
-// Output
-varying vec3 vPositionW;
-varying vec3 vNormalW;
-
-#ifdef VERTEXCOLOR
-varying vec3 vColor;
-#endif
-
-#ifdef CLIPPLANE
-uniform vec4 vClipPlane;
-varying float fClipDistance;
-#endif
-
-#ifdef FOG
-varying float fFogDistance;
-#endif
-
-#ifdef SHADOWS
-#ifdef LIGHT0
-uniform mat4 lightMatrix0;
-varying vec4 vPositionFromLight0;
-#endif
-#ifdef LIGHT1
-uniform mat4 lightMatrix1;
-varying vec4 vPositionFromLight1;
-#endif
-#ifdef LIGHT2
-uniform mat4 lightMatrix2;
-varying vec4 vPositionFromLight2;
-#endif
-#ifdef LIGHT3
-uniform mat4 lightMatrix3;
-varying vec4 vPositionFromLight3;
-#endif
-#endif
-
-#ifdef REFLECTION
-vec3 computeReflectionCoords(float mode, vec4 worldPos, vec3 worldNormal)
-{
-	if (mode == MAP_SPHERICAL)
-	{
-		vec3 coords = vec3(view * vec4(worldNormal, 0.0));
-
-		return vec3(reflectionMatrix * vec4(coords, 1.0));
-	}
-	else if (mode == MAP_PLANAR)
-	{
-		vec3 viewDir = worldPos.xyz - vEyePosition;
-		vec3 coords = normalize(reflect(viewDir, worldNormal));
-
-		return vec3(reflectionMatrix * vec4(coords, 1));
-	}
-	else if (mode == MAP_CUBIC)
-	{
-		vec3 viewDir = worldPos.xyz - vEyePosition;
-		vec3 coords = reflect(viewDir, worldNormal);
-
-		return vec3(reflectionMatrix * vec4(coords, 0));
-	}
-	else if (mode == MAP_PROJECTION)
-	{
-		return vec3(reflectionMatrix * (view * worldPos));
-	}
-	else if (mode == MAP_SKYBOX)
-	{
-		return position;
-	}
-
-	return vec3(0, 0, 0);
-}
-#endif
-
-void main(void) {
-	mat4 finalWorld;
-
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-
-#ifdef BONES4
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = world * (m0 + m1 + m2 + m3);
-#else
-	finalWorld = world * (m0 + m1 + m2);
-#endif 
-
-#else
-	finalWorld = world;
-#endif
-
-	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
-
-	vec4 worldPos = finalWorld * vec4(position, 1.0);
-	vPositionW = vec3(worldPos);
-	vNormalW = normalize(vec3(finalWorld * vec4(normal, 0.0)));
-
-	// Texture coordinates
-#ifndef UV1
-	vec2 uv = vec2(0., 0.);
-#endif
-#ifndef UV2
-	vec2 uv2 = vec2(0., 0.);
-#endif
-
-#ifdef DIFFUSE
-	if (vDiffuseInfos.x == 0.)
-	{
-		vDiffuseUV = vec2(diffuseMatrix * vec4(uv, 1.0, 0.0));
-	}
-	else
-	{
-		vDiffuseUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0));
-	}
-#endif
-
-#ifdef AMBIENT
-	if (vAmbientInfos.x == 0.)
-	{
-		vAmbientUV = vec2(ambientMatrix * vec4(uv, 1.0, 0.0));
-	}
-	else
-	{
-		vAmbientUV = vec2(ambientMatrix * vec4(uv2, 1.0, 0.0));
-	}
-#endif
-
-#ifdef OPACITY
-	if (vOpacityInfos.x == 0.)
-	{
-		vOpacityUV = vec2(opacityMatrix * vec4(uv, 1.0, 0.0));
-	}
-	else
-	{
-		vOpacityUV = vec2(opacityMatrix * vec4(uv2, 1.0, 0.0));
-	}
-#endif
-
-#ifdef REFLECTION
-	vReflectionUVW = computeReflectionCoords(vReflectionInfos.x, vec4(vPositionW, 1.0), vNormalW);
-#endif
-
-#ifdef EMISSIVE
-	if (vEmissiveInfos.x == 0.)
-	{
-		vEmissiveUV = vec2(emissiveMatrix * vec4(uv, 1.0, 0.0));
-	}
-	else
-	{
-		vEmissiveUV = vec2(emissiveMatrix * vec4(uv2, 1.0, 0.0));
-	}
-#endif
-
-#ifdef SPECULAR
-	if (vSpecularInfos.x == 0.)
-	{
-		vSpecularUV = vec2(specularMatrix * vec4(uv, 1.0, 0.0));
-	}
-	else
-	{
-		vSpecularUV = vec2(specularMatrix * vec4(uv2, 1.0, 0.0));
-	}
-#endif
-
-#ifdef BUMP
-	if (vBumpInfos.x == 0.)
-	{
-		vBumpUV = vec2(bumpMatrix * vec4(uv, 1.0, 0.0));
-	}
-	else
-	{
-		vBumpUV = vec2(bumpMatrix * vec4(uv2, 1.0, 0.0));
-	}
-#endif
-
-	// Clip plane
-#ifdef CLIPPLANE
-	fClipDistance = dot(worldPos, vClipPlane);
-#endif
-
-	// Fog
-#ifdef FOG
-	fFogDistance = (view * worldPos).z;
-#endif
-
-	// Shadows
-#ifdef SHADOWS
-#ifdef LIGHT0
-	vPositionFromLight0 = lightMatrix0 * vec4(position, 1.0);
-#endif
-#ifdef LIGHT1
-	vPositionFromLight1 = lightMatrix1 * vec4(position, 1.0);
-#endif
-#ifdef LIGHT2
-	vPositionFromLight2 = lightMatrix2 * vec4(position, 1.0);
-#endif
-#ifdef LIGHT3
-	vPositionFromLight3 = lightMatrix3 * vec4(position, 1.0);
-#endif
-#endif
-
-	// Vertex color
-#ifdef VERTEXCOLOR
-	vColor = color;
-#endif
+#ifdef GL_ES
+precision mediump float;
+#endif
+
+#define MAP_EXPLICIT	0.
+#define MAP_SPHERICAL	1.
+#define MAP_PLANAR		2.
+#define MAP_CUBIC		3.
+#define MAP_PROJECTION	4.
+#define MAP_SKYBOX		5.
+
+// Attributes
+attribute vec3 position;
+attribute vec3 normal;
+#ifdef UV1
+attribute vec2 uv;
+#endif
+#ifdef UV2
+attribute vec2 uv2;
+#endif
+#ifdef VERTEXCOLOR
+attribute vec3 color;
+#endif
+#ifdef BONES
+attribute vec4 matricesIndices;
+attribute vec4 matricesWeights;
+#endif
+
+// Uniforms
+uniform mat4 world;
+uniform mat4 view;
+uniform mat4 viewProjection;
+
+#ifdef DIFFUSE
+varying vec2 vDiffuseUV;
+uniform mat4 diffuseMatrix;
+uniform vec2 vDiffuseInfos;
+#endif
+
+#ifdef AMBIENT
+varying vec2 vAmbientUV;
+uniform mat4 ambientMatrix;
+uniform vec2 vAmbientInfos;
+#endif
+
+#ifdef OPACITY
+varying vec2 vOpacityUV;
+uniform mat4 opacityMatrix;
+uniform vec2 vOpacityInfos;
+#endif
+
+#ifdef REFLECTION
+uniform vec3 vEyePosition;
+varying vec3 vReflectionUVW;
+uniform vec3 vReflectionInfos;
+uniform mat4 reflectionMatrix;
+#endif
+
+#ifdef EMISSIVE
+varying vec2 vEmissiveUV;
+uniform vec2 vEmissiveInfos;
+uniform mat4 emissiveMatrix;
+#endif
+
+#ifdef SPECULAR
+varying vec2 vSpecularUV;
+uniform vec2 vSpecularInfos;
+uniform mat4 specularMatrix;
+#endif
+
+#ifdef BUMP
+varying vec2 vBumpUV;
+uniform vec2 vBumpInfos;
+uniform mat4 bumpMatrix;
+#endif
+
+#ifdef BONES
+uniform mat4 mBones[BonesPerMesh];
+#endif
+
+// Output
+varying vec3 vPositionW;
+varying vec3 vNormalW;
+
+#ifdef VERTEXCOLOR
+varying vec3 vColor;
+#endif
+
+#ifdef CLIPPLANE
+uniform vec4 vClipPlane;
+varying float fClipDistance;
+#endif
+
+#ifdef FOG
+varying float fFogDistance;
+#endif
+
+#ifdef SHADOWS
+#ifdef LIGHT0
+uniform mat4 lightMatrix0;
+varying vec4 vPositionFromLight0;
+#endif
+#ifdef LIGHT1
+uniform mat4 lightMatrix1;
+varying vec4 vPositionFromLight1;
+#endif
+#ifdef LIGHT2
+uniform mat4 lightMatrix2;
+varying vec4 vPositionFromLight2;
+#endif
+#ifdef LIGHT3
+uniform mat4 lightMatrix3;
+varying vec4 vPositionFromLight3;
+#endif
+#endif
+
+#ifdef REFLECTION
+vec3 computeReflectionCoords(float mode, vec4 worldPos, vec3 worldNormal)
+{
+	if (mode == MAP_SPHERICAL)
+	{
+		vec3 coords = vec3(view * vec4(worldNormal, 0.0));
+
+		return vec3(reflectionMatrix * vec4(coords, 1.0));
+	}
+	else if (mode == MAP_PLANAR)
+	{
+		vec3 viewDir = worldPos.xyz - vEyePosition;
+		vec3 coords = normalize(reflect(viewDir, worldNormal));
+
+		return vec3(reflectionMatrix * vec4(coords, 1));
+	}
+	else if (mode == MAP_CUBIC)
+	{
+		vec3 viewDir = worldPos.xyz - vEyePosition;
+		vec3 coords = reflect(viewDir, worldNormal);
+
+		return vec3(reflectionMatrix * vec4(coords, 0));
+	}
+	else if (mode == MAP_PROJECTION)
+	{
+		return vec3(reflectionMatrix * (view * worldPos));
+	}
+	else if (mode == MAP_SKYBOX)
+	{
+		return position;
+	}
+
+	return vec3(0, 0, 0);
+}
+#endif
+
+void main(void) {
+	mat4 finalWorld;
+
+#ifdef BONES
+	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
+	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
+	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
+
+#ifdef BONES4
+	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
+	finalWorld = world * (m0 + m1 + m2 + m3);
+#else
+	finalWorld = world * (m0 + m1 + m2);
+#endif 
+
+#else
+	finalWorld = world;
+#endif
+
+	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
+
+	vec4 worldPos = finalWorld * vec4(position, 1.0);
+	vPositionW = vec3(worldPos);
+	vNormalW = normalize(vec3(finalWorld * vec4(normal, 0.0)));
+
+	// Texture coordinates
+#ifndef UV1
+	vec2 uv = vec2(0., 0.);
+#endif
+#ifndef UV2
+	vec2 uv2 = vec2(0., 0.);
+#endif
+
+#ifdef DIFFUSE
+	if (vDiffuseInfos.x == 0.)
+	{
+		vDiffuseUV = vec2(diffuseMatrix * vec4(uv, 1.0, 0.0));
+	}
+	else
+	{
+		vDiffuseUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0));
+	}
+#endif
+
+#ifdef AMBIENT
+	if (vAmbientInfos.x == 0.)
+	{
+		vAmbientUV = vec2(ambientMatrix * vec4(uv, 1.0, 0.0));
+	}
+	else
+	{
+		vAmbientUV = vec2(ambientMatrix * vec4(uv2, 1.0, 0.0));
+	}
+#endif
+
+#ifdef OPACITY
+	if (vOpacityInfos.x == 0.)
+	{
+		vOpacityUV = vec2(opacityMatrix * vec4(uv, 1.0, 0.0));
+	}
+	else
+	{
+		vOpacityUV = vec2(opacityMatrix * vec4(uv2, 1.0, 0.0));
+	}
+#endif
+
+#ifdef REFLECTION
+	vReflectionUVW = computeReflectionCoords(vReflectionInfos.x, vec4(vPositionW, 1.0), vNormalW);
+#endif
+
+#ifdef EMISSIVE
+	if (vEmissiveInfos.x == 0.)
+	{
+		vEmissiveUV = vec2(emissiveMatrix * vec4(uv, 1.0, 0.0));
+	}
+	else
+	{
+		vEmissiveUV = vec2(emissiveMatrix * vec4(uv2, 1.0, 0.0));
+	}
+#endif
+
+#ifdef SPECULAR
+	if (vSpecularInfos.x == 0.)
+	{
+		vSpecularUV = vec2(specularMatrix * vec4(uv, 1.0, 0.0));
+	}
+	else
+	{
+		vSpecularUV = vec2(specularMatrix * vec4(uv2, 1.0, 0.0));
+	}
+#endif
+
+#ifdef BUMP
+	if (vBumpInfos.x == 0.)
+	{
+		vBumpUV = vec2(bumpMatrix * vec4(uv, 1.0, 0.0));
+	}
+	else
+	{
+		vBumpUV = vec2(bumpMatrix * vec4(uv2, 1.0, 0.0));
+	}
+#endif
+
+	// Clip plane
+#ifdef CLIPPLANE
+	fClipDistance = dot(worldPos, vClipPlane);
+#endif
+
+	// Fog
+#ifdef FOG
+	fFogDistance = (view * worldPos).z;
+#endif
+
+	// Shadows
+#ifdef SHADOWS
+#ifdef LIGHT0
+	vPositionFromLight0 = lightMatrix0 * vec4(position, 1.0);
+#endif
+#ifdef LIGHT1
+	vPositionFromLight1 = lightMatrix1 * vec4(position, 1.0);
+#endif
+#ifdef LIGHT2
+	vPositionFromLight2 = lightMatrix2 * vec4(position, 1.0);
+#endif
+#ifdef LIGHT3
+	vPositionFromLight3 = lightMatrix3 * vec4(position, 1.0);
+#endif
+#endif
+
+	// Vertex color
+#ifdef VERTEXCOLOR
+	vColor = color;
+#endif
 }

+ 502 - 21
Babylon/Tools/babylon.sceneSerializer.js

@@ -4,34 +4,454 @@ var BABYLON = BABYLON || {};
 
 (function () {
 
-    var serializeLight = function (light, serializationObject) {
+    var serializeLight = function (light) {
+        var serializationObject = {};
         serializationObject.name = light.name;
+        serializationObject.id = light.id;
 
         if (light instanceof BABYLON.PointLight) {
             serializationObject.type = 0;
             serializationObject.position = light.position.asArray();
+        } else if (light instanceof BABYLON.DirectionalLight) {
+            serializationObject.type = 1;
+            serializationObject.position = light.position.asArray();
+            serializationObject.direction = light.position.asArray();
+        } else if (light instanceof BABYLON.SpotLight) {
+            serializationObject.type = 2;
+            serializationObject.position = light.position.asArray();
+            serializationObject.direction = light.position.asArray();
+            serializationObject.angle = light.angle;
+            serializationObject.exponent = light.exponent;
+        } else if (light instanceof BABYLON.HemisphericLight) {
+            serializationObject.type = 2;
+            serializationObject.groundColor = light.groundColor.asArray();
         }
-        //switch (light.type) {
-        //    case 1:
-        //        light = new BABYLON.DirectionalLight(parsedLight.name, BABYLON.Vector3.FromArray(parsedLight.direction), scene);
-        //        light.position = BABYLON.Vector3.FromArray(parsedLight.position);
-        //        break;
-        //    case 2:
-        //        light = new BABYLON.SpotLight(parsedLight.name, BABYLON.Vector3.FromArray(parsedLight.position), BABYLON.Vector3.FromArray(parsedLight.direction), parsedLight.angle, parsedLight.exponent, scene);
-        //        break;
-        //    case 3:
-        //        light = new BABYLON.HemisphericLight(parsedLight.name, BABYLON.Vector3.FromArray(parsedLight.direction), scene);
-        //        light.groundColor = BABYLON.Color3.FromArray(parsedLight.groundColor);
-        //        break;
-        //}
-
-        serializationObject.id = light.id;
 
         if (light.intensity) {
             serializationObject.intensity = light.intensity;
         }
         serializationObject.diffuse = light.diffuse.asArray();
         serializationObject.specular = light.specular.asArray();
+
+        return serializationObject;
+    };
+
+    var serializeCamera = function (camera) {
+        var serializationObject = {};
+        serializationObject.name = camera.name;
+        serializationObject.id = camera.id;
+        serializationObject.position = camera.position.asArray();
+
+        // Parent
+        if (camera.parent) {
+            serializationObject.parentId = camera.parent.id;
+        }
+
+        // Target
+        serializationObject.rotation = camera.rotation.asArray();
+
+        // Locked target
+        if (camera.lockedTarget && camera.lockedTarget.id) {
+            serializationObject.lockedTargetId = camera.lockedTarget.id;
+        }
+
+        serializationObject.fov = camera.fov;
+        serializationObject.minZ = camera.minZ;
+        serializationObject.maxZ = camera.maxZ;
+
+        serializationObject.speed = camera.speed;
+        serializationObject.inertia = camera.inertia;
+
+        serializationObject.checkCollisions = camera.checkCollisions;
+        serializationObject.applyGravity = camera.applyGravity;
+
+        if (camera.ellipsoid) {
+            serializationObject.ellipsoid = camera.ellipsoid.asArray();
+        }
+
+        // Animations
+        appendAnimations(camera, serializationObject);
+
+        return serializationObject;
+    };
+
+    var appendAnimations = function (source, destination) {
+        if (source.animations) {
+            destination.animations = [];
+            for (var animationIndex = 0; animationIndex < source.animations.length; animationIndex++) {
+                var animation = source.animations[animationIndex];
+
+                destination.animations.push(serializeAnimation(animation));
+            }
+        }
+    };
+
+    var serializeAnimation = function (animation) {
+        var serializationObject = {};
+
+        serializationObject.name = animation.name;
+        serializationObject.property = animation.targetProperty;
+        serializationObject.framePerSecond = animation.framePerSecond;
+        serializationObject.dataType = animation.dataType;
+        serializationObject.loopBehavior = animation.loopBehavior;
+
+        var dataType = animation.dataType;
+        serializationObject.keys = [];
+        for (var index = 0; index < animation._keys.length; index++) {
+            var animationKey = animation._keys[index];
+
+            var key = {};
+            key.frame = animationKey.frame;
+
+            switch (dataType) {
+                case BABYLON.Animation.ANIMATIONTYPE_FLOAT:
+                    key.values = [animationKey.value];
+                    break;
+                case BABYLON.Animation.ANIMATIONTYPE_QUATERNION:
+                case BABYLON.Animation.ANIMATIONTYPE_MATRIX:
+                case BABYLON.Animation.ANIMATIONTYPE_VECTOR3:
+                    key.values = animationKey.value.asArray();
+                    break;
+            }
+
+            serializationObject.keys.push(key);
+        }
+
+        return serializationObject;
+    };
+
+    var serializeMultiMaterial = function (material) {
+        var serializationObject = {};
+
+        serializationObject.name = material.name;
+        serializationObject.id = material.id;
+
+        serializationObject.materials = [];
+
+        for (var matIndex = 0; matIndex < material.subMaterials.length; matIndex++) {
+            var subMat = material.subMaterials[matIndex];
+
+            if (subMat) {
+                serializationObject.materials.push(subMat.id);
+            } else {
+                serializationObject.materials.push(null);
+            }
+        }
+
+        return serializationObject;
+    };
+
+    var serializeMaterial = function (material) {
+        var serializationObject = {};
+
+        serializationObject.name = material.name;
+
+        serializationObject.ambient = material.ambientColor.asArray();
+        serializationObject.diffuse = material.diffuseColor.asArray();
+        serializationObject.specular = material.specularColor.asArray();
+        serializationObject.specularPower = material.specularPower;
+        serializationObject.emissive = material.emissiveColor.asArray();
+
+        serializationObject.alpha = material.alpha;
+
+        serializationObject.id = material.id;
+        serializationObject.backFaceCulling = material.backFaceCulling;
+
+        if (material.diffuseTexture) {
+            serializationObject.diffuseTexture = serializeTexture(material.diffuseTexture);
+        }
+
+        if (material.ambientTexture) {
+            serializationObject.ambientTexture = serializeTexture(material.ambientTexture);
+        }
+
+        if (material.opacityTexture) {
+            serializationObject.opacityTexture = serializeTexture(material.opacityTexture);
+        }
+
+        if (material.reflectionTexture) {
+            serializationObject.reflectionTexture = serializeTexture(material.reflectionTexture);
+        }
+
+        if (material.emissiveTexture) {
+            serializationObject.emissiveTexture = serializeTexture(material.emissiveTexture);
+        }
+
+        if (material.specularTexture) {
+            serializationObject.specularTexture = serializeTexture(material.specularTexture);
+        }
+
+        if (material.bumpTexture) {
+            serializationObject.bumpTexture = serializeTexture(material.bumpTexture);
+        }
+
+        return serializationObject;
+    };
+
+    var serializeTexture = function (texture) {
+        var serializationObject = {};
+
+        if (!texture.name) {
+            return null;
+        }
+
+        if (texture instanceof BABYLON.CubeTexture) {
+            serializationObject.name = texture.name;
+            serializationObject.hasAlpha = texture.hasAlpha;
+            serializationObject.level = texture.level;
+            serializationObject.coordinatesMode = texture.coordinatesMode;
+
+            return serializationObject;
+        }
+
+        if (texture instanceof BABYLON.MirrorTexture) {
+            serializationObject.renderTargetSize = texture.renderTargetSize;
+            serializationObject.renderList = [];
+
+            for (var index = 0; index < texture.renderList.length; index++) {
+                serializationObject.renderList.push(texture.renderList[index].id);
+            }
+
+            serializationObject.mirrorPlane = texture.mirrorPlane.asArray();
+        } else if (texture instanceof BABYLON.RenderTargetTexture) {
+            serializationObject.renderTargetSize = texture.renderTargetSize;
+            serializationObject.renderList = [];
+
+            for (var index = 0; index < texture.renderList.length; index++) {
+                serializationObject.renderList.push(texture.renderList[index].id);
+            }
+        }
+
+        serializationObject.name = texture.name;
+        serializationObject.hasAlpha = texture.hasAlpha;
+        serializationObject.level = texture.level;
+
+        serializationObject.coordinatesIndex = texture.coordinatesIndex;
+        serializationObject.coordinatesMode = texture.coordinatesMode;
+        serializationObject.uOffset = texture.uOffset;
+        serializationObject.vOffset = texture.vOffset;
+        serializationObject.uScale = texture.uScale;
+        serializationObject.vScale = texture.vScale;
+        serializationObject.uAng = texture.uAng;
+        serializationObject.vAng = texture.vAng;
+        serializationObject.wAng = texture.wAng;
+
+        serializationObject.wrapU = texture.wrapU;
+        serializationObject.wrapV = texture.wrapV;
+
+        // Animations
+        appendAnimations(texture, serializationObject);
+
+        return serializationObject;
+    };
+
+    var serializeSkeleton = function (skeleton) {
+        var serializationObject = {};
+
+        serializationObject.name = skeleton.name;
+        serializationObject.id = skeleton.id;
+
+        serializationObject.bones = [];
+
+        for (var index = 0; index < skeleton.bones.length; index++) {
+            var bone = skeleton.bones[index];
+
+            var serializedBone = {
+                parentBoneIndex: bone._parent ? bone._parent.id : -1,
+                name: bone.name,
+                matrix: bone._matrix.toArray()
+            };
+
+            serializationObject.bones.push(serializedBone);
+
+            if (bone.animations && bone.animations.length > 0) {
+                serializedBone.animation = serializeAnimation(bone.animations[0]);
+            }
+        }
+        return serializationObject;
+    };
+
+    var serializeParticleSystem = function (particleSystem) {
+        var serializationObject = {};
+
+        serializationObject.emitterId = particleSystem.emitter.id;
+        serializationObject.capacity = particleSystem._capacity;
+
+        if (particleSystem.particleTexture) {
+            serializationObject.textureName = particleSystem.particleTexture.name;
+        }
+
+        serializationObject.minAngularSpeed = particleSystem.minAngularSpeed;
+        serializationObject.maxAngularSpeed = particleSystem.maxAngularSpeed;
+        serializationObject.minSize = particleSystem.minSize;
+        serializationObject.maxSize = particleSystem.maxSize;
+        serializationObject.minLifeTime = particleSystem.minLifeTime;
+        serializationObject.maxLifeTime = particleSystem.maxLifeTime;
+        serializationObject.emitRate = particleSystem.emitRate;
+        serializationObject.minEmitBox = particleSystem.minEmitBox.asArray();
+        serializationObject.maxEmitBox = particleSystem.maxEmitBox.asArray();
+        serializationObject.gravity = particleSystem.gravity.asArray();
+        serializationObject.direction1 = particleSystem.direction1.asArray();
+        serializationObject.direction2 = particleSystem.direction2.asArray();
+        serializationObject.color1 = particleSystem.color1.asArray();
+        serializationObject.color2 = particleSystem.color2.asArray();
+        serializationObject.colorDead = particleSystem.colorDead.asArray();
+        serializationObject.updateSpeed = particleSystem.updateSpeed;
+        serializationObject.targetStopDuration = particleSystem.targetStopFrame;
+        serializationObject.textureMask = particleSystem.textureMask.asArray();
+        serializationObject.blendMode = particleSystem.blendMode;
+
+        return serializationObject;
+    };
+
+    var serializeLensFlareSystem = function (lensFlareSystem) {
+        var serializationObject = {};
+
+        serializationObject.emitterId = lensFlareSystem._emitter.id;
+        serializationObject.borderLimit = lensFlareSystem.borderLimit;
+
+        serializationObject.flares = [];
+        for (var index = 0; index < lensFlareSystem.lensFlares.length; index++) {
+            var flare = lensFlareSystem.lensFlares[index];
+
+            serializationObject.flares.push({
+                size: flare.size,
+                position: flare.position,
+                color: flare.color.asArray(),
+                textureName: BABYLON.Tools.GetFilename(flare.texture.name)
+            });
+        }
+
+
+        return serializationObject;
+    };
+
+    var serializeShadowGenerator = function (light) {
+        var serializationObject = {};
+        var shadowGenerator = light._shadowGenerator;
+
+        serializationObject.lightId = light.id;
+        serializationObject.mapSize = shadowGenerator.getShadowMap()._size;
+        serializationObject.useVarianceShadowMap = shadowGenerator.useVarianceShadowMap;
+
+        serializationObject.renderList = [];
+        for (var meshIndex = 0; meshIndex < shadowGenerator.getShadowMap().renderList.length; meshIndex++) {
+            var mesh = shadowGenerator.getShadowMap().renderList[meshIndex];
+
+            serializationObject.renderList.push(mesh.id);
+        }
+
+        return serializationObject;
+    };
+
+    var serializeMesh = function (mesh) {
+        var serializationObject = {};
+
+        serializationObject.name = mesh.name;
+        serializationObject.id = mesh.id;
+
+        serializationObject.position = mesh.position.asArray();
+
+        if (mesh.rotation) {
+            serializationObject.rotation = mesh.rotation.asArray();
+        } else if (mesh.rotationQuaternion) {
+            serializationObject.rotationQuaternion = mesh.rotationQuaternion.asArray();
+        }
+
+        serializationObject.scaling = mesh.scaling.asArray();
+        serializationObject.localMatrix = mesh.getPivotMatrix().asArray();
+
+        serializationObject.isEnabled = mesh.isEnabled();
+        serializationObject.isVisible = mesh.isVisible;
+        serializationObject.infiniteDistance = mesh.infiniteDistance;
+
+        serializationObject.receiveShadows = mesh.receiveShadows;
+
+        serializationObject.billboardMode = mesh.billboardMode;
+        serializationObject.visibility = mesh.visibility;
+
+        serializationObject.checkCollisions = mesh.checkCollisions;
+
+        // Parent
+        if (mesh.parent) {
+            serializationObject.parentId = mesh.parent.id;
+        }
+
+        // Geometry
+        if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
+            serializationObject.positions = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
+            serializationObject.normals = mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
+
+            if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                serializationObject.uvs = mesh.getVerticesData(BABYLON.VertexBuffer.UVKind);
+            }
+
+            if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
+                serializationObject.uvs2 = mesh.getVerticesData(BABYLON.VertexBuffer.UV2Kind);
+            }
+
+            if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
+                serializationObject.colors = mesh.getVerticesData(BABYLON.VertexBuffer.ColorKind);
+            }
+
+            if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
+                serializationObject.matricesWeights = mesh.getVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind);
+            }
+
+            if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind)) {
+                serializationObject.matricesWeights = mesh.getVerticesData(BABYLON.VertexBuffer.MatricesIndicesKind);
+                serializationObject.matricesWeights._isExpanded = true;
+            }
+
+            serializationObject.indices = mesh.getIndices();
+
+            // SubMeshes
+            serializationObject.subMeshes = [];
+            for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
+                var subMesh = mesh.subMeshes[subIndex];
+
+                serializationObject.subMeshes.push({
+                    materialIndex: subMesh.materialIndex,
+                    verticesStart: subMesh.verticesStart,
+                    verticesCount: subMesh.verticesCount,
+                    indexStart: subMesh.indexStart,
+                    indexCount: subMesh.indexCount
+                });
+            }
+        }
+
+        // Material
+        if (mesh.material) {
+            serializationObject.materialId = mesh.material.id;
+        } else {
+            mesh.material = null;
+        }
+
+        // Skeleton
+        if (mesh.skeleton) {
+            serializationObject.skeletonId = mesh.skeleton.id;
+        }
+
+        // Physics
+        if (mesh.getPhysicsImpostor() !== BABYLON.PhysicsEngine.NoImpostor) {
+            serializationObject.physicsMass = mesh.getPhysicsMass();
+            serializationObject.physicsFriction = mesh.getPhysicsFriction();
+            serializationObject.physicsRestitution = mesh.getPhysicsRestitution();
+
+            switch (mesh.getPhysicsImpostor()) {
+                case BABYLON.PhysicsEngine.BoxImpostor:
+                    serializationObject.physicsImpostor = 1;
+                    break;
+                case BABYLON.PhysicsEngine.SphereImpostor:
+                    serializationObject.physicsImpostor = 2;
+                    break;
+            }
+        }
+
+        // Animations
+        appendAnimations(mesh, serializationObject);
+
+        return serializationObject;
     };
 
     BABYLON.SceneSerializer = {
@@ -58,14 +478,75 @@ var BABYLON = BABYLON || {};
             serializationObject.lights = [];
             for (var index = 0; index < scene.lights.length; index++) {
                 var light = scene.lights[index];
-                
-                var serializedLight = {};
-                serializationObject.lights.push(serializedLight);
 
-                serializeLight(light, serializedLight);
+                serializationObject.lights.push(serializeLight(light));
+            }
+
+            // Cameras
+            serializationObject.cameras = [];
+            for (var index = 0; index < scene.cameras.length; index++) {
+                var camera = scene.cameras[index];
+
+                if (camera instanceof BABYLON.FreeCamera) {
+                    serializationObject.cameras.push(serializeCamera(camera));
+                }
+            }
+            if (scene.activecamera) {
+                serializationObject.activeCameraID = scene.activeCamera.id;
+            }
+
+            // Materials
+            serializationObject.materials = [];
+            serializationObject.multiMaterials = [];
+            for (var index = 0; index < scene.materials.length; index++) {
+                var material = scene.materials[index];
+
+                if (material instanceof BABYLON.StandardMaterial) {
+                    serializationObject.materials.push(serializeMaterial(material));
+                } else if (material instanceof BABYLON.MultiMaterial) {
+                    serializationObject.multiMaterials.push(serializeMultiMaterial(material));
+                }
+            }
+
+            // Skeletons
+            serializationObject.skeletons = [];
+            for (var index = 0; index < scene.skeletons.length; index++) {
+                serializationObject.skeletons.push(serializeSkeleton(scene.skeletons[index]));
+            }
+
+            // Meshes
+            serializationObject.meshes = [];
+            for (var index = 0; index < scene.meshes.length; index++) {
+                var mesh = scene.meshes[index];
+
+                if (mesh.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_LOADED || mesh.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_NONE) {
+                    serializationObject.meshes.push(serializeMesh(mesh));
+                }
+            }
+
+            // Particles Systems
+            serializationObject.particleSystems = [];
+            for (var index = 0; index < scene.particleSystems.length; index++) {
+                serializationObject.particleSystems.push(serializeParticleSystem(scene.particleSystems[index]));
+            }
+
+            // Lens flares
+            serializationObject.lensFlareSystems = [];
+            for (var index = 0; index < scene.lensFlareSystems.length; index++) {
+                serializationObject.lensFlareSystems.push(serializeLensFlareSystem(scene.lensFlareSystems[index]));
+            }
+
+            // Shadows
+            serializationObject.shadowGenerators = [];
+            for (var index = 0; index < scene.lights.length; index++) {
+                var light = scene.lights[index];
+
+                if (light._shadowGenerator) {
+                    serializationObject.shadowGenerators.push(serializeShadowGenerator(light));
+                }
             }
 
-            return JSON.stringify(serializationObject);
+            return serializationObject;
         }
     };
 })();

+ 17 - 5
Babylon/Tools/babylon.tools.js

@@ -5,6 +5,22 @@ var BABYLON = BABYLON || {};
 (function () {
     BABYLON.Tools = {};
 
+    BABYLON.Tools.GetFilename = function (path) {
+        var index = path.lastIndexOf("/");
+        if (index < 0)
+            return path;
+
+        return path.substring(index + 1);
+    };
+
+    BABYLON.Tools.ToDegrees = function(angle) {
+        return angle * 180 / Math.PI;
+    };
+
+    BABYLON.Tools.ToRadians = function(angle) {
+         return angle * Math.PI / 180;
+    };
+
     BABYLON.Tools.ExtractMinAndMax = function (positions, start, count) {
         var minimum = new BABYLON.Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
         var maximum = new BABYLON.Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
@@ -243,11 +259,7 @@ var BABYLON = BABYLON || {};
         reader.readAsText(fileToLoad);
     };
 
-    // Misc.    
-    BABYLON.Tools.isIE = function () {
-        return window.ActiveXObject !== undefined;
-    };
-    
+    // Misc.        
     BABYLON.Tools.WithinEpsilon = function (a, b) {
         var num = a - b;
         return -1.401298E-45 <= num && num <= 1.401298E-45;

+ 1 - 1
Babylon/babylon.engine.js

@@ -558,7 +558,7 @@ var BABYLON = BABYLON || {};
                 break;
             case BABYLON.Engine.ALPHA_COMBINE:
                 this.setDepthWrite(false);
-                this._gl.blendFuncSeparate(this._gl.SRC_ALPHA, this._gl.ONE_MINUS_SRC_ALPHA, this._gl.ZERO, this._gl.ONE);
+                this._gl.blendFuncSeparate(this._gl.SRC_ALPHA, this._gl.ONE_MINUS_SRC_ALPHA, this._gl.ONE, this._gl.ONE);
                 this._gl.enable(this._gl.BLEND);
                 break;
             case BABYLON.Engine.ALPHA_ADD:

+ 2 - 9
Babylon/babylon.node.js

@@ -15,6 +15,7 @@ var BABYLON = BABYLON || {};
     BABYLON.Node.prototype._childrenFlag = -1;
     BABYLON.Node.prototype._isReady = true;
     BABYLON.Node.prototype._isEnabled = true;
+    BABYLON.Node.prototype._currentRenderId = -1;
 
     // Cache
     BABYLON.Node.prototype._cache = null;
@@ -50,12 +51,8 @@ var BABYLON = BABYLON || {};
         return true;
     };
 
-    BABYLON.Node.prototype._syncChildFlag = function() {
-        this._childrenFlag = this.parent ? this.parent._childrenFlag : this._scene.getRenderId();
-    };
-
     BABYLON.Node.prototype.isSynchronizedWithParent = function() {
-        return this.parent ? !this.parent._needToSynchonizeChildren(this._childrenFlag) : true;
+        return this.parent ? !this.parent._currentRenderId === this._currentRenderId : true;
     };
 
     BABYLON.Node.prototype.isSynchronized = function (updateCache) {
@@ -81,10 +78,6 @@ var BABYLON = BABYLON || {};
         return true;
     };
 
-    BABYLON.Node.prototype._needToSynchonizeChildren = function (childFlag) {
-        return this._childrenFlag != childFlag;
-    };
-
     BABYLON.Node.prototype.isReady = function () {
         return this._isReady;
     };

+ 16 - 4
Babylon/babylon.scene.js

@@ -249,6 +249,7 @@ var BABYLON = BABYLON || {};
         if (speedRatio === undefined) {
             speedRatio = 1.0;
         }
+
         // Local animations
         if (target.animations) {
             this.stopAnimation(target);
@@ -269,10 +270,21 @@ var BABYLON = BABYLON || {};
     };
 
     BABYLON.Scene.prototype.stopAnimation = function (target) {
-        for (var index = 0; index < this._activeAnimatables.length; index++) {
-            if (this._activeAnimatables[index].target === target) {
-                this._activeAnimatables.splice(index, 1);
-                return;
+        // Local animations
+        if (target.animations) {
+            for (var index = 0; index < this._activeAnimatables.length; index++) {
+                if (this._activeAnimatables[index].target === target) {
+                    this._activeAnimatables.splice(index, 1);
+                    return;
+                }
+            }
+        }
+
+        // Children animations
+        if (target.getAnimatables) {
+            var animatables = target.getAnimatables();
+            for (var index = 0; index < animatables.length; index++) {
+                this.stopAnimation(animatables[index]);
             }
         }
     };

+ 65 - 18
Exporters/Blender/io_export_babylon.py

@@ -25,6 +25,8 @@ from bpy.props import (BoolProperty, FloatProperty, StringProperty, EnumProperty
 from math import radians
 from mathutils import *
 
+MAX_VERTICES = 65535
+
 class SubMesh:
     materialIndex = 0
     verticesStart = 0
@@ -342,20 +344,21 @@ class Export_babylon(bpy.types.Operator, ExportHelper):
         
         file_handler.write("]}")
 
-    def export_mesh(object, scene, file_handler, multiMaterials):
+    def export_mesh(object, scene, file_handler, multiMaterials, startFace, forcedParent, nameID):
         # Get mesh  
         mesh = object.to_mesh(scene, True, "PREVIEW")
         
         # Transform
         loc = mathutils.Vector((0, 0, 0))
-        rot = mathutils.Quaternion((0, 0, 0, 1))
+        rot = mathutils.Quaternion((0, 0, 0, -1))
         scale = mathutils.Vector((1, 1, 1))
         
+        hasSkeleton = False
+
         world = object.matrix_world
         if object.parent and object.parent.type == "ARMATURE" and len(object.vertex_groups) > 0:
             hasSkeleton = True
         else:
-            hasSkeleton = False
             if (object.parent):
                 world = object.parent.matrix_world.inverted() * object.matrix_world
 
@@ -401,6 +404,8 @@ class Export_babylon(bpy.types.Operator, ExportHelper):
         vertices_Colors=[]
         vertices_indices=[]
         subMeshes = []
+
+        offsetFace = 0
                 
         for v in range(0, len(mesh.vertices)):
             alreadySavedVertices.append(False)
@@ -414,18 +419,27 @@ class Export_babylon(bpy.types.Operator, ExportHelper):
         indicesCount = 0
 
         for materialIndex in range(materialsCount):
+            if offsetFace != 0:
+                break
+
             subMeshes.append(SubMesh())
             subMeshes[materialIndex].materialIndex = materialIndex
             subMeshes[materialIndex].verticesStart = verticesCount
             subMeshes[materialIndex].indexStart = indicesCount
         
-            for face in mesh.tessfaces:  # For each face
-                
+            for faceIndex in range(startFace, len(mesh.tessfaces)):  # For each face
+                face = mesh.tessfaces[faceIndex]
+
                 if face.material_index != materialIndex:
                     continue
-                
+
+                if verticesCount + 3 > MAX_VERTICES:
+                    offsetFace = faceIndex
+                    break
+
                 for v in range(3): # For each vertex in face
                     vertex_index = face.vertices[v]
+
                     vertex = mesh.vertices[vertex_index]
                     position = vertex.co
                     normal = vertex.normal
@@ -536,7 +550,7 @@ class Export_babylon(bpy.types.Operator, ExportHelper):
                     
             subMeshes[materialIndex].verticesCount = verticesCount - subMeshes[materialIndex].verticesStart
             subMeshes[materialIndex].indexCount = indicesCount - subMeshes[materialIndex].indexStart
-                
+
         positions=positions.rstrip(',')
         normals=normals.rstrip(',')
         indices=indices.rstrip(',')
@@ -567,10 +581,14 @@ class Export_babylon(bpy.types.Operator, ExportHelper):
         # Writing mesh      
         file_handler.write("{")
         
-        Export_babylon.write_string(file_handler, "name", object.name, True)        
-        Export_babylon.write_string(file_handler, "id", object.name)        
-        if object.parent != None:
-            Export_babylon.write_string(file_handler, "parentId", object.parent.name)
+        Export_babylon.write_string(file_handler, "name", object.name + nameID, True)        
+        Export_babylon.write_string(file_handler, "id", object.name + nameID)   
+
+        if forcedParent is None:     
+            if object.parent != None:
+                Export_babylon.write_string(file_handler, "parentId", object.parent.name)
+        else:
+            Export_babylon.write_string(file_handler, "parentId", forcedParent.name)
         
         if len(object.material_slots) == 1:
             material = object.material_slots[0].material
@@ -592,12 +610,19 @@ class Export_babylon(bpy.types.Operator, ExportHelper):
             billboardMode = 0
         else:
             billboardMode = 0
-            
-        Export_babylon.write_vector(file_handler, "position", loc)
-        Export_babylon.write_vectorScaled(file_handler, "rotation", rot.to_euler("XYZ"), -1)
-        Export_babylon.write_vector(file_handler, "scaling", scale)
+        
+        if forcedParent is None:
+            Export_babylon.write_vector(file_handler, "position", loc)
+            Export_babylon.write_vectorScaled(file_handler, "rotation", rot.to_euler("XYZ"), -1)
+            Export_babylon.write_vector(file_handler, "scaling", scale)
+        else:
+            Export_babylon.write_vector(file_handler, "position", mathutils.Vector((0, 0, 0)))
+            Export_babylon.write_vectorScaled(file_handler, "rotation", mathutils.Vector((0, 0, 0)), 1)
+            Export_babylon.write_vector(file_handler, "scaling", mathutils.Vector((1, 1, 1)))
+
         Export_babylon.write_bool(file_handler, "isVisible", object.is_visible(scene))
         Export_babylon.write_bool(file_handler, "isEnabled", True)
+        Export_babylon.write_bool(file_handler, "useFlatShading", object.data.useFlatShading)
         Export_babylon.write_bool(file_handler, "checkCollisions", object.data.checkCollisions)
         Export_babylon.write_int(file_handler, "billboardMode", billboardMode)
         Export_babylon.write_bool(file_handler, "receiveShadows", object.data.receiveShadows)
@@ -690,6 +715,8 @@ class Export_babylon(bpy.types.Operator, ExportHelper):
         # Closing
         file_handler.write("}")
 
+        return offsetFace
+
     def export_node(object, scene, file_handler):
         # Transform
         loc = mathutils.Vector((0, 0, 0))
@@ -922,7 +949,22 @@ class Export_babylon(bpy.types.Operator, ExportHelper):
 
                 first = False
                 if object.type == 'MESH':
-                    data_string = Export_babylon.export_mesh(object, scene, file_handler, multiMaterials)
+                    forcedParent = None
+                    nameID = ""
+                    startFace = 0
+
+                    while True:
+                        startFace = Export_babylon.export_mesh(object, scene, file_handler, multiMaterials, startFace, forcedParent, str(nameID))
+
+                        if startFace == 0:
+                            break
+
+                        if forcedParent is None:
+                            nameID = 0
+                            forcedParent = object
+
+                        nameID = nameID + 1
+                        file_handler.write(",")
                 else:
                     data_string = Export_babylon.export_node(object, scene, file_handler)
 
@@ -974,6 +1016,10 @@ class Export_babylon(bpy.types.Operator, ExportHelper):
         return {'FINISHED'}
 
 # UI
+bpy.types.Mesh.useFlatShading = BoolProperty(
+    name="Use Flat Shading", 
+    default = False)
+
 bpy.types.Mesh.checkCollisions = BoolProperty(
     name="Check Collisions", 
     default = False)
@@ -1023,10 +1069,11 @@ class ObjectPanel(bpy.types.Panel):
         isCamera = isinstance(ob.data, bpy.types.Camera)
         isLight = isinstance(ob.data, bpy.types.Lamp)
         
-        if isMesh:
+        if isMesh:   
+            layout.prop(ob.data, 'useFlatShading') 
             layout.prop(ob.data, 'checkCollisions')     
             layout.prop(ob.data, 'castShadows')     
-            layout.prop(ob.data, 'receiveShadows')      
+            layout.prop(ob.data, 'receiveShadows')   
         elif isCamera:
             layout.prop(ob.data, 'checkCollisions')
             layout.prop(ob.data, 'applyGravity')

+ 1 - 1
Exporters/XNA - OBJ/BabylonExport.Core/Entities/PositionNormalTexturedWeights.cs

@@ -6,7 +6,7 @@ namespace BabylonExport.Core
 {
     public struct PositionNormalTexturedWeights : IDumpable, IQueryable
     {
-        public const int Stride = 64;
+        public const int Stride = 52; // Maya returning >=52 for PNTW vertex, not 64
         public Vector3 Position;
         public int Indices;
         public Vector4 Weights;

+ 5 - 2
Tools/BuildOurOwnBabylonJS/BuildOurOwnBabylonJS/babylonJS.xml

@@ -24,7 +24,7 @@
   <script src="Babylon/Layer/babylon.layer.js"></script>
   <script src="Babylon/Sprites/babylon.sprite.js"></script>
   <script src="Babylon/Sprites/babylon.spriteManager.js"></script>
-  <script src="Babylon/Tools/babylon.sceneLoader.js"></script>
+  <script src="Babylon/Loading/babylon.sceneLoader.js"></script>
   <script src="Babylon/Tools/babylon.database.js"></script>
   <script src="Babylon/Materials/babylon.multiMaterial.js"></script>
   <script src="Babylon/Materials/babylon.standardMaterial.js"></script>
@@ -59,7 +59,10 @@
   <script src="Babylon/Culling/babylon.boundingBox.js"></script>
   <script src="Babylon/Culling/babylon.boundingSphere.js"></script>
   <script src="Babylon/babylon.engine.js"></script>
-  <script src="Babylon/Tools/babylon.tools.js"></script>
+  <script src="Babylon/Math/babylon.tools.js"></script>
   <script src="Babylon/Tools/babylon.math.js"></script>
   <script src="Babylon/babylon.node.js"></script>
+  <script src="Babylon/Tools/babylon.sceneSerializer.js"></script>
+  <script src="Babylon/Math/babylon.axis.js"></script>
+  <script src="Babylon/Loading/Plugins/babylon.babylonFileLoader.js"></script>
 </files>

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 22
babylon.1.8.5.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 22 - 0
babylon.1.9.0.js


+ 18 - 0
what's new.md

@@ -1,5 +1,23 @@
 Changes list
 ============
+- 1.9.0:
+ - **Major updates**
+ - Beta support for scene serialization with ```BABYLON.SceneSerializer.Serialize``` function ([deltakosh](http://www.github.com/deltakosh))
+ - Blender exporter now supports 32 bits indices ([deltakosh](http://www.github.com/deltakosh))
+ - Flat shading support (From Blender and with ```mesh.convertToFlatShadedMesh()``) ([deltakosh](http://www.github.com/deltakosh))
+ - **Updates**
+ - New ```mesh.rotate``` and ```mesh.translate``` functions to rotate and translate mesh both locally and globally ([deltakosh](http://www.github.com/deltakosh))
+ - New feature for particles: ```ParticleSystem.forceDepthWrite``` ([deltakosh](http://www.github.com/deltakosh))
+ - Adding a new parameter to pick in order to be able to pick even on multi views ([deltakosh](http://www.github.com/deltakosh))
+ - New ```mesh.lookAt``` function ([professorF](https://github.com/professorF))
+ - New postprocess system (independent from cameras) ([michael-korbas](https://github.com/michael-korbas))
+ - New ```mesh.setAbsolutePosition``` function ([gwenael-hagenmuller](https://github.com/gwenael-hagenmuller))
+ - **Bugfixes**
+ - Fixing issue with ```mesh.infiniteDistance``` ([deltakosh](http://www.github.com/deltakosh))
+ - Fixing issue with camera caches ([deltakosh](http://www.github.com/deltakosh))
+ - Fixing issue with aspect ratio ([deltakosh](http://www.github.com/deltakosh))
+ - Fixing arcRotateCamera angle limitations ([deltakosh](http://www.github.com/deltakosh))
+ - Fixing a bug with multi-views: depth buffer was not clear between different passes ([deltakosh](http://www.github.com/deltakosh))
 - 1.8.5:
  - **Major updates**
  - Visual Studio 2013 templates for Windows 8.1 and nuget packages ([pierlag](http://www.github.com/pierlag))