Pārlūkot izejas kodu

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

Gwenaël Hagenmuller 11 gadi atpakaļ
vecāks
revīzija
e92d473d05

+ 2 - 2
Babylon/Cameras/Controllers/babylon.inputCollisionFilter.js

@@ -8,7 +8,7 @@ var BABYLON = BABYLON || {};
 		this._transformedDirection = new BABYLON.Vector3();
 		this._tempNewPosition = new BABYLON.Vector3();
 		this._tempNewPosition2 = new BABYLON.Vector3();
-		this._ellipsoid = ellipsoid || new BABYLON.Vector3(.5,.5,.5);
+		this._ellipsoid = ellipsoid || new BABYLON.Vector3(.2,.855,.2);
 		this._collider = new BABYLON.Collider();
 		this._collidedPosition = new BABYLON.Vector3(0, 0, 0);
 		this._cameraHeight = 1.7;
@@ -31,7 +31,7 @@ var BABYLON = BABYLON || {};
 
 
 		this._collidedPosition.subtractToRef(this._positionBottom, this._tempNewPosition2);
-		if (this._tempNewPosition2.length() > BABYLON.Engine.collisionsEpsilon * 5) {
+		if (this._tempNewPosition2.length() > BABYLON.Engine.collisionsEpsilon * 2) {
 
 		    BABYLON.Vector3.TransformNormalToRef(this._tempNewPosition2, this.getInvertOrientationMatrix(), this._tempNewPosition);
 		    this.target.moveRelative(this._tempNewPosition);

+ 1 - 1
Babylon/Cameras/babylon.camera.js

@@ -325,4 +325,4 @@ var BABYLON = BABYLON || {};
             this._postProcesses[this._postProcessesTakenIndices[i]].dispose(this);
         }
     };
-})();
+})();

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

@@ -72,10 +72,12 @@ var BABYLON = BABYLON || {};
             this._cache.lockedTarget = null;
         }
         else {
-            if (!this._cache.lockedTarget)
+            if (!this._cache.lockedTarget) {
                 this._cache.lockedTarget = lockedTargetPosition.clone();
-            else
+            }
+            else {
                 this._cache.lockedTarget.copyFrom(lockedTargetPosition);
+            }
         }
 
         this._cache.rotation.copyFrom(this.rotation);

+ 4 - 3
Babylon/Cameras/babylon.oculusOrientedCamera.js

@@ -35,8 +35,9 @@ var BABYLON = BABYLON || {};
         this.resetViewMatrix();
     };
     
-    BABYLON.OculusOrientedCamera.BuildOculusStereoCamera = function (scene, name, canvas, minZ, maxZ, position, neutralOrientation, useFXAA, disableGravity,disableCollisions, ovrSettings) {
-        position = position || new BABYLON.Vector2(0, 0);
+    BABYLON.OculusOrientedCamera.BuildOculusStereoCamera = function (scene, name, minZ, maxZ, position, neutralOrientation, useFXAA, disableGravity, disableCollisions, collisionEllipsoid, ovrSettings) {
+        var canvas = scene.getEngine().getRenderingCanvas();
+        position = position || BABYLON.Vector3.Zero(0, 0, 0);
         neutralOrientation = neutralOrientation || { yaw: 0.0, pitch: 0.0, roll: 0.0 };
         //var controller =  new BABYLON.OculusController();
         ovrSettings = ovrSettings || BABYLON.OculusController.CameraSettings_OculusRiftDevKit2013_Metric;
@@ -63,7 +64,7 @@ var BABYLON = BABYLON || {};
         var controller = new BABYLON.OculusController(scene, multiTarget);
         var moveTarget = multiTarget;
         if (!disableCollisions) {
-            var collisionFilter = new BABYLON.InputCollisionFilter(scene, multiTarget);
+            var collisionFilter = new BABYLON.InputCollisionFilter(scene, multiTarget, collisionEllipsoid);
             moveTarget = collisionFilter;
         }
         if (!disableGravity) {

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

@@ -14,12 +14,20 @@ var BABYLON = BABYLON || {};
         this._compilationError = "";
         this._attributesNames = attributesNames;
 
-        var vertex = baseName.vertex || baseName;
-        var fragment = baseName.fragment || baseName;
+        var vertexSource;
+        var fragmentSource;
+
+        if (baseName.vertexElement) {
+            vertexSource = document.getElementById(baseName.vertexElement);
+            fragmentSource = document.getElementById(baseName.fragmentElement);
+        } else {
+            vertexSource = baseName.vertexElement || baseName.vertex || baseName;
+            fragmentSource = baseName.fragmentElement || baseName.fragment || baseName;
+        }
 
         var that = this;
-        this._loadVertexShader(vertex, function (vertexCode) {
-            that._loadFragmentShader(fragment, function (fragmentCode) {
+        this._loadVertexShader(vertexSource, function (vertexCode) {
+            that._loadFragmentShader(fragmentSource, function (fragmentCode) {
                 that._prepareEffect(vertexCode, fragmentCode, attributesNames, defines, optionalDefines);
             });
         });   
@@ -67,6 +75,13 @@ var BABYLON = BABYLON || {};
 
     // Methods
     BABYLON.Effect.prototype._loadVertexShader = function (vertex, callback) {
+        // DOM element ?
+        if (vertex instanceof HTMLElement) {
+            var vertexCode = BABYLON.Tools.GetDOMTextContent(vertex);
+            callback(vertexCode);
+            return;
+        }
+
         // Is in local store ?
         if (BABYLON.Effect.ShadersStore[vertex + "VertexShader"]) {
             callback(BABYLON.Effect.ShadersStore[vertex + "VertexShader"]);
@@ -86,6 +101,13 @@ var BABYLON = BABYLON || {};
     };
 
     BABYLON.Effect.prototype._loadFragmentShader = function (fragment, callback) {
+        // DOM element ?
+        if (fragment instanceof HTMLElement) {
+            var fragmentCode = BABYLON.Tools.GetDOMTextContent(fragment);
+            callback(fragmentCode);
+            return;
+        }
+
         // Is in local store ?
         if (BABYLON.Effect.ShadersStore[fragment + "PixelShader"]) {
             callback(BABYLON.Effect.ShadersStore[fragment + "PixelShader"]);
@@ -196,10 +218,14 @@ var BABYLON = BABYLON || {};
     
     BABYLON.Effect.prototype.setArray = function (uniformName, array) {
         this._engine.setArray(this.getUniform(uniformName), array);
+
+        return this;
     };
 
     BABYLON.Effect.prototype.setMatrices = function (uniformName, matrices) {
         this._engine.setMatrices(this.getUniform(uniformName), matrices);
+
+        return this;
     };
 
     BABYLON.Effect.prototype.setMatrix = function (uniformName, matrix) {
@@ -208,81 +234,101 @@ var BABYLON = BABYLON || {};
 
         //this._cacheMatrix(uniformName, matrix);
         this._engine.setMatrix(this.getUniform(uniformName), matrix);
+
+        return this;
     };
 
     BABYLON.Effect.prototype.setFloat = function (uniformName, value) {
         if (this._valueCache[uniformName] && this._valueCache[uniformName] === value)
-            return;
+            return this;
 
         this._valueCache[uniformName] = value;
 
         this._engine.setFloat(this.getUniform(uniformName), value);
+
+        return this;
     };
 
     BABYLON.Effect.prototype.setBool = function (uniformName, bool) {
         if (this._valueCache[uniformName] && this._valueCache[uniformName] === bool)
-            return;
+            return this;
 
         this._valueCache[uniformName] = bool;
 
         this._engine.setBool(this.getUniform(uniformName), bool);
+
+        return this;
     };
     
     BABYLON.Effect.prototype.setVector2 = function (uniformName, vector2) {
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == vector2.x && this._valueCache[uniformName][1] == vector2.y)
-            return;
+            return this;
 
         this._cacheFloat2(uniformName, vector2.x, vector2.y);
         this._engine.setFloat2(this.getUniform(uniformName), vector2.x, vector2.y);
+
+        return this;
     };
 
     BABYLON.Effect.prototype.setFloat2 = function (uniformName, x, y) {
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == x && this._valueCache[uniformName][1] == y)
-            return;
+            return this;
 
         this._cacheFloat2(uniformName, x, y);
         this._engine.setFloat2(this.getUniform(uniformName), x, y);
+
+        return this;
     };
     
     BABYLON.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)
-            return;
+            return this;
 
         this._cacheFloat3(uniformName, vector3.x, vector3.y, vector3.z);
 
         this._engine.setFloat3(this.getUniform(uniformName), vector3.x, vector3.y, vector3.z);
+
+        return this;
     };
 
     BABYLON.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)
-            return;
+            return this;
 
         this._cacheFloat3(uniformName, x, y, z);
         this._engine.setFloat3(this.getUniform(uniformName), x, y, z);
+
+        return this;
     };
 
     BABYLON.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)
-            return;
+            return this;
 
         this._cacheFloat4(uniformName, x, y, z, w);
         this._engine.setFloat4(this.getUniform(uniformName), x, y, z, w);
+
+        return this;
     };
 
     BABYLON.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)
-            return;
+            return this;
 
         this._cacheFloat3(uniformName, color3.r, color3.g, color3.b);
         this._engine.setColor3(this.getUniform(uniformName), color3);
+
+        return this;
     };
 
     BABYLON.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)
