Selaa lähdekoodia

Integrating Jerome works on DOUBLESIDE

David Catuhe 10 vuotta sitten
vanhempi
commit
7a102ac4de

+ 30 - 18
Babylon/Mesh/babylon.geometry.js

@@ -398,68 +398,76 @@ var BABYLON;
             Primitives._Primitive = _Primitive;
             var Box = (function (_super) {
                 __extends(Box, _super);
-                function Box(id, scene, size, canBeRegenerated, mesh) {
+                function Box(id, scene, size, canBeRegenerated, mesh, side) {
+                    if (side === void 0) { side = BABYLON.Mesh.DEFAULTSIDE; }
                     this.size = size;
+                    this.side = side;
                     _super.call(this, id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
                 }
                 Box.prototype._regenerateVertexData = function () {
-                    return BABYLON.VertexData.CreateBox(this.size);
+                    return BABYLON.VertexData.CreateBox(this.size, this.side);
                 };
                 Box.prototype.copy = function (id) {
-                    return new Box(id, this.getScene(), this.size, this.canBeRegenerated(), null);
+                    return new Box(id, this.getScene(), this.size, this.canBeRegenerated(), null, this.side);
                 };
                 return Box;
             })(_Primitive);
             Primitives.Box = Box;
             var Sphere = (function (_super) {
                 __extends(Sphere, _super);
-                function Sphere(id, scene, segments, diameter, canBeRegenerated, mesh) {
+                function Sphere(id, scene, segments, diameter, canBeRegenerated, mesh, side) {
+                    if (side === void 0) { side = BABYLON.Mesh.DEFAULTSIDE; }
                     this.segments = segments;
                     this.diameter = diameter;
+                    this.side = side;
                     _super.call(this, id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
                 }
                 Sphere.prototype._regenerateVertexData = function () {
-                    return BABYLON.VertexData.CreateSphere(this.segments, this.diameter);
+                    return BABYLON.VertexData.CreateSphere(this.segments, this.diameter, this.side);
                 };
                 Sphere.prototype.copy = function (id) {
-                    return new Sphere(id, this.getScene(), this.segments, this.diameter, this.canBeRegenerated(), null);
+                    return new Sphere(id, this.getScene(), this.segments, this.diameter, this.canBeRegenerated(), null, this.side);
                 };
                 return Sphere;
             })(_Primitive);
             Primitives.Sphere = Sphere;
             var Cylinder = (function (_super) {
                 __extends(Cylinder, _super);
-                function Cylinder(id, scene, height, diameterTop, diameterBottom, tessellation, subdivisions, canBeRegenerated, mesh) {
+                function Cylinder(id, scene, height, diameterTop, diameterBottom, tessellation, subdivisions, canBeRegenerated, mesh, side) {
                     if (subdivisions === void 0) { subdivisions = 1; }
+                    if (side === void 0) { side = BABYLON.Mesh.DEFAULTSIDE; }
                     this.height = height;
                     this.diameterTop = diameterTop;
                     this.diameterBottom = diameterBottom;
                     this.tessellation = tessellation;
                     this.subdivisions = subdivisions;
+                    this.side = side;
                     _super.call(this, id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
                 }
                 Cylinder.prototype._regenerateVertexData = function () {
-                    return BABYLON.VertexData.CreateCylinder(this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions);
+                    return BABYLON.VertexData.CreateCylinder(this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions, this.side);
                 };
                 Cylinder.prototype.copy = function (id) {
-                    return new Cylinder(id, this.getScene(), this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions, this.canBeRegenerated(), null);
+                    return new Cylinder(id, this.getScene(), this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions, this.canBeRegenerated(), null, this.side);
                 };
                 return Cylinder;
             })(_Primitive);
             Primitives.Cylinder = Cylinder;
             var Torus = (function (_super) {
                 __extends(Torus, _super);
-                function Torus(id, scene, diameter, thickness, tessellation, canBeRegenerated, mesh) {
+                function Torus(id, scene, diameter, thickness, tessellation, canBeRegenerated, mesh, side) {
+                    if (side === void 0) { side = BABYLON.Mesh.DEFAULTSIDE; }
                     this.diameter = diameter;
                     this.thickness = thickness;
                     this.tessellation = tessellation;
+                    this.side = side;
                     _super.call(this, id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
                 }
                 Torus.prototype._regenerateVertexData = function () {
-                    return BABYLON.VertexData.CreateTorus(this.diameter, this.thickness, this.tessellation);
+                    return BABYLON.VertexData.CreateTorus(this.diameter, this.thickness, this.tessellation, this.side);
                 };
                 Torus.prototype.copy = function (id) {
-                    return new Torus(id, this.getScene(), this.diameter, this.thickness, this.tessellation, this.canBeRegenerated(), null);
+                    return new Torus(id, this.getScene(), this.diameter, this.thickness, this.tessellation, this.canBeRegenerated(), null, this.side);
                 };
                 return Torus;
             })(_Primitive);
@@ -503,35 +511,39 @@ var BABYLON;
             Primitives.TiledGround = TiledGround;
             var Plane = (function (_super) {
                 __extends(Plane, _super);
-                function Plane(id, scene, size, canBeRegenerated, mesh) {
+                function Plane(id, scene, size, canBeRegenerated, mesh, side) {
+                    if (side === void 0) { side = BABYLON.Mesh.DEFAULTSIDE; }
                     this.size = size;
+                    this.side = side;
                     _super.call(this, id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
                 }
                 Plane.prototype._regenerateVertexData = function () {
-                    return BABYLON.VertexData.CreatePlane(this.size);
+                    return BABYLON.VertexData.CreatePlane(this.size, this.side);
                 };
                 Plane.prototype.copy = function (id) {
-                    return new Plane(id, this.getScene(), this.size, this.canBeRegenerated(), null);
+                    return new Plane(id, this.getScene(), this.size, this.canBeRegenerated(), null, this.side);
                 };
                 return Plane;
             })(_Primitive);
             Primitives.Plane = Plane;
             var TorusKnot = (function (_super) {
                 __extends(TorusKnot, _super);
-                function TorusKnot(id, scene, radius, tube, radialSegments, tubularSegments, p, q, canBeRegenerated, mesh) {
+                function TorusKnot(id, scene, radius, tube, radialSegments, tubularSegments, p, q, canBeRegenerated, mesh, side) {
+                    if (side === void 0) { side = BABYLON.Mesh.DEFAULTSIDE; }
                     this.radius = radius;
                     this.tube = tube;
                     this.radialSegments = radialSegments;
                     this.tubularSegments = tubularSegments;
                     this.p = p;
                     this.q = q;
+                    this.side = side;
                     _super.call(this, id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
                 }
                 TorusKnot.prototype._regenerateVertexData = function () {
-                    return BABYLON.VertexData.CreateTorusKnot(this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q);
+                    return BABYLON.VertexData.CreateTorusKnot(this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q, this.side);
                 };
                 TorusKnot.prototype.copy = function (id) {
-                    return new TorusKnot(id, this.getScene(), this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q, this.canBeRegenerated(), null);
+                    return new TorusKnot(id, this.getScene(), this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q, this.canBeRegenerated(), null, this.side);
                 };
                 return TorusKnot;
             })(_Primitive);

+ 30 - 18
Babylon/Mesh/babylon.geometry.ts

@@ -503,19 +503,21 @@
         export class Box extends _Primitive {
             // Members
             public size: number;
+            public side: number;
 
-            constructor(id: string, scene: Scene, size: number, canBeRegenerated?: boolean, mesh?: Mesh) {
+            constructor(id: string, scene: Scene, size: number, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
                 this.size = size;
+                this.side = side;
 
                 super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
             }
 
             public _regenerateVertexData(): VertexData {
-                return VertexData.CreateBox(this.size);
+                return VertexData.CreateBox(this.size, this.side);
             }
 
             public copy(id: string): Geometry {
-                return new Box(id, this.getScene(), this.size, this.canBeRegenerated(), null);
+                return new Box(id, this.getScene(), this.size, this.canBeRegenerated(), null, this.side);
             }
         }
 
@@ -523,20 +525,22 @@
             // Members
             public segments: number;
             public diameter: number;
+            public side: number;
 
-            constructor(id: string, scene: Scene, segments: number, diameter: number, canBeRegenerated?: boolean, mesh?: Mesh) {
+            constructor(id: string, scene: Scene, segments: number, diameter: number, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
                 this.segments = segments;
                 this.diameter = diameter;
+                this.side = side;
 
                 super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
             }
 
             public _regenerateVertexData(): VertexData {
-                return VertexData.CreateSphere(this.segments, this.diameter);
+                return VertexData.CreateSphere(this.segments, this.diameter, this.side);
             }
 
             public copy(id: string): Geometry {
-                return new Sphere(id, this.getScene(), this.segments, this.diameter, this.canBeRegenerated(), null);
+                return new Sphere(id, this.getScene(), this.segments, this.diameter, this.canBeRegenerated(), null, this.side);
             }
         }
 
@@ -547,23 +551,25 @@
             public diameterBottom: number;
             public tessellation: number;
             public subdivisions: number;
+            public side: number;
 
-            constructor(id: string, scene: Scene, height: number, diameterTop: number, diameterBottom: number, tessellation: number, subdivisions: number = 1, canBeRegenerated?: boolean, mesh?: Mesh) {
+            constructor(id: string, scene: Scene, height: number, diameterTop: number, diameterBottom: number, tessellation: number, subdivisions: number = 1, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
                 this.height = height;
                 this.diameterTop = diameterTop;
                 this.diameterBottom = diameterBottom;
                 this.tessellation = tessellation;
                 this.subdivisions = subdivisions;
+                this.side = side;
 
                 super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
             }
 
             public _regenerateVertexData(): VertexData {
-                return VertexData.CreateCylinder(this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions);
+                return VertexData.CreateCylinder(this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions, this.side);
             }
 
             public copy(id: string): Geometry {
-                return new Cylinder(id, this.getScene(), this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions, this.canBeRegenerated(), null);
+                return new Cylinder(id, this.getScene(), this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions, this.canBeRegenerated(), null, this.side);
             }
         }
 
@@ -572,21 +578,23 @@
             public diameter: number;
             public thickness: number;
             public tessellation: number;
+            public side: number;
 
-            constructor(id: string, scene: Scene, diameter: number, thickness: number, tessellation: number, canBeRegenerated?: boolean, mesh?: Mesh) {
+            constructor(id: string, scene: Scene, diameter: number, thickness: number, tessellation: number, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
                 this.diameter = diameter;
                 this.thickness = thickness;
                 this.tessellation = tessellation;
+                this.side = side;
 
                 super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
             }
 
             public _regenerateVertexData(): VertexData {
-                return VertexData.CreateTorus(this.diameter, this.thickness, this.tessellation);
+                return VertexData.CreateTorus(this.diameter, this.thickness, this.tessellation, this.side);
             }
 
             public copy(id: string): Geometry {
-                return new Torus(id, this.getScene(), this.diameter, this.thickness, this.tessellation, this.canBeRegenerated(), null);
+                return new Torus(id, this.getScene(), this.diameter, this.thickness, this.tessellation, this.canBeRegenerated(), null, this.side);
             }
         }
 
@@ -645,19 +653,21 @@
         export class Plane extends _Primitive {
             // Members
             public size: number;
+            public side: number;
 
-            constructor(id: string, scene: Scene, size: number, canBeRegenerated?: boolean, mesh?: Mesh) {
+            constructor(id: string, scene: Scene, size: number, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
                 this.size = size;
+                this.side = side;
 
                 super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
             }
 
             public _regenerateVertexData(): VertexData {
-                return VertexData.CreatePlane(this.size);
+                return VertexData.CreatePlane(this.size, this.side);
             }
 
             public copy(id: string): Geometry {
-                return new Plane(id, this.getScene(), this.size, this.canBeRegenerated(), null);
+                return new Plane(id, this.getScene(), this.size, this.canBeRegenerated(), null, this.side);
             }
         }
 
@@ -669,24 +679,26 @@
             public tubularSegments: number;
             public p: number;
             public q: number;
+            public side: number;
 
-            constructor(id: string, scene: Scene, radius: number, tube: number, radialSegments: number, tubularSegments: number, p: number, q: number, canBeRegenerated?: boolean, mesh?: Mesh) {
+            constructor(id: string, scene: Scene, radius: number, tube: number, radialSegments: number, tubularSegments: number, p: number, q: number, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
                 this.radius = radius;
                 this.tube = tube;
                 this.radialSegments = radialSegments;
                 this.tubularSegments = tubularSegments;
                 this.p = p;
                 this.q = q;
+                this.side = side;
 
                 super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
             }
 
             public _regenerateVertexData(): VertexData {
-                return VertexData.CreateTorusKnot(this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q);
+                return VertexData.CreateTorusKnot(this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q, this.side);
             }
 
             public copy(id: string): Geometry {
-                return new TorusKnot(id, this.getScene(), this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q, this.canBeRegenerated(), null);
+                return new TorusKnot(id, this.getScene(), this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q, this.canBeRegenerated(), null, this.side);
             }
         }
     }

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

@@ -71,6 +71,34 @@ var BABYLON;
                 this.parent = parent;
             }
         }
+        Object.defineProperty(Mesh, "FRONTSIDE", {
+            get: function () {
+                return Mesh._FRONTSIDE;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Mesh, "BACKSIDE", {
+            get: function () {
+                return Mesh._BACKSIDE;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Mesh, "DOUBLESIDE", {
+            get: function () {
+                return Mesh._DOUBLESIDE;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Mesh, "DEFAULTSIDE", {
+            get: function () {
+                return Mesh._DEFAULTSIDE;
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(Mesh.prototype, "hasLODLevels", {
             // Methods
             get: function () {
@@ -268,7 +296,7 @@ var BABYLON;
             var totalIndices = this.getTotalIndices();
             var subdivisionSize = (totalIndices / count) | 0;
             var offset = 0;
-            while (subdivisionSize % 3 != 0) {
+            while (subdivisionSize % 3 !== 0) {
                 subdivisionSize++;
             }
             this.releaseSubMeshes();
@@ -891,26 +919,30 @@ var BABYLON;
             }
         };
         // Statics
-        Mesh.CreateRibbon = function (name, pathArray, closeArray, closePath, offset, scene, updatable) {
+        Mesh.CreateRibbon = function (name, pathArray, closeArray, closePath, offset, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             var ribbon = new Mesh(name, scene);
-            var vertexData = BABYLON.VertexData.CreateRibbon(pathArray, closeArray, closePath, offset);
+            var vertexData = BABYLON.VertexData.CreateRibbon(pathArray, closeArray, closePath, offset, sideOrientation);
             vertexData.applyToMesh(ribbon, updatable);
             return ribbon;
         };
-        Mesh.CreateBox = function (name, size, scene, updatable) {
+        Mesh.CreateBox = function (name, size, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             var box = new Mesh(name, scene);
-            var vertexData = BABYLON.VertexData.CreateBox(size);
+            var vertexData = BABYLON.VertexData.CreateBox(size, sideOrientation);
             vertexData.applyToMesh(box, updatable);
             return box;
         };
-        Mesh.CreateSphere = function (name, segments, diameter, scene, updatable) {
+        Mesh.CreateSphere = function (name, segments, diameter, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             var sphere = new Mesh(name, scene);
-            var vertexData = BABYLON.VertexData.CreateSphere(segments, diameter);
+            var vertexData = BABYLON.VertexData.CreateSphere(segments, diameter, sideOrientation);
             vertexData.applyToMesh(sphere, updatable);
             return sphere;
         };
         // Cylinder and cone (Code inspired by SharpDX.org)
-        Mesh.CreateCylinder = function (name, height, diameterTop, diameterBottom, tessellation, subdivisions, scene, updatable) {
+        Mesh.CreateCylinder = function (name, height, diameterTop, diameterBottom, tessellation, subdivisions, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             // subdivisions is a new parameter, we need to support old signature
             if (scene === undefined || !(scene instanceof BABYLON.Scene)) {
                 if (scene !== undefined) {
@@ -925,15 +957,17 @@ var BABYLON;
             return cylinder;
         };
         // Torus  (Code from SharpDX.org)
-        Mesh.CreateTorus = function (name, diameter, thickness, tessellation, scene, updatable) {
+        Mesh.CreateTorus = function (name, diameter, thickness, tessellation, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             var torus = new Mesh(name, scene);
-            var vertexData = BABYLON.VertexData.CreateTorus(diameter, thickness, tessellation);
+            var vertexData = BABYLON.VertexData.CreateTorus(diameter, thickness, tessellation, sideOrientation);
             vertexData.applyToMesh(torus, updatable);
             return torus;
         };
-        Mesh.CreateTorusKnot = function (name, radius, tube, radialSegments, tubularSegments, p, q, scene, updatable) {
+        Mesh.CreateTorusKnot = function (name, radius, tube, radialSegments, tubularSegments, p, q, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             var torusKnot = new Mesh(name, scene);
-            var vertexData = BABYLON.VertexData.CreateTorusKnot(radius, tube, radialSegments, tubularSegments, p, q);
+            var vertexData = BABYLON.VertexData.CreateTorusKnot(radius, tube, radialSegments, tubularSegments, p, q, sideOrientation);
             vertexData.applyToMesh(torusKnot, updatable);
             return torusKnot;
         };
@@ -945,9 +979,10 @@ var BABYLON;
             return lines;
         };
         // Plane & ground
-        Mesh.CreatePlane = function (name, size, scene, updatable) {
+        Mesh.CreatePlane = function (name, size, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             var plane = new Mesh(name, scene);
-            var vertexData = BABYLON.VertexData.CreatePlane(size);
+            var vertexData = BABYLON.VertexData.CreatePlane(size, sideOrientation);
             vertexData.applyToMesh(plane, updatable);
             return plane;
         };
@@ -1054,6 +1089,11 @@ var BABYLON;
             }
             return newMesh;
         };
+        // Consts
+        Mesh._FRONTSIDE = 0;
+        Mesh._BACKSIDE = 1;
+        Mesh._DOUBLESIDE = 2;
+        Mesh._DEFAULTSIDE = 0;
         return Mesh;
     })(BABYLON.AbstractMesh);
     BABYLON.Mesh = Mesh;

+ 37 - 14
Babylon/Mesh/babylon.mesh.ts

@@ -6,6 +6,29 @@
     }
 
     export class Mesh extends AbstractMesh implements IGetSetVerticesData {
+        // Consts
+        public static _FRONTSIDE: number = 0;
+        public static _BACKSIDE: number = 1;
+        public static _DOUBLESIDE: number = 2;
+        public static _DEFAULTSIDE: number = 0;
+
+        public static get FRONTSIDE(): number {
+            return Mesh._FRONTSIDE;
+        }
+
+        public static get BACKSIDE(): number {
+            return Mesh._BACKSIDE;
+        }
+
+        public static get DOUBLESIDE(): number {
+            return Mesh._DOUBLESIDE;
+        }
+
+        public static get DEFAULTSIDE(): number {
+            return Mesh._DEFAULTSIDE;
+        }
+
+
         // Members
         public delayLoadState = Engine.DELAYLOADSTATE_NONE;
         public instances = new Array<InstancedMesh>();
@@ -312,7 +335,7 @@
             var offset = 0;
 
             // Ensure that subdivisionSize is a multiple of 3
-            while (subdivisionSize % 3 != 0) {
+            while (subdivisionSize % 3 !== 0) {
                 subdivisionSize++;
             }
 
@@ -1095,27 +1118,27 @@
         }
 
         // Statics
-        public static CreateRibbon(name: string, pathArray: Vector3[][], closeArray: boolean, closePath: boolean, offset: number, scene: Scene, updatable?: boolean): Mesh {
+        public static CreateRibbon(name: string, pathArray: Vector3[][], closeArray: boolean, closePath: boolean, offset: number, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE): Mesh {
             var ribbon = new Mesh(name, scene);
-            var vertexData = VertexData.CreateRibbon(pathArray, closeArray, closePath, offset);
+            var vertexData = VertexData.CreateRibbon(pathArray, closeArray, closePath, offset, sideOrientation);
 
             vertexData.applyToMesh(ribbon, updatable);
 
             return ribbon;
         }
 
-        public static CreateBox(name: string, size: number, scene: Scene, updatable?: boolean): Mesh {
+        public static CreateBox(name: string, size: number, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE): Mesh {
             var box = new Mesh(name, scene);
-            var vertexData = VertexData.CreateBox(size);
+            var vertexData = VertexData.CreateBox(size, sideOrientation);
 
             vertexData.applyToMesh(box, updatable);
 
             return box;
         }
 
-        public static CreateSphere(name: string, segments: number, diameter: number, scene: Scene, updatable?: boolean): Mesh {
+        public static CreateSphere(name: string, segments: number, diameter: number, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE): Mesh {
             var sphere = new Mesh(name, scene);
-            var vertexData = VertexData.CreateSphere(segments, diameter);
+            var vertexData = VertexData.CreateSphere(segments, diameter, sideOrientation);
 
             vertexData.applyToMesh(sphere, updatable);
 
@@ -1123,7 +1146,7 @@
         }
 
         // Cylinder and cone (Code inspired by SharpDX.org)
-        public static CreateCylinder(name: string, height: number, diameterTop: number, diameterBottom: number, tessellation: number, subdivisions: any, scene: Scene, updatable?: any): Mesh {
+        public static CreateCylinder(name: string, height: number, diameterTop: number, diameterBottom: number, tessellation: number, subdivisions: any, scene: Scene, updatable?: any, sideOrientation: number = Mesh.DEFAULTSIDE): Mesh {
             // subdivisions is a new parameter, we need to support old signature
             if (scene === undefined || !(scene instanceof Scene)) {
                 if (scene !== undefined) {
@@ -1142,18 +1165,18 @@
         }
 
         // Torus  (Code from SharpDX.org)
-        public static CreateTorus(name: string, diameter: number, thickness: number, tessellation: number, scene: Scene, updatable?: boolean): Mesh {
+        public static CreateTorus(name: string, diameter: number, thickness: number, tessellation: number, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE): Mesh {
             var torus = new Mesh(name, scene);
-            var vertexData = VertexData.CreateTorus(diameter, thickness, tessellation);
+            var vertexData = VertexData.CreateTorus(diameter, thickness, tessellation, sideOrientation);
 
             vertexData.applyToMesh(torus, updatable);
 
             return torus;
         }
 
-        public static CreateTorusKnot(name: string, radius: number, tube: number, radialSegments: number, tubularSegments: number, p: number, q: number, scene: Scene, updatable?: boolean): Mesh {
+        public static CreateTorusKnot(name: string, radius: number, tube: number, radialSegments: number, tubularSegments: number, p: number, q: number, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE): Mesh {
             var torusKnot = new Mesh(name, scene);
-            var vertexData = VertexData.CreateTorusKnot(radius, tube, radialSegments, tubularSegments, p, q);
+            var vertexData = VertexData.CreateTorusKnot(radius, tube, radialSegments, tubularSegments, p, q, sideOrientation);
 
             vertexData.applyToMesh(torusKnot, updatable);
 
@@ -1172,9 +1195,9 @@
         }
 
         // Plane & ground
-        public static CreatePlane(name: string, size: number, scene: Scene, updatable?: boolean): Mesh {
+        public static CreatePlane(name: string, size: number, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE): Mesh {
             var plane = new Mesh(name, scene);
-            var vertexData = VertexData.CreatePlane(size);
+            var vertexData = VertexData.CreatePlane(size, sideOrientation);
 
             vertexData.applyToMesh(plane, updatable);
 

+ 71 - 7
Babylon/Mesh/babylon.mesh.vertexData.js

@@ -215,7 +215,8 @@ var BABYLON;
             result.indices = meshOrGeometry.getIndices();
             return result;
         };
-        VertexData.CreateRibbon = function (pathArray, closeArray, closePath, offset) {
+        VertexData.CreateRibbon = function (pathArray, closeArray, closePath, offset, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             closeArray = closeArray || false;
             closePath = closePath || false;
             var defaultOffset = Math.floor(pathArray[0].length / 2);
@@ -350,6 +351,8 @@ var BABYLON;
             }
             // normals
             VertexData.ComputeNormals(positions, indices, normals);
+            // sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -358,7 +361,8 @@ var BABYLON;
             vertexData.uvs = uvs;
             return vertexData;
         };
-        VertexData.CreateBox = function (size) {
+        VertexData.CreateBox = function (size, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             var normalsSource = [
                 new BABYLON.Vector3(0, 0, 1),
                 new BABYLON.Vector3(0, 0, -1),
@@ -403,6 +407,8 @@ var BABYLON;
                 normals.push(normal.x, normal.y, normal.z);
                 uvs.push(1.0, 0.0);
             }
+            // sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -411,7 +417,8 @@ var BABYLON;
             vertexData.uvs = uvs;
             return vertexData;
         };
-        VertexData.CreateSphere = function (segments, diameter) {
+        VertexData.CreateSphere = function (segments, diameter, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             segments = segments || 32;
             diameter = diameter || 1;
             var radius = diameter / 2;
@@ -449,6 +456,8 @@ var BABYLON;
                     }
                 }
             }
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -457,8 +466,9 @@ var BABYLON;
             vertexData.uvs = uvs;
             return vertexData;
         };
-        VertexData.CreateCylinder = function (height, diameterTop, diameterBottom, tessellation, subdivisions) {
+        VertexData.CreateCylinder = function (height, diameterTop, diameterBottom, tessellation, subdivisions, sideOrientation) {
             if (subdivisions === void 0) { subdivisions = 1; }
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             var radiusTop = diameterTop / 2;
             var radiusBottom = diameterBottom / 2;
             var indices = [];
@@ -543,6 +553,8 @@ var BABYLON;
             createCylinderCap(false);
             // Normals
             VertexData.ComputeNormals(positions, indices, normals);
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -551,7 +563,8 @@ var BABYLON;
             vertexData.uvs = uvs;
             return vertexData;
         };
-        VertexData.CreateTorus = function (diameter, thickness, tessellation) {
+        VertexData.CreateTorus = function (diameter, thickness, tessellation, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             var indices = [];
             var positions = [];
             var normals = [];
@@ -589,6 +602,8 @@ var BABYLON;
                     indices.push(nextI * stride + j);
                 }
             }
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -756,7 +771,8 @@ var BABYLON;
             vertexData.uvs = uvs;
             return vertexData;
         };
-        VertexData.CreatePlane = function (size) {
+        VertexData.CreatePlane = function (size, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             var indices = [];
             var positions = [];
             var normals = [];
@@ -783,6 +799,8 @@ var BABYLON;
             indices.push(0);
             indices.push(2);
             indices.push(3);
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -792,7 +810,8 @@ var BABYLON;
             return vertexData;
         };
         // based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473
-        VertexData.CreateTorusKnot = function (radius, tube, radialSegments, tubularSegments, p, q) {
+        VertexData.CreateTorusKnot = function (radius, tube, radialSegments, tubularSegments, p, q, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             var indices = [];
             var positions = [];
             var normals = [];
@@ -854,6 +873,8 @@ var BABYLON;
             }
             // Normals
             VertexData.ComputeNormals(positions, indices, normals);
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -900,6 +921,49 @@ var BABYLON;
                 normals[index * 3 + 2] = normal.z;
             }
         };
+        VertexData.ComputeSides = function (sideOrientation, positions, indices, normals, uvs) {
+            var li = indices.length;
+            var ln = normals.length;
+            var i;
+            var n;
+            sideOrientation = sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
+            switch (sideOrientation) {
+                case BABYLON.Mesh.FRONTSIDE:
+                    break;
+                case BABYLON.Mesh.BACKSIDE:
+                    var tmp;
+                    for (i = 0; i < li; i += 3) {
+                        tmp = indices[i];
+                        indices[i] = indices[i + 2];
+                        indices[i + 2] = tmp;
+                    }
+                    for (n = 0; n < ln; n++) {
+                        normals[n] = -normals[n];
+                    }
+                    break;
+                case BABYLON.Mesh.DOUBLESIDE:
+                    // positions 
+                    var lp = positions.length;
+                    var l = lp / 3;
+                    for (var p = 0; p < lp; p++) {
+                        positions[lp + p] = positions[p];
+                    }
+                    for (i = 0; i < li; i += 3) {
+                        indices[i + li] = indices[i + 2] + l;
+                        indices[i + 1 + li] = indices[i + 1] + l;
+                        indices[i + 2 + li] = indices[i] + l;
+                    }
+                    for (n = 0; n < ln; n++) {
+                        normals[ln + n] = -normals[n];
+                    }
+                    // uvs
+                    var lu = uvs.length;
+                    for (var u = 0; u < lu; u++) {
+                        uvs[u + lu] = uvs[u];
+                    }
+                    break;
+            }
+        };
         return VertexData;
     })();
     BABYLON.VertexData = VertexData;

+ 85 - 8
Babylon/Mesh/babylon.mesh.vertexData.ts

@@ -280,7 +280,7 @@
             return result;
         }
 
-        public static CreateRibbon(pathArray: Vector3[][], closeArray: boolean, closePath: boolean, offset: number): VertexData {
+        public static CreateRibbon(pathArray: Vector3[][], closeArray: boolean, closePath: boolean, offset: number, sideOrientation: number = Mesh.DEFAULTSIDE): VertexData {
             closeArray = closeArray || false;
             closePath = closePath || false;
             var defaultOffset = Math.floor(pathArray[0].length / 2);
@@ -430,6 +430,9 @@
             // normals
             VertexData.ComputeNormals(positions, indices, normals);
 
+            // sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
+
             // Result
             var vertexData = new VertexData();
 
@@ -441,7 +444,7 @@
             return vertexData;
         }
 
-        public static CreateBox(size: number): VertexData {
+        public static CreateBox(size: number, sideOrientation: number = Mesh.DEFAULTSIDE): VertexData {
             var normalsSource = [
                 new Vector3(0, 0, 1),
                 new Vector3(0, 0, -1),
@@ -498,6 +501,9 @@
                 uvs.push(1.0, 0.0);
             }
 
+            // sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
+
             // Result
             var vertexData = new VertexData();
 
@@ -509,7 +515,7 @@
             return vertexData;
         }
 
-        public static CreateSphere(segments: number, diameter: number): VertexData {
+        public static CreateSphere(segments: number, diameter: number, sideOrientation: number = Mesh.DEFAULTSIDE): VertexData {
 
             segments = segments || 32;
             diameter = diameter || 1;
@@ -560,6 +566,9 @@
                 }
             }
 
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
+
             // Result
             var vertexData = new VertexData();
 
@@ -571,7 +580,7 @@
             return vertexData;
         }
 
-        public static CreateCylinder(height: number, diameterTop: number, diameterBottom: number, tessellation: number, subdivisions: number = 1): VertexData {
+        public static CreateCylinder(height: number, diameterTop: number, diameterBottom: number, tessellation: number, subdivisions: number = 1, sideOrientation: number = Mesh.DEFAULTSIDE): VertexData {
             var radiusTop = diameterTop / 2;
             var radiusBottom = diameterBottom / 2;
             var indices = [];
@@ -681,6 +690,9 @@
             // Normals
             VertexData.ComputeNormals(positions, indices, normals);
 
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
+
             // Result
             var vertexData = new VertexData();
 
@@ -692,7 +704,7 @@
             return vertexData;
         }
 
-        public static CreateTorus(diameter, thickness, tessellation) {
+        public static CreateTorus(diameter, thickness, tessellation, sideOrientation: number = Mesh.DEFAULTSIDE) {
             var indices = [];
             var positions = [];
             var normals = [];
@@ -744,9 +756,13 @@
                 }
             }
 
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
+
             // Result
             var vertexData = new VertexData();
 
+
             vertexData.indices = indices;
             vertexData.positions = positions;
             vertexData.normals = normals;
@@ -958,7 +974,7 @@
             return vertexData;
         }
 
-        public static CreatePlane(size: number): VertexData {
+        public static CreatePlane(size: number, sideOrientation: number = Mesh.DEFAULTSIDE): VertexData {
             var indices = [];
             var positions = [];
             var normals = [];
@@ -993,6 +1009,9 @@
             indices.push(2);
             indices.push(3);
 
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
+
             // Result
             var vertexData = new VertexData();
 
@@ -1005,7 +1024,7 @@
         }
 
         // based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473
-        public static CreateTorusKnot(radius: number, tube: number, radialSegments: number, tubularSegments: number, p: number, q: number): VertexData {
+        public static CreateTorusKnot(radius: number, tube: number, radialSegments: number, tubularSegments: number, p: number, q: number, sideOrientation: number = Mesh.DEFAULTSIDE): VertexData {
             var indices = [];
             var positions = [];
             var normals = [];
@@ -1079,6 +1098,9 @@
             // Normals
             VertexData.ComputeNormals(positions, indices, normals);
 
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
+
             // Result
             var vertexData = new VertexData();
 
@@ -1136,5 +1158,60 @@
                 normals[index * 3 + 2] = normal.z;
             }
         }
+
+        public static ComputeSides(sideOrientation: number, positions: number[], indices: number[], normals: number[], uvs: number[]) {
+            var li: number = indices.length;
+            var ln: number = normals.length;
+            var i: number;
+            var n: number;
+            sideOrientation = sideOrientation || Mesh.DEFAULTSIDE;
+
+            switch (sideOrientation) {
+
+                case Mesh.FRONTSIDE:
+                    // nothing changed
+                    break;
+
+                case Mesh.BACKSIDE:
+                    var tmp: number;
+                    // positions unchanged
+                    // indices
+                    for (i = 0; i < li; i += 3) {
+                        tmp = indices[i];
+                        indices[i] = indices[i + 2];
+                        indices[i + 2] = tmp;
+                    }
+                    // normals
+                    for (n = 0; n < ln; n++) {
+                        normals[n] = -normals[n];
+                    }
+                    // uvs unchanged                    
+                    break;
+
+                case Mesh.DOUBLESIDE:
+                    // positions 
+                    var lp: number = positions.length;
+                    var l: number = lp / 3;
+                    for (var p = 0; p < lp; p++) {
+                        positions[lp + p] = positions[p];
+                    }
+                    // indices
+                    for (i = 0; i < li; i += 3) {
+                        indices[i + li] = indices[i + 2] + l;
+                        indices[i + 1 + li] = indices[i + 1] + l;
+                        indices[i + 2 + li] = indices[i] + l;
+                    }
+                    // normals
+                    for (n = 0; n < ln; n++) {
+                        normals[ln + n] = -normals[n];
+                    }
+                    // uvs
+                    var lu: number = uvs.length;
+                    for (var u: number = 0; u < lu; u++) {
+                        uvs[u + lu] = uvs[u];
+                    }
+                    break;
+            }
+        }
     }
-} 
+} 

+ 155 - 39
babylon.2.1-alpha.debug.js

@@ -10067,6 +10067,34 @@ var BABYLON;
                 this.parent = parent;
             }
         }
+        Object.defineProperty(Mesh, "FRONTSIDE", {
+            get: function () {
+                return Mesh._FRONTSIDE;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Mesh, "BACKSIDE", {
+            get: function () {
+                return Mesh._BACKSIDE;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Mesh, "DOUBLESIDE", {
+            get: function () {
+                return Mesh._DOUBLESIDE;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Mesh, "DEFAULTSIDE", {
+            get: function () {
+                return Mesh._DEFAULTSIDE;
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(Mesh.prototype, "hasLODLevels", {
             // Methods
             get: function () {
@@ -10264,7 +10292,7 @@ var BABYLON;
             var totalIndices = this.getTotalIndices();
             var subdivisionSize = (totalIndices / count) | 0;
             var offset = 0;
-            while (subdivisionSize % 3 != 0) {
+            while (subdivisionSize % 3 !== 0) {
                 subdivisionSize++;
             }
             this.releaseSubMeshes();
@@ -10887,26 +10915,30 @@ var BABYLON;
             }
         };
         // Statics
-        Mesh.CreateRibbon = function (name, pathArray, closeArray, closePath, offset, scene, updatable) {
+        Mesh.CreateRibbon = function (name, pathArray, closeArray, closePath, offset, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             var ribbon = new Mesh(name, scene);
-            var vertexData = BABYLON.VertexData.CreateRibbon(pathArray, closeArray, closePath, offset);
+            var vertexData = BABYLON.VertexData.CreateRibbon(pathArray, closeArray, closePath, offset, sideOrientation);
             vertexData.applyToMesh(ribbon, updatable);
             return ribbon;
         };
-        Mesh.CreateBox = function (name, size, scene, updatable) {
+        Mesh.CreateBox = function (name, size, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             var box = new Mesh(name, scene);
-            var vertexData = BABYLON.VertexData.CreateBox(size);
+            var vertexData = BABYLON.VertexData.CreateBox(size, sideOrientation);
             vertexData.applyToMesh(box, updatable);
             return box;
         };
-        Mesh.CreateSphere = function (name, segments, diameter, scene, updatable) {
+        Mesh.CreateSphere = function (name, segments, diameter, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             var sphere = new Mesh(name, scene);
-            var vertexData = BABYLON.VertexData.CreateSphere(segments, diameter);
+            var vertexData = BABYLON.VertexData.CreateSphere(segments, diameter, sideOrientation);
             vertexData.applyToMesh(sphere, updatable);
             return sphere;
         };
         // Cylinder and cone (Code inspired by SharpDX.org)
-        Mesh.CreateCylinder = function (name, height, diameterTop, diameterBottom, tessellation, subdivisions, scene, updatable) {
+        Mesh.CreateCylinder = function (name, height, diameterTop, diameterBottom, tessellation, subdivisions, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             // subdivisions is a new parameter, we need to support old signature
             if (scene === undefined || !(scene instanceof BABYLON.Scene)) {
                 if (scene !== undefined) {
@@ -10921,15 +10953,17 @@ var BABYLON;
             return cylinder;
         };
         // Torus  (Code from SharpDX.org)
-        Mesh.CreateTorus = function (name, diameter, thickness, tessellation, scene, updatable) {
+        Mesh.CreateTorus = function (name, diameter, thickness, tessellation, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             var torus = new Mesh(name, scene);
-            var vertexData = BABYLON.VertexData.CreateTorus(diameter, thickness, tessellation);
+            var vertexData = BABYLON.VertexData.CreateTorus(diameter, thickness, tessellation, sideOrientation);
             vertexData.applyToMesh(torus, updatable);
             return torus;
         };
-        Mesh.CreateTorusKnot = function (name, radius, tube, radialSegments, tubularSegments, p, q, scene, updatable) {
+        Mesh.CreateTorusKnot = function (name, radius, tube, radialSegments, tubularSegments, p, q, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             var torusKnot = new Mesh(name, scene);
-            var vertexData = BABYLON.VertexData.CreateTorusKnot(radius, tube, radialSegments, tubularSegments, p, q);
+            var vertexData = BABYLON.VertexData.CreateTorusKnot(radius, tube, radialSegments, tubularSegments, p, q, sideOrientation);
             vertexData.applyToMesh(torusKnot, updatable);
             return torusKnot;
         };
@@ -10941,9 +10975,10 @@ var BABYLON;
             return lines;
         };
         // Plane & ground
-        Mesh.CreatePlane = function (name, size, scene, updatable) {
+        Mesh.CreatePlane = function (name, size, scene, updatable, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }
             var plane = new Mesh(name, scene);
-            var vertexData = BABYLON.VertexData.CreatePlane(size);
+            var vertexData = BABYLON.VertexData.CreatePlane(size, sideOrientation);
             vertexData.applyToMesh(plane, updatable);
             return plane;
         };
@@ -11050,6 +11085,11 @@ var BABYLON;
             }
             return newMesh;
         };
+        // Consts
+        Mesh._FRONTSIDE = 0;
+        Mesh._BACKSIDE = 1;
+        Mesh._DOUBLESIDE = 2;
+        Mesh._DEFAULTSIDE = 0;
         return Mesh;
     })(BABYLON.AbstractMesh);
     BABYLON.Mesh = Mesh;
@@ -20974,7 +21014,8 @@ var BABYLON;
             result.indices = meshOrGeometry.getIndices();
             return result;
         };
-        VertexData.CreateRibbon = function (pathArray, closeArray, closePath, offset) {
+        VertexData.CreateRibbon = function (pathArray, closeArray, closePath, offset, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             closeArray = closeArray || false;
             closePath = closePath || false;
             var defaultOffset = Math.floor(pathArray[0].length / 2);
@@ -21109,6 +21150,8 @@ var BABYLON;
             }
             // normals
             VertexData.ComputeNormals(positions, indices, normals);
+            // sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -21117,7 +21160,8 @@ var BABYLON;
             vertexData.uvs = uvs;
             return vertexData;
         };
-        VertexData.CreateBox = function (size) {
+        VertexData.CreateBox = function (size, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             var normalsSource = [
                 new BABYLON.Vector3(0, 0, 1),
                 new BABYLON.Vector3(0, 0, -1),
@@ -21162,6 +21206,8 @@ var BABYLON;
                 normals.push(normal.x, normal.y, normal.z);
                 uvs.push(1.0, 0.0);
             }
+            // sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -21170,7 +21216,8 @@ var BABYLON;
             vertexData.uvs = uvs;
             return vertexData;
         };
-        VertexData.CreateSphere = function (segments, diameter) {
+        VertexData.CreateSphere = function (segments, diameter, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             segments = segments || 32;
             diameter = diameter || 1;
             var radius = diameter / 2;
@@ -21208,6 +21255,8 @@ var BABYLON;
                     }
                 }
             }
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -21216,8 +21265,9 @@ var BABYLON;
             vertexData.uvs = uvs;
             return vertexData;
         };
-        VertexData.CreateCylinder = function (height, diameterTop, diameterBottom, tessellation, subdivisions) {
+        VertexData.CreateCylinder = function (height, diameterTop, diameterBottom, tessellation, subdivisions, sideOrientation) {
             if (subdivisions === void 0) { subdivisions = 1; }
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             var radiusTop = diameterTop / 2;
             var radiusBottom = diameterBottom / 2;
             var indices = [];
@@ -21302,6 +21352,8 @@ var BABYLON;
             createCylinderCap(false);
             // Normals
             VertexData.ComputeNormals(positions, indices, normals);
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -21310,7 +21362,8 @@ var BABYLON;
             vertexData.uvs = uvs;
             return vertexData;
         };
-        VertexData.CreateTorus = function (diameter, thickness, tessellation) {
+        VertexData.CreateTorus = function (diameter, thickness, tessellation, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             var indices = [];
             var positions = [];
             var normals = [];
@@ -21348,6 +21401,8 @@ var BABYLON;
                     indices.push(nextI * stride + j);
                 }
             }
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -21515,7 +21570,8 @@ var BABYLON;
             vertexData.uvs = uvs;
             return vertexData;
         };
-        VertexData.CreatePlane = function (size) {
+        VertexData.CreatePlane = function (size, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             var indices = [];
             var positions = [];
             var normals = [];
@@ -21542,6 +21598,8 @@ var BABYLON;
             indices.push(0);
             indices.push(2);
             indices.push(3);
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -21551,7 +21609,8 @@ var BABYLON;
             return vertexData;
         };
         // based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473
-        VertexData.CreateTorusKnot = function (radius, tube, radialSegments, tubularSegments, p, q) {
+        VertexData.CreateTorusKnot = function (radius, tube, radialSegments, tubularSegments, p, q, sideOrientation) {
+            if (sideOrientation === void 0) { sideOrientation = BABYLON.Mesh.DEFAULTSIDE; }
             var indices = [];
             var positions = [];
             var normals = [];
@@ -21613,6 +21672,8 @@ var BABYLON;
             }
             // Normals
             VertexData.ComputeNormals(positions, indices, normals);
+            // Sides
+            VertexData.ComputeSides(sideOrientation, positions, indices, normals, uvs);
             // Result
             var vertexData = new VertexData();
             vertexData.indices = indices;
@@ -21659,6 +21720,49 @@ var BABYLON;
                 normals[index * 3 + 2] = normal.z;
             }
         };
+        VertexData.ComputeSides = function (sideOrientation, positions, indices, normals, uvs) {
+            var li = indices.length;
+            var ln = normals.length;
+            var i;
+            var n;
+            sideOrientation = sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
+            switch (sideOrientation) {
+                case BABYLON.Mesh.FRONTSIDE:
+                    break;
+                case BABYLON.Mesh.BACKSIDE:
+                    var tmp;
+                    for (i = 0; i < li; i += 3) {
+                        tmp = indices[i];
+                        indices[i] = indices[i + 2];
+                        indices[i + 2] = tmp;
+                    }
+                    for (n = 0; n < ln; n++) {
+                        normals[n] = -normals[n];
+                    }
+                    break;
+                case BABYLON.Mesh.DOUBLESIDE:
+                    // positions 
+                    var lp = positions.length;
+                    var l = lp / 3;
+                    for (var p = 0; p < lp; p++) {
+                        positions[lp + p] = positions[p];
+                    }
+                    for (i = 0; i < li; i += 3) {
+                        indices[i + li] = indices[i + 2] + l;
+                        indices[i + 1 + li] = indices[i + 1] + l;
+                        indices[i + 2 + li] = indices[i] + l;
+                    }
+                    for (n = 0; n < ln; n++) {
+                        normals[ln + n] = -normals[n];
+                    }
+                    // uvs
+                    var lu = uvs.length;
+                    for (var u = 0; u < lu; u++) {
+                        uvs[u + lu] = uvs[u];
+                    }
+                    break;
+            }
+        };
         return VertexData;
     })();
     BABYLON.VertexData = VertexData;
@@ -24232,68 +24336,76 @@ var BABYLON;
             Primitives._Primitive = _Primitive;
             var Box = (function (_super) {
                 __extends(Box, _super);
-                function Box(id, scene, size, canBeRegenerated, mesh) {
+                function Box(id, scene, size, canBeRegenerated, mesh, side) {
+                    if (side === void 0) { side = BABYLON.Mesh.DEFAULTSIDE; }
                     this.size = size;
+                    this.side = side;
                     _super.call(this, id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
                 }
                 Box.prototype._regenerateVertexData = function () {
-                    return BABYLON.VertexData.CreateBox(this.size);
+                    return BABYLON.VertexData.CreateBox(this.size, this.side);
                 };
                 Box.prototype.copy = function (id) {
-                    return new Box(id, this.getScene(), this.size, this.canBeRegenerated(), null);
+                    return new Box(id, this.getScene(), this.size, this.canBeRegenerated(), null, this.side);
                 };
                 return Box;
             })(_Primitive);
             Primitives.Box = Box;
             var Sphere = (function (_super) {
                 __extends(Sphere, _super);
-                function Sphere(id, scene, segments, diameter, canBeRegenerated, mesh) {
+                function Sphere(id, scene, segments, diameter, canBeRegenerated, mesh, side) {
+                    if (side === void 0) { side = BABYLON.Mesh.DEFAULTSIDE; }
                     this.segments = segments;
                     this.diameter = diameter;
+                    this.side = side;
                     _super.call(this, id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
                 }
                 Sphere.prototype._regenerateVertexData = function () {
-                    return BABYLON.VertexData.CreateSphere(this.segments, this.diameter);
+                    return BABYLON.VertexData.CreateSphere(this.segments, this.diameter, this.side);
                 };
                 Sphere.prototype.copy = function (id) {
-                    return new Sphere(id, this.getScene(), this.segments, this.diameter, this.canBeRegenerated(), null);
+                    return new Sphere(id, this.getScene(), this.segments, this.diameter, this.canBeRegenerated(), null, this.side);
                 };
                 return Sphere;
             })(_Primitive);
             Primitives.Sphere = Sphere;
             var Cylinder = (function (_super) {
                 __extends(Cylinder, _super);
-                function Cylinder(id, scene, height, diameterTop, diameterBottom, tessellation, subdivisions, canBeRegenerated, mesh) {
+                function Cylinder(id, scene, height, diameterTop, diameterBottom, tessellation, subdivisions, canBeRegenerated, mesh, side) {
                     if (subdivisions === void 0) { subdivisions = 1; }
+                    if (side === void 0) { side = BABYLON.Mesh.DEFAULTSIDE; }
                     this.height = height;
                     this.diameterTop = diameterTop;
                     this.diameterBottom = diameterBottom;
                     this.tessellation = tessellation;
                     this.subdivisions = subdivisions;
+                    this.side = side;
                     _super.call(this, id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
                 }
                 Cylinder.prototype._regenerateVertexData = function () {
-                    return BABYLON.VertexData.CreateCylinder(this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions);
+                    return BABYLON.VertexData.CreateCylinder(this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions, this.side);
                 };
                 Cylinder.prototype.copy = function (id) {
-                    return new Cylinder(id, this.getScene(), this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions, this.canBeRegenerated(), null);
+                    return new Cylinder(id, this.getScene(), this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions, this.canBeRegenerated(), null, this.side);
                 };
                 return Cylinder;
             })(_Primitive);
             Primitives.Cylinder = Cylinder;
             var Torus = (function (_super) {
                 __extends(Torus, _super);
-                function Torus(id, scene, diameter, thickness, tessellation, canBeRegenerated, mesh) {
+                function Torus(id, scene, diameter, thickness, tessellation, canBeRegenerated, mesh, side) {
+                    if (side === void 0) { side = BABYLON.Mesh.DEFAULTSIDE; }
                     this.diameter = diameter;
                     this.thickness = thickness;
                     this.tessellation = tessellation;
+                    this.side = side;
                     _super.call(this, id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
                 }
                 Torus.prototype._regenerateVertexData = function () {
-                    return BABYLON.VertexData.CreateTorus(this.diameter, this.thickness, this.tessellation);
+                    return BABYLON.VertexData.CreateTorus(this.diameter, this.thickness, this.tessellation, this.side);
                 };
                 Torus.prototype.copy = function (id) {
-                    return new Torus(id, this.getScene(), this.diameter, this.thickness, this.tessellation, this.canBeRegenerated(), null);
+                    return new Torus(id, this.getScene(), this.diameter, this.thickness, this.tessellation, this.canBeRegenerated(), null, this.side);
                 };
                 return Torus;
             })(_Primitive);
@@ -24337,35 +24449,39 @@ var BABYLON;
             Primitives.TiledGround = TiledGround;
             var Plane = (function (_super) {
                 __extends(Plane, _super);
-                function Plane(id, scene, size, canBeRegenerated, mesh) {
+                function Plane(id, scene, size, canBeRegenerated, mesh, side) {
+                    if (side === void 0) { side = BABYLON.Mesh.DEFAULTSIDE; }
                     this.size = size;
+                    this.side = side;
                     _super.call(this, id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
                 }
                 Plane.prototype._regenerateVertexData = function () {
-                    return BABYLON.VertexData.CreatePlane(this.size);
+                    return BABYLON.VertexData.CreatePlane(this.size, this.side);
                 };
                 Plane.prototype.copy = function (id) {
-                    return new Plane(id, this.getScene(), this.size, this.canBeRegenerated(), null);
+                    return new Plane(id, this.getScene(), this.size, this.canBeRegenerated(), null, this.side);
                 };
                 return Plane;
             })(_Primitive);
             Primitives.Plane = Plane;
             var TorusKnot = (function (_super) {
                 __extends(TorusKnot, _super);
-                function TorusKnot(id, scene, radius, tube, radialSegments, tubularSegments, p, q, canBeRegenerated, mesh) {
+                function TorusKnot(id, scene, radius, tube, radialSegments, tubularSegments, p, q, canBeRegenerated, mesh, side) {
+                    if (side === void 0) { side = BABYLON.Mesh.DEFAULTSIDE; }
                     this.radius = radius;
                     this.tube = tube;
                     this.radialSegments = radialSegments;
                     this.tubularSegments = tubularSegments;
                     this.p = p;
                     this.q = q;
+                    this.side = side;
                     _super.call(this, id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
                 }
                 TorusKnot.prototype._regenerateVertexData = function () {
-                    return BABYLON.VertexData.CreateTorusKnot(this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q);
+                    return BABYLON.VertexData.CreateTorusKnot(this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q, this.side);
                 };
                 TorusKnot.prototype.copy = function (id) {
-                    return new TorusKnot(id, this.getScene(), this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q, this.canBeRegenerated(), null);
+                    return new TorusKnot(id, this.getScene(), this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q, this.canBeRegenerated(), null, this.side);
                 };
                 return TorusKnot;
             })(_Primitive);

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 9 - 9
babylon.2.1-alpha.js