-            return;
+            return this;
 
         this._cacheFloat4(uniformName, color3.r, color3.g, color3.b, alpha);
         this._engine.setColor4(this.getUniform(uniformName), color3, alpha);
+
+        return this;
     };
 
     // Statics

+ 202 - 0
Babylon/Materials/babylon.shaderMaterial.js

@@ -0,0 +1,202 @@
+"use strict";
+
+var BABYLON = BABYLON || {};
+
+(function () {
+    BABYLON.ShaderMaterial = function (name, scene, shaderPath, options) {
+        this.name = name;
+        this.id = name;
+        this._shaderPath = shaderPath;
+
+        options.needAlphaBlending = options.needAlphaBlending || false;
+        options.needAlphaTesting = options.needAlphaTesting || false;
+        options.attributes = options.attributes || ["position", "normal", "uv"];
+        options.uniforms = options.uniforms || ["worldViewProjection"];
+        options.samplers = options.samplers || [];
+        
+        this._options = options;
+        this._scene = scene;
+        scene.materials.push(this);
+
+        this._textures = [];
+        this._floats = [];
+        this._floatsArrays = [];
+        this._colors3 = [];
+        this._colors4 = [];
+        this._vectors2 = [];
+        this._vectors3 = [];
+        this._vectors4 = [];
+        this._matrices = [];
+    };
+
+    BABYLON.ShaderMaterial.prototype = Object.create(BABYLON.Material.prototype);
+
+    // Properties   
+    BABYLON.ShaderMaterial.prototype.needAlphaBlending = function () {
+        return this._options.needAlphaBlending;
+    };
+
+    BABYLON.ShaderMaterial.prototype.needAlphaTesting = function () {
+        return this._options.needAlphaTesting;
+    };
+
+    // Methods   
+    BABYLON.ShaderMaterial.prototype._checkUniform = function (uniformName) {
+        if (this._options.uniforms.indexOf(uniformName) === -1) {
+            this._options.uniforms.push(uniformName);
+        }
+    };
+
+    BABYLON.ShaderMaterial.prototype.setTexture = function (name, texture) {
+        this._checkUniform(name);
+        this._textures[name] = texture;
+
+        return this;
+    };
+
+    BABYLON.ShaderMaterial.prototype.setFloat = function (name, value) {
+        this._checkUniform(name);
+        this._floats[name] = value;
+
+        return this;
+    };
+
+    BABYLON.ShaderMaterial.prototype.setFloats = function (name, value) {
+        this._checkUniform(name);
+        this._floatsArrays[name] = value;
+
+        return this;
+    };
+
+    BABYLON.ShaderMaterial.prototype.setColor3 = function (name, value) {
+        this._checkUniform(name);
+        this._colors3[name] = value;
+
+        return this;
+    };
+
+    BABYLON.ShaderMaterial.prototype.setColor4 = function (name, value) {
+        this._checkUniform(name);
+        this._colors4[name] = value;
+
+        return this;
+    };
+
+    BABYLON.ShaderMaterial.prototype.setVector2 = function (name, value) {
+        this._checkUniform(name);
+        this._vectors2[name] = value;
+
+        return this;
+    };
+
+    BABYLON.ShaderMaterial.prototype.setVector3 = function (name, value) {
+        this._checkUniform(name);
+        this._vectors3[name] = value;
+
+        return this;
+    };
+
+    BABYLON.ShaderMaterial.prototype.setVector4 = function (name, value) {
+        this._checkUniform(name);
+        this._vectors4[name] = value;
+
+        return this;
+    };
+
+    BABYLON.ShaderMaterial.prototype.setMatrix = function (name, value) {
+        this._checkUniform(name);
+        this._matrices[name] = value;
+
+        return this;
+    };
+
+    BABYLON.ShaderMaterial.prototype.isReady = function (mesh) {
+        var engine = this._scene.getEngine();
+
+        this._effect = engine.createEffect(this._shaderPath,
+            this._options.attributes,
+            this._options.uniforms,
+            this._options.samplers,
+            "");
+
+        if (!this._effect.isReady()) {
+            return false;
+        }
+
+        return true;
+    };
+
+    BABYLON.ShaderMaterial.prototype.bind = function (world, mesh) {
+        // 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._scene.getViewMatrix());
+        }
+
+        if (this._options.uniforms.indexOf("projection") !== -1) {
+            this._effect.setMatrix("projection", this._scene.getProjectionMatrix());
+        }
+
+        if (this._options.uniforms.indexOf("worldViewProjection") !== -1) {
+            this._effect.setMatrix("worldViewProjection", world.multiply(this._scene.getTransformMatrix()));
+        }        
+
+        // Texture
+        for (var name in this._textures) {
+            this._effect.setTexture(name, this._textures[name]);
+        }
+
+        // Float    
+        for (name in this._floats) {            
+            this._effect.setFloat(name, this._floats[name]);
+        }
+
+        // Float s   
+        for (name in this._floatsArrays) {
+            this._effect.setArray(name, this._floatsArrays[name]);
+        }
+
+        // Color3        
+        for (name in this._colors3) {
+            this._effect.setColor3(name, this._colors3[name]);
+        }
+
+        // Color4      
+        for (name in this._colors4) {
+            this._effect.setColor4(name, this._colors4[name]);
+        }
+
+        // Vector2        
+        for (name in this._vectors2) {
+            this._effect.setVector2(name, this._vectors2[name]);
+        }
+
+        // Vector3        
+        for (name in this._vectors3) {
+            this._effect.setVector3(name, this._vectors3[name]);
+        }
+
+        // Vector4      
+        for (name in this._vectors4) {
+            this._effect.setVector4(name, this._vectors4[name]);
+        }
+
+        // Matrix      
+        for (name in this._matrices) {
+            this._effect.setMatrix(name, this._matrices[name]);
+        }
+    };
+
+    BABYLON.ShaderMaterial.prototype.dispose = function () {
+        for (var name in this._textures) {
+            this._textures[name].dispose();
+        }
+
+        this._textures = [];
+        
+        this.baseDispose();
+    };
+})();

+ 3 - 3
Babylon/Mesh/babylon.csg.js

@@ -7,7 +7,7 @@ var BABYLON = BABYLON || {};
 (function () {
 
     // Unique ID when we import meshes from Babylon to CSG
-    var _currentCSGMeshId = 0;
+    var currentCSGMeshId = 0;
 
     BABYLON.CSG = function () {
         this.polygons = [];
@@ -51,7 +51,7 @@ var BABYLON = BABYLON || {};
                     vertices.push(vertex);
                 }
 
-                polygon = new BABYLON.CSG.Polygon(vertices, { subMeshId: sm, meshId: _currentCSGMeshId, materialIndex: subMeshes[sm].materialIndex });
+                polygon = new BABYLON.CSG.Polygon(vertices, { subMeshId: sm, meshId: currentCSGMeshId, materialIndex: subMeshes[sm].materialIndex });
 
                 // To handle the case of degenerated triangle
                 // polygon.plane == null <=> the polygon does not represent 1 single plane <=> the triangle is degenerated
@@ -62,7 +62,7 @@ var BABYLON = BABYLON || {};
 
         var csg = BABYLON.CSG.fromPolygons(polygons);
         csg.copyTransformAttributes(this);
-        _currentCSGMeshId++;
+        currentCSGMeshId++;
 
         return csg;
     };

+ 14 - 331
Babylon/Mesh/babylon.mesh.js

@@ -1100,231 +1100,28 @@ var BABYLON = BABYLON || {};
     // Statics
     BABYLON.Mesh.CreateBox = function (name, size, scene, updatable) {
         var box = new BABYLON.Mesh(name, scene);
+        var vertexData = BABYLON.VertexData.CreateBox(size);
 
-        var normalsSource = [
-            new BABYLON.Vector3(0, 0, 1),
-            new BABYLON.Vector3(0, 0, -1),
-            new BABYLON.Vector3(1, 0, 0),
-            new BABYLON.Vector3(-1, 0, 0),
-            new BABYLON.Vector3(0, 1, 0),
-            new BABYLON.Vector3(0, -1, 0)
-        ];
-
-        var indices = [];
-        var positions = [];
-        var normals = [];
-        var uvs = [];
-
-        // Create each face in turn.
-        for (var index = 0; index < normalsSource.length; index++) {
-            var normal = normalsSource[index];
-
-            // Get two vectors perpendicular to the face normal and to each other.
-            var side1 = new BABYLON.Vector3(normal.y, normal.z, normal.x);
-            var side2 = BABYLON.Vector3.Cross(normal, side1);
-
-            // Six indices (two triangles) per face.
-            var verticesLength = positions.length / 3;
-            indices.push(verticesLength);
-            indices.push(verticesLength + 1);
-            indices.push(verticesLength + 2);
-
-            indices.push(verticesLength);
-            indices.push(verticesLength + 2);
-            indices.push(verticesLength + 3);
-
-            // Four vertices per face.
-            var vertex = normal.subtract(side1).subtract(side2).scale(size / 2);
-            positions.push(vertex.x, vertex.y, vertex.z);
-            normals.push(normal.x, normal.y, normal.z);
-            uvs.push(1.0, 1.0);
-
-            vertex = normal.subtract(side1).add(side2).scale(size / 2);
-            positions.push(vertex.x, vertex.y, vertex.z);
-            normals.push(normal.x, normal.y, normal.z);
-            uvs.push(0.0, 1.0);
-
-            vertex = normal.add(side1).add(side2).scale(size / 2);
-            positions.push(vertex.x, vertex.y, vertex.z);
-            normals.push(normal.x, normal.y, normal.z);
-            uvs.push(0.0, 0.0);
-
-            vertex = normal.add(side1).subtract(side2).scale(size / 2);
-            positions.push(vertex.x, vertex.y, vertex.z);
-            normals.push(normal.x, normal.y, normal.z);
-            uvs.push(1.0, 0.0);
-        }
-
-        box.setVerticesData(positions, BABYLON.VertexBuffer.PositionKind, updatable);
-        box.setVerticesData(normals, BABYLON.VertexBuffer.NormalKind, updatable);
-        box.setVerticesData(uvs, BABYLON.VertexBuffer.UVKind, updatable);
-        box.setIndices(indices);
+        vertexData.applyToMesh(box, updatable);
 
         return box;
     };
 
     BABYLON.Mesh.CreateSphere = function (name, segments, diameter, scene, updatable) {
         var sphere = new BABYLON.Mesh(name, scene);
+        var vertexData = BABYLON.VertexData.CreateSphere(segments, diameter);
 
-        var radius = diameter / 2;
-
-        var totalZRotationSteps = 2 + segments;
-        var totalYRotationSteps = 2 * totalZRotationSteps;
-
-        var indices = [];
-        var positions = [];
-        var normals = [];
-        var uvs = [];
-
-        for (var zRotationStep = 0; zRotationStep <= totalZRotationSteps; zRotationStep++) {
-            var normalizedZ = zRotationStep / totalZRotationSteps;
-            var angleZ = (normalizedZ * Math.PI);
-
-            for (var yRotationStep = 0; yRotationStep <= totalYRotationSteps; yRotationStep++) {
-                var normalizedY = yRotationStep / totalYRotationSteps;
-
-                var angleY = normalizedY * Math.PI * 2;
-
-                var rotationZ = BABYLON.Matrix.RotationZ(-angleZ);
-                var rotationY = BABYLON.Matrix.RotationY(angleY);
-                var afterRotZ = BABYLON.Vector3.TransformCoordinates(BABYLON.Vector3.Up(), rotationZ);
-                var complete = BABYLON.Vector3.TransformCoordinates(afterRotZ, rotationY);
-
-                var vertex = complete.scale(radius);
-                var normal = BABYLON.Vector3.Normalize(vertex);
-
-                positions.push(vertex.x, vertex.y, vertex.z);
-                normals.push(normal.x, normal.y, normal.z);
-                uvs.push(normalizedZ, normalizedY);
-            }
-
-            if (zRotationStep > 0) {
-                var verticesCount = positions.length / 3;
-                for (var firstIndex = verticesCount - 2 * (totalYRotationSteps + 1) ; (firstIndex + totalYRotationSteps + 2) < verticesCount; firstIndex++) {
-                    indices.push((firstIndex));
-                    indices.push((firstIndex + 1));
-                    indices.push(firstIndex + totalYRotationSteps + 1);
-
-                    indices.push((firstIndex + totalYRotationSteps + 1));
-                    indices.push((firstIndex + 1));
-                    indices.push((firstIndex + totalYRotationSteps + 2));
-                }
-            }
-        }
-
-        sphere.setVerticesData(positions, BABYLON.VertexBuffer.PositionKind, updatable);
-        sphere.setVerticesData(normals, BABYLON.VertexBuffer.NormalKind, updatable);
-        sphere.setVerticesData(uvs, BABYLON.VertexBuffer.UVKind, updatable);
-        sphere.setIndices(indices);
+        vertexData.applyToMesh(sphere, updatable);
 
         return sphere;
     };
 
     // Cylinder and cone (Code inspired by SharpDX.org)
     BABYLON.Mesh.CreateCylinder = function (name, height, diameterTop, diameterBottom, tessellation, scene, updatable) {
-        var radiusTop = diameterTop / 2;
-        var radiusBottom = diameterBottom / 2;
-        var indices = [];
-        var positions = [];
-        var normals = [];
-        var uvs = [];
-        var cylinder = new BABYLON.Mesh(name, scene);
-
-        var getCircleVector = function (i) {
-            var angle = (i * 2.0 * Math.PI / tessellation);
-            var dx = Math.sin(angle);
-            var dz = Math.cos(angle);
-
-            return new BABYLON.Vector3(dx, 0, dz);
-        };
-
-        var createCylinderCap = function (isTop) {
-            var radius = isTop ? radiusTop : radiusBottom;
-
-            if (radius == 0) {
-                return;
-            }
-
-            // Create cap indices.
-            for (var i = 0; i < tessellation - 2; i++) {
-                var i1 = (i + 1) % tessellation;
-                var i2 = (i + 2) % tessellation;
-
-                if (!isTop) {
-                    var tmp = i1;
-                    var i1 = i2;
-                    i2 = tmp;
-                }
-
-                var vbase = positions.length / 3;
-                indices.push(vbase);
-                indices.push(vbase + i1);
-                indices.push(vbase + i2);
-            }
-
-
-            // Which end of the cylinder is this?
-            var normal = new BABYLON.Vector3(0, -1, 0);
-            var textureScale = new BABYLON.Vector2(-0.5, -0.5);
-
-            if (!isTop) {
-                normal = normal.scale(-1);
-                textureScale.x = -textureScale.x;
-            }
-
-            // Create cap vertices.
-            for (var i = 0; i < tessellation; i++) {
-                var circleVector = getCircleVector(i);
-                var position = circleVector.scale(radius).add(normal.scale(height));
-                var textureCoordinate = new BABYLON.Vector2(circleVector.x * textureScale.x + 0.5, circleVector.z * textureScale.y + 0.5);
-
-                positions.push(position.x, position.y, position.z);
-                normals.push(normal.x, normal.y, normal.z);
-                uvs.push(textureCoordinate.x, textureCoordinate.y);
-            }
-        };
-
-        height /= 2;
-
-        var topOffset = new BABYLON.Vector3(0, 1, 0).scale(height);
-
-        var stride = tessellation + 1;
-
-        // Create a ring of triangles around the outside of the cylinder.
-        for (var i = 0; i <= tessellation; i++) {
-            var normal = getCircleVector(i);
-            var sideOffsetBottom = normal.scale(radiusBottom);
-            var sideOffsetTop = normal.scale(radiusTop);
-            var textureCoordinate = new BABYLON.Vector2(i / tessellation, 0);
-
-            var position = sideOffsetBottom.add(topOffset);
-            positions.push(position.x, position.y, position.z);
-            normals.push(normal.x, normal.y, normal.z);
-            uvs.push(textureCoordinate.x, textureCoordinate.y);
-
-            position = sideOffsetTop.subtract(topOffset);
-            textureCoordinate.y += 1;
-            positions.push(position.x, position.y, position.z);
-            normals.push(normal.x, normal.y, normal.z);
-            uvs.push(textureCoordinate.x, textureCoordinate.y);
-
-            indices.push(i * 2);
-            indices.push((i * 2 + 2) % (stride * 2));
-            indices.push(i * 2 + 1);
-
-            indices.push(i * 2 + 1);
-            indices.push((i * 2 + 2) % (stride * 2));
-            indices.push((i * 2 + 3) % (stride * 2));
-        }
-
-        // Create flat triangle fan caps to seal the top and bottom.
-        createCylinderCap(true);
-        createCylinderCap(false);
+        var cylinder = new BABYLON.Mesh(name, scene);        
+        var vertexData = BABYLON.VertexData.CreateCylinder(height, diameterTop, diameterBottom, tessellation);
 
-        cylinder.setVerticesData(positions, BABYLON.VertexBuffer.PositionKind, updatable);
-        cylinder.setVerticesData(normals, BABYLON.VertexBuffer.NormalKind, updatable);
-        cylinder.setVerticesData(uvs, BABYLON.VertexBuffer.UVKind, updatable);
-        cylinder.setIndices(indices);
+        vertexData.applyToMesh(cylinder, updatable);
 
         return cylinder;
     };
@@ -1332,142 +1129,28 @@ var BABYLON = BABYLON || {};
     // Torus  (Code from SharpDX.org)
     BABYLON.Mesh.CreateTorus = function (name, diameter, thickness, tessellation, scene, updatable) {
         var torus = new BABYLON.Mesh(name, scene);
+        var vertexData = BABYLON.VertexData.CreateTorus(diameter, thickness, tessellation);
 
-        var indices = [];
-        var positions = [];
-        var normals = [];
-        var uvs = [];
-
-        var stride = tessellation + 1;
-
-        for (var i = 0; i <= tessellation; i++) {
-            var u = i / tessellation;
-
-            var outerAngle = i * Math.PI * 2.0 / tessellation - Math.PI / 2.0;
-
-            var transform = BABYLON.Matrix.Translation(diameter / 2.0, 0, 0).multiply(BABYLON.Matrix.RotationY(outerAngle));
-
-            for (var j = 0; j <= tessellation; j++) {
-                var v = 1 - j / tessellation;
-
-                var innerAngle = j * Math.PI * 2.0 / tessellation + Math.PI;
-                var dx = Math.cos(innerAngle);
-                var dy = Math.sin(innerAngle);
-
-                // Create a vertex.
-                var normal = new BABYLON.Vector3(dx, dy, 0);
-                var position = normal.scale(thickness / 2);
-                var textureCoordinate = new BABYLON.Vector2(u, v);
-
-                position = BABYLON.Vector3.TransformCoordinates(position, transform);
-                normal = BABYLON.Vector3.TransformNormal(normal, transform);
-
-                positions.push(position.x, position.y, position.z);
-                normals.push(normal.x, normal.y, normal.z);
-                uvs.push(textureCoordinate.x, textureCoordinate.y);
-
-                // And create indices for two triangles.
-                var nextI = (i + 1) % stride;
-                var nextJ = (j + 1) % stride;
-
-                indices.push(i * stride + j);
-                indices.push(i * stride + nextJ);
-                indices.push(nextI * stride + j);
-
-                indices.push(i * stride + nextJ);
-                indices.push(nextI * stride + nextJ);
-                indices.push(nextI * stride + j);
-            }
-        }
-
-        torus.setVerticesData(positions, BABYLON.VertexBuffer.PositionKind, updatable);
-        torus.setVerticesData(normals, BABYLON.VertexBuffer.NormalKind, updatable);
-        torus.setVerticesData(uvs, BABYLON.VertexBuffer.UVKind, updatable);
-        torus.setIndices(indices);
+        vertexData.applyToMesh(torus, updatable);
 
         return torus;
     };
 
-    // Plane
+    // Plane & ground
     BABYLON.Mesh.CreatePlane = function (name, size, scene, updatable) {
         var plane = new BABYLON.Mesh(name, scene);
+        var vertexData = BABYLON.VertexData.CreatePlane(size);
 
-        var indices = [];
-        var positions = [];
-        var normals = [];
-        var uvs = [];
-
-        // Vertices
-        var halfSize = size / 2.0;
-        positions.push(-halfSize, -halfSize, 0);
-        normals.push(0, 0, -1.0);
-        uvs.push(0.0, 0.0);
-
-        positions.push(halfSize, -halfSize, 0);
-        normals.push(0, 0, -1.0);
-        uvs.push(1.0, 0.0);
-
-        positions.push(halfSize, halfSize, 0);
-        normals.push(0, 0, -1.0);
-        uvs.push(1.0, 1.0);
-
-        positions.push(-halfSize, halfSize, 0);
-        normals.push(0, 0, -1.0);
-        uvs.push(0.0, 1.0);
-
-        // Indices
-        indices.push(0);
-        indices.push(1);
-        indices.push(2);
-
-        indices.push(0);
-        indices.push(2);
-        indices.push(3);
-
-        plane.setVerticesData(positions, BABYLON.VertexBuffer.PositionKind, updatable);
-        plane.setVerticesData(normals, BABYLON.VertexBuffer.NormalKind, updatable);
-        plane.setVerticesData(uvs, BABYLON.VertexBuffer.UVKind, updatable);
-        plane.setIndices(indices);
+        vertexData.applyToMesh(plane, updatable);
 
         return plane;
     };
 
     BABYLON.Mesh.CreateGround = function (name, width, height, subdivisions, scene, updatable) {
         var ground = new BABYLON.Mesh(name, scene);
+        var vertexData = BABYLON.VertexData.CreateGround(width, height, subdivisions);
 
-        var indices = [];
-        var positions = [];
-        var normals = [];
-        var uvs = [];
-        var row, col;
-
-        for (row = 0; row <= subdivisions; row++) {
-            for (col = 0; col <= subdivisions; col++) {
-                var position = new BABYLON.Vector3((col * width) / subdivisions - (width / 2.0), 0, ((subdivisions - row) * height) / subdivisions - (height / 2.0));
-                var normal = new BABYLON.Vector3(0, 1.0, 0);
-
-                positions.push(position.x, position.y, position.z);
-                normals.push(normal.x, normal.y, normal.z);
-                uvs.push(col / subdivisions, 1.0 - row / subdivisions);
-            }
-        }
-
-        for (row = 0; row < subdivisions; row++) {
-            for (col = 0; col < subdivisions; col++) {
-                indices.push(col + 1 + (row + 1) * (subdivisions + 1));
-                indices.push(col + 1 + row * (subdivisions + 1));
-                indices.push(col + row * (subdivisions + 1));
-
-                indices.push(col + (row + 1) * (subdivisions + 1));
-                indices.push(col + 1 + (row + 1) * (subdivisions + 1));
-                indices.push(col + row * (subdivisions + 1));
-            }
-        }
-
-        ground.setVerticesData(positions, BABYLON.VertexBuffer.PositionKind, updatable);
-        ground.setVerticesData(normals, BABYLON.VertexBuffer.NormalKind, updatable);
-        ground.setVerticesData(uvs, BABYLON.VertexBuffer.UVKind, updatable);
-        ground.setIndices(indices);
+        vertexData.applyToMesh(ground, updatable);
 
         return ground;
     };

+ 477 - 0
Babylon/Mesh/babylon.mesh.vertexData.js

@@ -0,0 +1,477 @@
+"use strict";
+
+var BABYLON = BABYLON || {};
+
+(function () {
+    BABYLON.VertexData = function () {
+    };
+
+    // Methods
+    BABYLON.VertexData.prototype.applyToMesh = function(mesh, updatable) {
+        if (this.positions) {
+            mesh.setVerticesData(this.positions, BABYLON.VertexBuffer.PositionKind, updatable);
+        }
+
+        if (this.normals) {
+            mesh.setVerticesData(this.normals, BABYLON.VertexBuffer.NormalKind, updatable);
+        }
+
+        if (this.uvs) {
+            mesh.setVerticesData(this.uvs, BABYLON.VertexBuffer.UVKind, updatable);
+        }
+
+        if (this.indices) {
+            mesh.setIndices(this.indices);
+        }
+    };
+
+    BABYLON.VertexData.prototype.transform = function (matrix) {
+        var transformed = BABYLON.Vector3.Zero();
+
+        if (this.positions) {
+            var position = BABYLON.Vector3.Zero();
+
+            for (var index = 0; index < this.positions.length; index += 3) {
+                BABYLON.Vector3.FromArrayToRef(this.positions, index, position);
+
+                BABYLON.Vector3.TransformCoordinatesToRef(position, matrix, transformed);
+                this.positions[index] = transformed.x;
+                this.positions[index + 1] = transformed.y;
+                this.positions[index + 2] = transformed.z;
+            }
+        }
+
+        if (this.normals) {
+            var normal = BABYLON.Vector3.Zero();
+
+            for (index = 0; index < this.normals.length; index += 3) {
+                BABYLON.Vector3.FromArrayToRef(this.normals, index, normal);
+
+                BABYLON.Vector3.TransformNormalToRef(normal, matrix, transformed);
+                this.normals[index] = transformed.x;
+                this.normals[index + 1] = transformed.y;
+                this.normals[index + 2] = transformed.z;
+            }
+        }
+    };
+
+    BABYLON.VertexData.prototype.merge = function (other) {
+        if (other.indices) {
+            if (!this.indices) {
+                this.indices = [];
+            }
+
+            var offset = this.positions ? this.positions.length / 3 : 0;
+            for (var index = 0; index < other.indices.length; index++) {
+                this.indices.push(other.indices[index] + offset);
+            }
+        }
+
+        if (other.positions) {
+            if (!this.positions) {
+                this.positions = [];
+            }
+
+            for (index = 0; index < other.positions.length; index++) {
+                this.positions.push(other.positions[index]);
+            }
+        }
+
+        if (other.normals) {
+            if (!this.normals) {
+                this.normals = [];
+            }
+            for (index = 0; index < other.normals.length; index++) {
+                this.normals.push(other.normals[index]);
+            }
+        }
+
+        if (other.uvs) {
+            if (!this.uvs) {
+                this.uvs = [];
+            }
+            for (index = 0; index < other.uvs.length; index++) {
+                this.uvs.push(other.uvs[index]);
+            }
+        }
+    };
+
+    // Statics
+    BABYLON.VertexData.CreateBox = function(size) {
+        var normalsSource = [
+            new BABYLON.Vector3(0, 0, 1),
+            new BABYLON.Vector3(0, 0, -1),
+            new BABYLON.Vector3(1, 0, 0),
+            new BABYLON.Vector3(-1, 0, 0),
+            new BABYLON.Vector3(0, 1, 0),
+            new BABYLON.Vector3(0, -1, 0)
+        ];
+
+        var indices = [];
+        var positions = [];
+        var normals = [];
+        var uvs = [];
+
+        // Create each face in turn.
+        for (var index = 0; index < normalsSource.length; index++) {
+            var normal = normalsSource[index];
+
+            // Get two vectors perpendicular to the face normal and to each other.
+            var side1 = new BABYLON.Vector3(normal.y, normal.z, normal.x);
+            var side2 = BABYLON.Vector3.Cross(normal, side1);
+
+            // Six indices (two triangles) per face.
+            var verticesLength = positions.length / 3;
+            indices.push(verticesLength);
+            indices.push(verticesLength + 1);
+            indices.push(verticesLength + 2);
+
+            indices.push(verticesLength);
+            indices.push(verticesLength + 2);
+            indices.push(verticesLength + 3);
+
+            // Four vertices per face.
+            var vertex = normal.subtract(side1).subtract(side2).scale(size / 2);
+            positions.push(vertex.x, vertex.y, vertex.z);
+            normals.push(normal.x, normal.y, normal.z);
+            uvs.push(1.0, 1.0);
+
+            vertex = normal.subtract(side1).add(side2).scale(size / 2);
+            positions.push(vertex.x, vertex.y, vertex.z);
+            normals.push(normal.x, normal.y, normal.z);
+            uvs.push(0.0, 1.0);
+
+            vertex = normal.add(side1).add(side2).scale(size / 2);
+            positions.push(vertex.x, vertex.y, vertex.z);
+            normals.push(normal.x, normal.y, normal.z);
+            uvs.push(0.0, 0.0);
+
+            vertex = normal.add(side1).subtract(side2).scale(size / 2);
+            positions.push(vertex.x, vertex.y, vertex.z);
+            normals.push(normal.x, normal.y, normal.z);
+            uvs.push(1.0, 0.0);
+        }
+
+        // Result
+        var vertexData = new BABYLON.VertexData();
+
+        vertexData.indices = indices;
+        vertexData.positions = positions;
+        vertexData.normals = normals;
+        vertexData.uvs = uvs;
+
+        return vertexData;
+    };
+
+    BABYLON.VertexData.CreateSphere = function (segments, diameter) {
+        var radius = diameter / 2;
+
+        var totalZRotationSteps = 2 + segments;
+        var totalYRotationSteps = 2 * totalZRotationSteps;
+
+        var indices = [];
+        var positions = [];
+        var normals = [];
+        var uvs = [];
+
+        for (var zRotationStep = 0; zRotationStep <= totalZRotationSteps; zRotationStep++) {
+            var normalizedZ = zRotationStep / totalZRotationSteps;
+            var angleZ = (normalizedZ * Math.PI);
+
+            for (var yRotationStep = 0; yRotationStep <= totalYRotationSteps; yRotationStep++) {
+                var normalizedY = yRotationStep / totalYRotationSteps;
+
+                var angleY = normalizedY * Math.PI * 2;
+
+                var rotationZ = BABYLON.Matrix.RotationZ(-angleZ);
+                var rotationY = BABYLON.Matrix.RotationY(angleY);
+                var afterRotZ = BABYLON.Vector3.TransformCoordinates(BABYLON.Vector3.Up(), rotationZ);
+                var complete = BABYLON.Vector3.TransformCoordinates(afterRotZ, rotationY);
+
+                var vertex = complete.scale(radius);
+                var normal = BABYLON.Vector3.Normalize(vertex);
+
+                positions.push(vertex.x, vertex.y, vertex.z);
+                normals.push(normal.x, normal.y, normal.z);
+                uvs.push(normalizedZ, normalizedY);
+            }
+
+            if (zRotationStep > 0) {
+                var verticesCount = positions.length / 3;
+                for (var firstIndex = verticesCount - 2 * (totalYRotationSteps + 1) ; (firstIndex + totalYRotationSteps + 2) < verticesCount; firstIndex++) {
+                    indices.push((firstIndex));
+                    indices.push((firstIndex + 1));
+                    indices.push(firstIndex + totalYRotationSteps + 1);
+
+                    indices.push((firstIndex + totalYRotationSteps + 1));
+                    indices.push((firstIndex + 1));
+                    indices.push((firstIndex + totalYRotationSteps + 2));
+                }
+            }
+        }
+
+        // Result
+        var vertexData = new BABYLON.VertexData();
+
+        vertexData.indices = indices;
+        vertexData.positions = positions;
+        vertexData.normals = normals;
+        vertexData.uvs = uvs;
+
+        return vertexData;
+    };
+
+    BABYLON.VertexData.CreateCylinder = function (height, diameterTop, diameterBottom, tessellation) {
+        var radiusTop = diameterTop / 2;
+        var radiusBottom = diameterBottom / 2;
+        var indices = [];
+        var positions = [];
+        var normals = [];
+        var uvs = [];
+
+        var getCircleVector = function (i) {
+            var angle = (i * 2.0 * Math.PI / tessellation);
+            var dx = Math.sin(angle);
+            var dz = Math.cos(angle);
+
+            return new BABYLON.Vector3(dx, 0, dz);
+        };
+
+        var createCylinderCap = function (isTop) {
+            var radius = isTop ? radiusTop : radiusBottom;
+
+            if (radius == 0) {
+                return;
+            }
+
+            // Create cap indices.
+            for (var i = 0; i < tessellation - 2; i++) {
+                var i1 = (i + 1) % tessellation;
+                var i2 = (i + 2) % tessellation;
+
+                if (!isTop) {
+                    var tmp = i1;
+                    var i1 = i2;
+                    i2 = tmp;
+                }
+
+                var vbase = positions.length / 3;
+                indices.push(vbase);
+                indices.push(vbase + i1);
+                indices.push(vbase + i2);
+            }
+
+
+            // Which end of the cylinder is this?
+            var normal = new BABYLON.Vector3(0, -1, 0);
+            var textureScale = new BABYLON.Vector2(-0.5, -0.5);
+
+            if (!isTop) {
+                normal = normal.scale(-1);
+                textureScale.x = -textureScale.x;
+            }
+
+            // Create cap vertices.
+            for (var i = 0; i < tessellation; i++) {
+                var circleVector = getCircleVector(i);
+                var position = circleVector.scale(radius).add(normal.scale(height));
+                var textureCoordinate = new BABYLON.Vector2(circleVector.x * textureScale.x + 0.5, circleVector.z * textureScale.y + 0.5);
+
+                positions.push(position.x, position.y, position.z);
+                normals.push(normal.x, normal.y, normal.z);
+                uvs.push(textureCoordinate.x, textureCoordinate.y);
+            }
+        };
+
+        height /= 2;
+
+        var topOffset = new BABYLON.Vector3(0, 1, 0).scale(height);
+
+        var stride = tessellation + 1;
+
+        // Create a ring of triangles around the outside of the cylinder.
+        for (var i = 0; i <= tessellation; i++) {
+            var normal = getCircleVector(i);
+            var sideOffsetBottom = normal.scale(radiusBottom);
+            var sideOffsetTop = normal.scale(radiusTop);
+            var textureCoordinate = new BABYLON.Vector2(i / tessellation, 0);
+
+            var position = sideOffsetBottom.add(topOffset);
+            positions.push(position.x, position.y, position.z);
+            normals.push(normal.x, normal.y, normal.z);
+            uvs.push(textureCoordinate.x, textureCoordinate.y);
+
+            position = sideOffsetTop.subtract(topOffset);
+            textureCoordinate.y += 1;
+            positions.push(position.x, position.y, position.z);
+            normals.push(normal.x, normal.y, normal.z);
+            uvs.push(textureCoordinate.x, textureCoordinate.y);
+
+            indices.push(i * 2);
+            indices.push((i * 2 + 2) % (stride * 2));
+            indices.push(i * 2 + 1);
+
+            indices.push(i * 2 + 1);
+            indices.push((i * 2 + 2) % (stride * 2));
+            indices.push((i * 2 + 3) % (stride * 2));
+        }
+
+        // Create flat triangle fan caps to seal the top and bottom.
+        createCylinderCap(true);
+        createCylinderCap(false);
+
+        // Result
+        var vertexData = new BABYLON.VertexData();
+
+        vertexData.indices = indices;
+        vertexData.positions = positions;
+        vertexData.normals = normals;
+        vertexData.uvs = uvs;
+
+        return vertexData;
+    };
+
+    BABYLON.VertexData.CreateTorus = function (diameter, thickness, tessellation) {
+        var indices = [];
+        var positions = [];
+        var normals = [];
+        var uvs = [];
+
+        var stride = tessellation + 1;
+
+        for (var i = 0; i <= tessellation; i++) {
+            var u = i / tessellation;
+
+            var outerAngle = i * Math.PI * 2.0 / tessellation - Math.PI / 2.0;
+
+            var transform = BABYLON.Matrix.Translation(diameter / 2.0, 0, 0).multiply(BABYLON.Matrix.RotationY(outerAngle));
+
+            for (var j = 0; j <= tessellation; j++) {
+                var v = 1 - j / tessellation;
+
+                var innerAngle = j * Math.PI * 2.0 / tessellation + Math.PI;
+                var dx = Math.cos(innerAngle);
+                var dy = Math.sin(innerAngle);
+
+                // Create a vertex.
+                var normal = new BABYLON.Vector3(dx, dy, 0);
+                var position = normal.scale(thickness / 2);
+                var textureCoordinate = new BABYLON.Vector2(u, v);
+
+                position = BABYLON.Vector3.TransformCoordinates(position, transform);
+                normal = BABYLON.Vector3.TransformNormal(normal, transform);
+
+                positions.push(position.x, position.y, position.z);
+                normals.push(normal.x, normal.y, normal.z);
+                uvs.push(textureCoordinate.x, textureCoordinate.y);
+
+                // And create indices for two triangles.
+                var nextI = (i + 1) % stride;
+                var nextJ = (j + 1) % stride;
+
+                indices.push(i * stride + j);
+                indices.push(i * stride + nextJ);
+                indices.push(nextI * stride + j);
+
+                indices.push(i * stride + nextJ);
+                indices.push(nextI * stride + nextJ);
+                indices.push(nextI * stride + j);
+            }
+        }
+
+        // Result
+        var vertexData = new BABYLON.VertexData();
+
+        vertexData.indices = indices;
+        vertexData.positions = positions;
+        vertexData.normals = normals;
+        vertexData.uvs = uvs;
+
+        return vertexData;
+    };
+
+    BABYLON.VertexData.CreateGround = function (width, height, subdivisions) {
+        var indices = [];
+        var positions = [];
+        var normals = [];
+        var uvs = [];
+        var row, col;
+
+        for (row = 0; row <= subdivisions; row++) {
+            for (col = 0; col <= subdivisions; col++) {
+                var position = new BABYLON.Vector3((col * width) / subdivisions - (width / 2.0), 0, ((subdivisions - row) * height) / subdivisions - (height / 2.0));
+                var normal = new BABYLON.Vector3(0, 1.0, 0);
+
+                positions.push(position.x, position.y, position.z);
+                normals.push(normal.x, normal.y, normal.z);
+                uvs.push(col / subdivisions, 1.0 - row / subdivisions);
+            }
+        }
+
+        for (row = 0; row < subdivisions; row++) {
+            for (col = 0; col < subdivisions; col++) {
+                indices.push(col + 1 + (row + 1) * (subdivisions + 1));
+                indices.push(col + 1 + row * (subdivisions + 1));
+                indices.push(col + row * (subdivisions + 1));
+
+                indices.push(col + (row + 1) * (subdivisions + 1));
+                indices.push(col + 1 + (row + 1) * (subdivisions + 1));
+                indices.push(col + row * (subdivisions + 1));
+            }
+        }
+
+        // Result
+        var vertexData = new BABYLON.VertexData();
+
+        vertexData.indices = indices;
+        vertexData.positions = positions;
+        vertexData.normals = normals;
+        vertexData.uvs = uvs;
+
+        return vertexData;
+    };
+
+    BABYLON.VertexData.CreatePlane = function (size) {
+        var indices = [];
+        var positions = [];
+        var normals = [];
+        var uvs = [];
+
+        // Vertices
+        var halfSize = size / 2.0;
+        positions.push(-halfSize, -halfSize, 0);
+        normals.push(0, 0, -1.0);
+        uvs.push(0.0, 0.0);
+
+        positions.push(halfSize, -halfSize, 0);
+        normals.push(0, 0, -1.0);
+        uvs.push(1.0, 0.0);
+
+        positions.push(halfSize, halfSize, 0);
+        normals.push(0, 0, -1.0);
+        uvs.push(1.0, 1.0);
+
+        positions.push(-halfSize, halfSize, 0);
+        normals.push(0, 0, -1.0);
+        uvs.push(0.0, 1.0);
+
+        // Indices
+        indices.push(0);
+        indices.push(1);
+        indices.push(2);
+
+        indices.push(0);
+        indices.push(2);
+        indices.push(3);
+
+        // Result
+        var vertexData = new BABYLON.VertexData();
+
+        vertexData.indices = indices;
+        vertexData.positions = positions;
+        vertexData.normals = normals;
+        vertexData.uvs = uvs;
+
+        return vertexData;
+    };
+})();

+ 5 - 6
Babylon/Shaders/shadowMap.fragment.fx

@@ -7,11 +7,10 @@ vec4 pack(float depth)
 	const vec4 bitOffset = vec4(255. * 255. * 255., 255. * 255., 255., 1.);
 	const vec4 bitMask = vec4(0., 1. / 255., 1. / 255., 1. / 255.);
 	
-	vec4 comp = mod( depth * bitOffset * vec4( 254. ),
-    			vec4( 255. ) ) / vec4( 254. );
-  	comp -= comp.xxyz * bitMask;
-
-  	return comp;
+	vec4 comp = mod(depth * bitOffset * vec4(254.), vec4(255.)) / vec4(254.);
+	comp -= comp.xxyz * bitMask;
+	
+	return comp;
 }
 
 // Thanks to http://devmaster.net/
@@ -36,4 +35,4 @@ void main(void)
 #else
 	gl_FragColor = pack(vPosition.z / vPosition.w);
 #endif
-}
+}

+ 14 - 0
Babylon/Tools/babylon.tools.js

@@ -13,6 +13,20 @@ var BABYLON = BABYLON || {};
         return path.substring(index + 1);
     };
 
+    BABYLON.Tools.GetDOMTextContent = function(element) {
+        var result = "";
+        var child = element.firstChild;
+
+        while (child) {
+            if (child.nodeType == 3) {
+                result += child.textContent;
+            }
+            child = child.nextSibling;
+        }
+
+        return result;
+    };
+
     BABYLON.Tools.ToDegrees = function(angle) {
         return angle * 180 / Math.PI;
     };

+ 2 - 2
Babylon/babylon.engine.js

@@ -369,8 +369,8 @@ var BABYLON = BABYLON || {};
 
     // Shaders
     BABYLON.Engine.prototype.createEffect = function (baseName, attributesNames, uniformsNames, samplers, defines, optionalDefines) {
-        var vertex = baseName.vertex || baseName;
-        var fragment = baseName.fragment || baseName;
+        var vertex = baseName.vertexElement || baseName.vertex || baseName;
+        var fragment = baseName.fragmentElement || baseName.fragment || baseName;
         
         var name = vertex + "+" + fragment + "@" + defines;
         if (this._compiledEffects[name]) {

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

@@ -1,5 +1,7 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <files xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="babylonJS.xsd">
+  <script src="Babylon/Mesh/babylon.mesh.vertexData.js"></script>
+  <script src="Babylon/Materials/babylon.shaderMaterial.js"></script>
   <script src="Babylon/Cameras/babylon.virtualJoysticksCamera.js"></script>
   <script src="Babylon/Tools/babylon.virtualJoystick.js"></script>
   <script src="Babylon/Cameras/babylon.oculusOrientedCamera.js"></script>

BIN
Tools/Visual Studio Extensions/Babylon.VSIX.vsix


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 24 - 0
babylon.1.10.0.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 24
babylon.1.9.0.js


+ 1 - 0
readme.md

@@ -15,6 +15,7 @@ Online [sandbox](http://www.babylonjs.com/sandbox) where you can test your .baby
 - [Creating the minified version](https://github.com/BabylonJS/Babylon.js/wiki/Creating-the-minified-version)
 - [Roadmap](https://github.com/BabylonJS/Babylon.js/wiki/Roadmap)
 - [Samples](https://github.com/BabylonJS/Samples)
+- [Video overview (1 hour) of BabylonJS features](http://www.youtube.com/watch?v=z80TYMqsdEM)
 
 ## Features
 - Complete scene graph with lights, cameras, materials and meshes

+ 39 - 0
what's new.md

@@ -1,5 +1,44 @@
 Changes list
 ============
+- 1.10.0:
+ - **Major updates**
+ - Virtual joysticks canera ([davrous](http://www.github.com/davrous))
+ - Oculus Rift support ([davrous](http://www.github.com/davrous)), ([simonferquel](http://www.github.com/simonferquel)), ([deltakosh](http://www.github.com/deltakosh))
+ - Support for DDS textures ([deltakosh](http://www.github.com/deltakosh))
+ - Constructive solid geometries ([CraigFeldspar](https://github.com/CraigFeldspar))
+ - Importer plugin system ([deltakosh](http://www.github.com/deltakosh))
+ - Filter postprocess ([deltakosh](http://www.github.com/deltakosh))
+ - Convolution postprocess ([deltakosh](http://www.github.com/deltakosh))
+ - Added Cheetah3d exporter ([Calebsem](http://www.github.com/Calebsem))
+ - New ```BABYLON.ShaderMaterial``` object to simply create custom shaders ([deltakosh](http://www.github.com/deltakosh)) - See [Custom shader - cell shading](http://www.babylonjs.com/index.html?CUSTOMSHADER)
+ - New ```BABYLON.VertexData``` object to easily manipulates vertex attributes ([deltakosh](http://www.github.com/deltakosh)) - See [VertexData](http://www.babylonjs.com/index.html?CLOUDS)
+ - **Updates**
+ - Shaders can be loaded from DOM element alongside .fx files ([deltakosh](http://www.github.com/deltakosh))
+ - Adding arcRotateCamera.wheelPrecision ([deltakosh](http://www.github.com/deltakosh))
+ - Support for DOMMouseScroll ([nicolas-obre](https://github.com/nicolas-obre))
+ - Adding BABYLON.PickingInfo.prototype.getNormal ([deltakosh](http://www.github.com/deltakosh))
+ - Adding a new noMipmap parameter to ```BABYLON.CubeTexture``` constructor ([deltakosh](http://www.github.com/deltakosh))
+ - Adding ```BABYLON.Color3.FromInts()``` and ```BABYLON.Color4.FromInts()``` ([deltakosh](http://www.github.com/deltakosh))
+ - Adding invertY parameter to ```BABYLON.VideoTexture``` constructor ([deltakosh](http://www.github.com/deltakosh))
+ - Adding new ```BABYLON.Scene.getCameraByID``` function ([deltakosh](http://www.github.com/deltakosh))
+ - Adding new ```BABYLON.Scene.setActiveCameraByName()``` function ([deltakosh](http://www.github.com/deltakosh))
+ - Renaming ```BABYLON.Scene.activeCameraByID()``` to ```BABYLON.Scene.setActiveCameraByID()``` ([deltakosh](http://www.github.com/deltakosh))
+ - Adding texture wrapping support to Blender exporter ([vousk](http://www.github.com/vousk))
+ - Add Gulp for buiding babylon cross platform ([SideraX](http://www.github.com/SideraX))
+ - Shadow map improvement on pack method ([clementlevasseur](http://www.github.com/clementlevasseur))
+ - **Bugfixes**
+ - Fixing multimat naming convention in Blender ([deltakosh](http://www.github.com/deltakosh))
+ - Fixing mesh.clone ([temechon](http://www.github.com/temechon))
+ - Fixing camera rotation export in blender ([khmm12](http://www.github.com/khmm12))
+ - Fixing opacity map bug ([deltakosh](http://www.github.com/deltakosh))
+ - Fixing physics objects disposal ([deltakosh](http://www.github.com/deltakosh))
+ - Using the hardware scaling when creating a ray ([demonixis](http://www.github.com/demonixis))
+ - **New demos*
+ - [Hill Valley](http://www.babylonjs.com/index.html?HILLVALLEY)
+ - [Custom shader - cell shading](http://www.babylonjs.com/index.html?CUSTOMSHADER)
+ - [Constructive solid geometries](http://www.babylonjs.com/index.html?CSG)
+ - [Postprocess - Convolution](http://www.babylonjs.com/index.html?PPCONVOLUTION)
+ - [VertexData](http://www.babylonjs.com/index.html?CLOUDS)
 - 1.9.0:
  - **Major updates**
  - Beta support for scene serialization with ```BABYLON.SceneSerializer.Serialize``` function ([deltakosh](http://www.github.com/deltakosh))