Преглед изворни кода

New CreateIcoSphere function

David Catuhe пре 9 година
родитељ
комит
d40caf92c8

Разлика између датотеке није приказан због своје велике величине
+ 9 - 9
dist/preview release/babylon.core.js


Разлика између датотеке није приказан због своје велике величине
+ 873 - 853
dist/preview release/babylon.d.ts


Разлика између датотеке није приказан због своје велике величине
+ 13 - 13
dist/preview release/babylon.js


Разлика између датотеке није приказан због своје велике величине
+ 215 - 1
dist/preview release/babylon.max.js


Разлика између датотеке није приказан због своје велике величине
+ 13 - 13
dist/preview release/babylon.noworker.js


+ 1 - 0
dist/preview release/what's new.md

@@ -10,6 +10,7 @@
       - New .obj serializer ([BitOfGold](https://github.com/BitOfGold))
     - Sprites now can be [picked](http://www.babylonjs-playground.com/#1XMVZW#3) and can use [actions](http://www.babylonjs-playground.com/#9RUHH#3) ([deltakosh](https://github.com/deltakosh))
     - New `Mesh.CreatePolygon()` method ([jerome](https://github.com/jbousquie))
+    - New `Mesh.CreateIcoSphere()` method. [Demo here](http://www.babylonjs-playground.com/#24DUYD) (G'kar)
     - Introducing [babylon.core.js](http://doc.babylonjs.com/generals/Framework_versions) ([deltakosh](https://github.com/deltakosh))
   - **Updates**
     - Adding `StandardMaterial.linkEmissiveWithDiffuse` to, well, link emissive with diffuse value. (With)[http://www.babylonjs-playground.com/#2FPUCS#2] and (without)[http://www.babylonjs-playground.com/#2FPUCS#1] ([deltakosh](https://github.com/deltakosh))

+ 3 - 0
src/Mesh/babylon.mesh.js

@@ -1256,6 +1256,9 @@ var BABYLON;
         Mesh.CreatePolyhedron = function (name, options, scene) {
             return BABYLON.MeshBuilder.CreatePolyhedron(name, options, scene);
         };
+        Mesh.CreateIcoSphere = function (name, options, scene) {
+            return BABYLON.MeshBuilder.CreateIcoSphere(name, options, scene);
+        };
         // Decals
         Mesh.CreateDecal = function (name, sourceMesh, position, normal, size, angle) {
             var options = {

+ 4 - 0
src/Mesh/babylon.mesh.ts

@@ -1468,6 +1468,10 @@
             return MeshBuilder.CreatePolyhedron(name, options, scene);
         }
 
+        public static CreateIcoSphere(name: string, options: { radius?: number, flat?: number, subdivisions?: number, sideOrientation?: number, updatable?: boolean }, scene: Scene): Mesh {
+            return MeshBuilder.CreateIcoSphere(name, options, scene);
+        }
+
         // Decals
         public static CreateDecal(name: string, sourceMesh: AbstractMesh, position: Vector3, normal: Vector3, size: Vector3, angle: number): Mesh {
             var options = {

+ 204 - 0
src/Mesh/babylon.mesh.vertexData.js

@@ -1092,6 +1092,210 @@ var BABYLON;
             vertexData.uvs = uvs;
             return vertexData;
         };
+        VertexData.CreateIcoSphere = function (options) {
+            var sideOrientation = options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
+            var radius = options.radius || 1;
+            var flat = options.flat || false;
+            var subdivisions = options.subdivisions || 1;
+            var t = (1 + Math.sqrt(5)) / 2;
+            // 12 vertex x,y,z
+            var ico_vertices = [
+                -1, t, -0, 1, t, 0, -1, -t, 0, 1, -t, 0,
+                0, -1, -t, 0, 1, -t, 0, -1, t, 0, 1, t,
+                t, 0, 1, t, 0, -1, -t, 0, 1, -t, 0, -1 // v8-11
+            ];
+            // index of 3 vertex makes a face of icopshere
+            var ico_indices = [
+                0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,
+                1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,
+                3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,
+                4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1
+            ];
+            // uv as integer step (not pixels !)
+            var ico_vertexuv = [
+                4, 1, 2, 1, 6, 3, 5, 4,
+                4, 3, 3, 2, 7, 4, 3, 0,
+                1, 0, 0, 1, 5, 0, 5, 2 // v8-11
+            ];
+            // Vertices [0, 1, ...9, A, B] : position on UV plane (7,8,9,10=A have duplicate position)
+            // v=5h          9+  8+  7+
+            // v=4h        9+  3   6   A+
+            // v=3h      9+  4   2   A+
+            // v=2h    9+  5   B   A+
+            // v=1h  9   1   0   A+
+            // v=0h    8   7   A
+            //     u=0 1 2 3 4 5 6 7 8 9   *a
+            //
+            // uv step is u:1 or 0.5, v:cos(30)=sqrt(3)/2, ratio approx is 84/97
+            var ustep = 97 / 1024;
+            var vstep = 168 / 1024;
+            var uoffset = 50 / 1024;
+            var voffset = 51 / 1024;
+            var indices = [];
+            var positions = [];
+            var normals = [];
+            var uvs = [];
+            var current_indice = 0;
+            // prepare array of 3 vector (empty) (to be worked in place, shared for each face)
+            var face_vertex_pos = new Array(3);
+            var face_vertex_uv = new Array(3);
+            for (var v012 = 0; v012 < 3; v012++) {
+                face_vertex_pos[v012] = BABYLON.Vector3.Zero();
+                face_vertex_uv[v012] = BABYLON.Vector2.Zero();
+            }
+            // create all with normals
+            for (var face = 0; face < 20; face++) {
+                // 3 vertex per face
+                for (var v012 = 0; v012 < 3; v012++) {
+                    // look up vertex 0,1,2 to its index in 0 to 11
+                    var v_id = ico_indices[3 * face + v012];
+                    // vertex have 3D position (x,y,z)
+                    face_vertex_pos[v012].copyFromFloats(ico_vertices[3 * v_id], ico_vertices[3 * v_id + 1], ico_vertices[3 * v_id + 2]);
+                    // Normalize to get normal, then scale to radius
+                    face_vertex_pos[v012].normalize().scaleInPlace(radius);
+                    // uv from vertex ID (may need fix due to unwrap on texture plan, unalias needed)
+                    // vertex may get to different UV according to belonging face (see fix below)
+                    var fix = 0;
+                    // Vertice 9 UV to be fixed
+                    if (face === 5 && v012 === 2) {
+                        fix = 1;
+                    }
+                    if (face === 15 && v012 === 1) {
+                        fix = 2;
+                    }
+                    if (face === 10 && v012 === 1) {
+                        fix = 3;
+                    }
+                    if (face === 14 && v012 === 2) {
+                        fix = 4;
+                    }
+                    // vertice 10 UV to be fixed
+                    if (face === 4 && v012 === 1) {
+                        fix = 1;
+                    }
+                    if (face === 7 && v012 === 1) {
+                        fix = 2;
+                    }
+                    if (face === 17 && v012 === 2) {
+                        fix = 3;
+                    }
+                    if (face === 8 && v012 === 0) {
+                        fix = 4;
+                    }
+                    // vertice 7 UV to be fixed
+                    if (face === 8 && v012 === 1) {
+                        fix = 5;
+                    }
+                    if (face === 18 && v012 === 0) {
+                        fix = 5;
+                    }
+                    // vertice 8 UV to be fixed
+                    if (face === 13 && v012 === 2) {
+                        fix = 5;
+                    }
+                    if (face === 14 && v012 === 1) {
+                        fix = 5;
+                    }
+                    if (face === 18 && v012 === 2) {
+                        fix = 5;
+                    }
+                    //
+                    face_vertex_uv[v012].copyFromFloats((ico_vertexuv[2 * v_id] + fix) * ustep + uoffset, (ico_vertexuv[2 * v_id + 1] + fix) * vstep + voffset);
+                }
+                // Subdivide the face (interpolate pos, norm, uv)
+                // - pos is linear interpolation, then projected to sphere (converge polyhedron to sphere)
+                // - norm is linear interpolation of vertex corner normal
+                //   (to be checked if better to re-calc from face vertex, or if approximation is OK ??? )
+                // - uv is linear interpolation
+                //
+                // Topology is as below for sub-divide by 2
+                // vertex shown as v0,v1,v2
+                // interp index is i1 to progress in range [v0,v1[
+                // interp index is i2 to progress in range [v0,v2[
+                // face index as  (i1,i2)  for /\  : (i1,i2),(i1+1,i2),(i1,i2+1)
+                //            and (i1,i2)' for \/  : (i1+1,i2),(i1+1,i2+1),(i1,i2+1)
+                //
+                //
+                //                    i2    v2
+                //                    ^    ^
+                //                   /    / \
+                //                  /    /   \
+                //                 /    /     \
+                //                /    / (0,1) \
+                //               /    #---------\
+                //              /    / \ (0,0)'/ \
+                //             /    /   \     /   \
+                //            /    /     \   /     \
+                //           /    / (0,0) \ / (1,0) \
+                //          /    #---------#---------\
+                //              v0                    v1
+                //
+                //              --------------------> i1
+                //
+                // interp of (i1,i2):
+                //  along i2 :  x0=lerp(v0,v2, i2/S) <---> x1=lerp(v1,v2, i2/S)
+                //  along i1 :  lerp(x0,x1, i1/(S-i2))
+                //
+                // centroid of triangle is needed to get help normal computation
+                //  (c1,c2) are used for centroid location
+                var interp_vertex = function (i1, i2, c1, c2) {
+                    // vertex is interpolated from
+                    //   - face_vertex_pos[0..2]
+                    //   - face_vertex_uv[0..2]
+                    var pos_x0 = BABYLON.Vector3.Lerp(face_vertex_pos[0], face_vertex_pos[2], i2 / subdivisions);
+                    var pos_x1 = BABYLON.Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], i2 / subdivisions);
+                    var pos_interp = (subdivisions === i2) ? face_vertex_pos[2] : BABYLON.Vector3.Lerp(pos_x0, pos_x1, i1 / (subdivisions - i2));
+                    pos_interp.normalize().scaleInPlace(radius);
+                    var vertex_normal;
+                    if (flat) {
+                        // in flat mode, recalculate normal as face centroid normal
+                        var centroid_x0 = BABYLON.Vector3.Lerp(face_vertex_pos[0], face_vertex_pos[2], c2 / subdivisions);
+                        var centroid_x1 = BABYLON.Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], c2 / subdivisions);
+                        var centroid_interp = BABYLON.Vector3.Lerp(centroid_x0, centroid_x1, c1 / (subdivisions - c2));
+                        vertex_normal = BABYLON.Vector3.Normalize(centroid_interp);
+                    }
+                    else {
+                        // in smooth mode, recalculate normal from each single vertex position
+                        vertex_normal = BABYLON.Vector3.Normalize(pos_interp);
+                    }
+                    var uv_x0 = BABYLON.Vector2.Lerp(face_vertex_uv[0], face_vertex_uv[2], i2 / subdivisions);
+                    var uv_x1 = BABYLON.Vector2.Lerp(face_vertex_uv[1], face_vertex_uv[2], i2 / subdivisions);
+                    var uv_interp = (subdivisions === i2) ? face_vertex_uv[2] : BABYLON.Vector2.Lerp(uv_x0, uv_x1, i1 / (subdivisions - i2));
+                    positions.push(pos_interp.x, pos_interp.y, pos_interp.z);
+                    normals.push(vertex_normal.x, vertex_normal.y, vertex_normal.z);
+                    uvs.push(uv_interp.x, uv_interp.y);
+                    // push each vertex has member of a face
+                    // Same vertex can bleong to multiple face, it is pushed multiple time (duplicate vertex are present)
+                    indices.push(current_indice);
+                    current_indice++;
+                };
+                for (var i2 = 0; i2 < subdivisions; i2++) {
+                    for (var i1 = 0; i1 + i2 < subdivisions; i1++) {
+                        // face : (i1,i2)  for /\  :
+                        // interp for : (i1,i2),(i1+1,i2),(i1,i2+1)
+                        interp_vertex(i1, i2, i1 + 1.0 / 3, i2 + 1.0 / 3);
+                        interp_vertex(i1 + 1, i2, i1 + 1.0 / 3, i2 + 1.0 / 3);
+                        interp_vertex(i1, i2 + 1, i1 + 1.0 / 3, i2 + 1.0 / 3);
+                        if (i1 + i2 + 1 < subdivisions) {
+                            // face : (i1,i2)' for \/  :
+                            // interp for (i1+1,i2),(i1+1,i2+1),(i1,i2+1)
+                            interp_vertex(i1 + 1, i2, i1 + 2.0 / 3, i2 + 2.0 / 3);
+                            interp_vertex(i1 + 1, i2 + 1, i1 + 2.0 / 3, i2 + 2.0 / 3);
+                            interp_vertex(i1, i2 + 1, i1 + 2.0 / 3, i2 + 2.0 / 3);
+                        }
+                    }
+                }
+            }
+            // Sides
+            VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
+            // Result
+            var vertexData = new VertexData();
+            vertexData.indices = indices;
+            vertexData.positions = positions;
+            vertexData.normals = normals;
+            vertexData.uvs = uvs;
+            return vertexData;
+        };
         // inspired from // http://stemkoski.github.io/Three.js/Polyhedra.html
         VertexData.CreatePolyhedron = function (options) {
             // provided polyhedron types :

+ 201 - 0
src/Mesh/babylon.mesh.vertexData.ts

@@ -1335,6 +1335,207 @@
             return vertexData;
         }
 
+        public static CreateIcoSphere(options: {radius?: number, flat?: number, subdivisions?: number, sideOrientation?: number}): VertexData {
+            var sideOrientation = options.sideOrientation || Mesh.DEFAULTSIDE;
+            var radius = options.radius || 1;
+            var flat = options.flat || false;
+            var subdivisions = options.subdivisions || 1;
+
+            var t = (1 + Math.sqrt(5)) / 2;
+
+            // 12 vertex x,y,z
+            var ico_vertices = [
+                -1, t, -0, 1, t, 0, -1, -t, 0, 1, -t, 0, // v0-3
+                0, -1, -t, 0, 1, -t, 0, -1, t, 0, 1, t, // v4-7
+                t, 0, 1, t, 0, -1, -t, 0, 1, -t, 0, -1  // v8-11
+            ];
+
+            // index of 3 vertex makes a face of icopshere
+            var ico_indices = [
+                0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,
+                1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,
+                3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,
+                4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1
+            ];
+
+            // uv as integer step (not pixels !)
+            var ico_vertexuv = [
+                4, 1, 2, 1, 6, 3, 5, 4,  // v0-3
+                4, 3, 3, 2, 7, 4, 3, 0,  // v4-7
+                1, 0, 0, 1, 5, 0, 5, 2   // v8-11
+            ];
+            // Vertices [0, 1, ...9, A, B] : position on UV plane (7,8,9,10=A have duplicate position)
+            // v=5h          9+  8+  7+
+            // v=4h        9+  3   6   A+
+            // v=3h      9+  4   2   A+
+            // v=2h    9+  5   B   A+
+            // v=1h  9   1   0   A+
+            // v=0h    8   7   A
+            //     u=0 1 2 3 4 5 6 7 8 9   *a
+            //
+
+            // uv step is u:1 or 0.5, v:cos(30)=sqrt(3)/2, ratio approx is 84/97
+            var ustep = 97 / 1024;
+            var vstep = 168 / 1024;
+            var uoffset = 50 / 1024;
+            var voffset = 51 / 1024;
+
+            var indices = [];
+            var positions = [];
+            var normals = [];
+            var uvs = [];
+
+            var current_indice = 0;
+            // prepare array of 3 vector (empty) (to be worked in place, shared for each face)
+            var face_vertex_pos = new Array(3);
+            var face_vertex_uv = new Array(3);
+            for (var v012 = 0; v012 < 3; v012++) {
+                face_vertex_pos[v012] = Vector3.Zero();
+                face_vertex_uv[v012] = Vector2.Zero();
+            }
+            // create all with normals
+            for (var face = 0; face < 20; face++) {
+                // 3 vertex per face
+                for (var v012 = 0; v012 < 3; v012++) {
+                    // look up vertex 0,1,2 to its index in 0 to 11
+                    var v_id = ico_indices[3 * face + v012];
+                    // vertex have 3D position (x,y,z)
+                    face_vertex_pos[v012].copyFromFloats(
+                        ico_vertices[3 * v_id],
+                        ico_vertices[3 * v_id + 1],
+                        ico_vertices[3 * v_id + 2]);
+                    // Normalize to get normal, then scale to radius
+                    face_vertex_pos[v012].normalize().scaleInPlace(radius);
+
+                    // uv from vertex ID (may need fix due to unwrap on texture plan, unalias needed)
+                    // vertex may get to different UV according to belonging face (see fix below)
+                    var fix = 0;
+                    // Vertice 9 UV to be fixed
+                    if (face === 5 && v012 === 2) { fix = 1; }
+                    if (face === 15 && v012 === 1) { fix = 2; }
+                    if (face === 10 && v012 === 1) { fix = 3; }
+                    if (face === 14 && v012 === 2) { fix = 4; }
+                    // vertice 10 UV to be fixed
+                    if (face === 4 && v012 === 1) { fix = 1; }
+                    if (face === 7 && v012 === 1) { fix = 2; }
+                    if (face === 17 && v012 === 2) { fix = 3; }
+                    if (face === 8 && v012 === 0) { fix = 4; }
+                    // vertice 7 UV to be fixed
+                    if (face === 8 && v012 === 1) { fix = 5; }
+                    if (face === 18 && v012 === 0) { fix = 5; }
+                    // vertice 8 UV to be fixed
+                    if (face === 13 && v012 === 2) { fix = 5; }
+                    if (face === 14 && v012 === 1) { fix = 5; }
+                    if (face === 18 && v012 === 2) { fix = 5; }
+                    //
+                    face_vertex_uv[v012].copyFromFloats(
+                        (ico_vertexuv[2 * v_id] + fix) * ustep + uoffset,
+                        (ico_vertexuv[2 * v_id + 1] + fix) * vstep + voffset);
+
+                }
+
+                // Subdivide the face (interpolate pos, norm, uv)
+                // - pos is linear interpolation, then projected to sphere (converge polyhedron to sphere)
+                // - norm is linear interpolation of vertex corner normal
+                //   (to be checked if better to re-calc from face vertex, or if approximation is OK ??? )
+                // - uv is linear interpolation
+                //
+                // Topology is as below for sub-divide by 2
+                // vertex shown as v0,v1,v2
+                // interp index is i1 to progress in range [v0,v1[
+                // interp index is i2 to progress in range [v0,v2[
+                // face index as  (i1,i2)  for /\  : (i1,i2),(i1+1,i2),(i1,i2+1)
+                //            and (i1,i2)' for \/  : (i1+1,i2),(i1+1,i2+1),(i1,i2+1)
+                //
+                //
+                //                    i2    v2
+                //                    ^    ^
+                //                   /    / \
+                //                  /    /   \
+                //                 /    /     \
+                //                /    / (0,1) \
+                //               /    #---------\
+                //              /    / \ (0,0)'/ \
+                //             /    /   \     /   \
+                //            /    /     \   /     \
+                //           /    / (0,0) \ / (1,0) \
+                //          /    #---------#---------\
+                //              v0                    v1
+                //
+                //              --------------------> i1
+                //
+                // interp of (i1,i2):
+                //  along i2 :  x0=lerp(v0,v2, i2/S) <---> x1=lerp(v1,v2, i2/S)
+                //  along i1 :  lerp(x0,x1, i1/(S-i2))
+                //
+                // centroid of triangle is needed to get help normal computation
+                //  (c1,c2) are used for centroid location
+
+                var interp_vertex = (i1: number, i2: number, c1: number, c2: number) =>{
+                    // vertex is interpolated from
+                    //   - face_vertex_pos[0..2]
+                    //   - face_vertex_uv[0..2]
+                    var pos_x0 = Vector3.Lerp(face_vertex_pos[0], face_vertex_pos[2], i2 / subdivisions);
+                    var pos_x1 = Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], i2 / subdivisions);
+                    var pos_interp = (subdivisions === i2) ? face_vertex_pos[2] : Vector3.Lerp(pos_x0, pos_x1, i1 / (subdivisions - i2));
+                    pos_interp.normalize().scaleInPlace(radius);
+
+                    var vertex_normal;
+                    if (flat) {
+                        // in flat mode, recalculate normal as face centroid normal
+                        var centroid_x0 = Vector3.Lerp(face_vertex_pos[0], face_vertex_pos[2], c2 / subdivisions);
+                        var centroid_x1 = Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], c2 / subdivisions);
+                        var centroid_interp = Vector3.Lerp(centroid_x0, centroid_x1, c1 / (subdivisions - c2));
+                        vertex_normal = Vector3.Normalize(centroid_interp);
+                    } else {
+                        // in smooth mode, recalculate normal from each single vertex position
+                        vertex_normal = Vector3.Normalize(pos_interp);
+                    }
+
+                    var uv_x0 = Vector2.Lerp(face_vertex_uv[0], face_vertex_uv[2], i2 / subdivisions);
+                    var uv_x1 = Vector2.Lerp(face_vertex_uv[1], face_vertex_uv[2], i2 / subdivisions);
+                    var uv_interp = (subdivisions === i2) ? face_vertex_uv[2] : Vector2.Lerp(uv_x0, uv_x1, i1 / (subdivisions - i2));
+                    positions.push(pos_interp.x, pos_interp.y, pos_interp.z);
+                    normals.push(vertex_normal.x, vertex_normal.y, vertex_normal.z);
+                    uvs.push(uv_interp.x, uv_interp.y);
+                    // push each vertex has member of a face
+                    // Same vertex can bleong to multiple face, it is pushed multiple time (duplicate vertex are present)
+                    indices.push(current_indice);
+                    current_indice++;
+                }
+
+                for (var i2 = 0; i2 < subdivisions; i2++) {
+                    for (var i1 = 0; i1 + i2 < subdivisions; i1++) {
+                        // face : (i1,i2)  for /\  :
+                        // interp for : (i1,i2),(i1+1,i2),(i1,i2+1)
+                        interp_vertex(i1, i2, i1 + 1.0 / 3, i2 + 1.0 / 3);
+                        interp_vertex(i1 + 1, i2, i1 + 1.0 / 3, i2 + 1.0 / 3);
+                        interp_vertex(i1, i2 + 1, i1 + 1.0 / 3, i2 + 1.0 / 3);
+                        if (i1 + i2 + 1 < subdivisions) {
+                            // face : (i1,i2)' for \/  :
+                            // interp for (i1+1,i2),(i1+1,i2+1),(i1,i2+1)
+                            interp_vertex(i1 + 1, i2, i1 + 2.0 / 3, i2 + 2.0 / 3);
+                            interp_vertex(i1 + 1, i2 + 1, i1 + 2.0 / 3, i2 + 2.0 / 3);
+                            interp_vertex(i1, i2 + 1, i1 + 2.0 / 3, i2 + 2.0 / 3);
+                        }
+                    }
+                }
+            }
+
+
+            // Sides
+            VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
+
+            // Result
+            var vertexData = new VertexData();
+            vertexData.indices = indices;
+            vertexData.positions = positions;
+            vertexData.normals = normals;
+            vertexData.uvs = uvs;
+            return vertexData;
+        }
+
+
         // inspired from // http://stemkoski.github.io/Three.js/Polyhedra.html
         public static CreatePolyhedron(options: { type?: number, size?: number, sizeX?: number, sizeY?: number, sizeZ?: number, custom?: any, faceUV?: Vector4[], faceColors?: Color4[], singleFace?: boolean, sideOrientation?: number }): VertexData {
             // provided polyhedron types :

+ 7 - 0
src/Mesh/babylon.meshBuilder.js

@@ -21,6 +21,13 @@ var BABYLON;
             vertexData.applyToMesh(disc, options.updatable);
             return disc;
         };
+        MeshBuilder.CreateIcoSphere = function (name, options, scene) {
+            var sphere = new BABYLON.Mesh(name, scene);
+            var vertexData = BABYLON.VertexData.CreateIcoSphere(options);
+            vertexData.applyToMesh(sphere, options.updatable);
+            return sphere;
+        };
+        ;
         MeshBuilder.CreateRibbon = function (name, options, scene) {
             var pathArray = options.pathArray;
             var closeArray = options.closeArray;

+ 9 - 1
src/Mesh/babylon.meshBuilder.ts

@@ -19,7 +19,6 @@
         }
 
         public static CreateDisc(name: string, options: { radius?: number, tessellation?: number, arc?: number, updatable?: boolean, sideOrientation?: number }, scene: Scene): Mesh {
-
             var disc = new Mesh(name, scene);
             var vertexData = VertexData.CreateDisc(options);
 
@@ -28,6 +27,15 @@
             return disc;
         }
 
+        public static CreateIcoSphere(name: string, options: { radius?: number, flat?: number, subdivisions?: number, sideOrientation?: number, updatable?: boolean }, scene: Scene): Mesh {
+            var sphere = new Mesh(name, scene);
+            var vertexData = VertexData.CreateIcoSphere(options);
+
+            vertexData.applyToMesh(sphere, options.updatable);
+
+            return sphere;
+        };
+
         public static CreateRibbon(name: string, options: { pathArray: Vector3[][], closeArray?: boolean, closePath?: boolean, offset?: number, updatable?: boolean, sideOrientation?: number, instance?: Mesh }, scene?: Scene): Mesh {
             var pathArray = options.pathArray;
             var closeArray = options.closeArray;

+ 46 - 45
src/Shaders/default.fragment.fx

@@ -186,18 +186,18 @@ uniform sampler2D reflection2DSampler;
 #endif
 
 #ifdef REFLECTIONMAP_SKYBOX
-	varying vec3 vPositionUVW;
+varying vec3 vPositionUVW;
 #else
 #ifdef REFLECTIONMAP_EQUIRECTANGULAR
-	varying vec3 vDirectionW;
+varying vec3 vDirectionW;
 #endif
 
-	#if defined(REFLECTIONMAP_PLANAR) || defined(REFLECTIONMAP_CUBIC) || defined(REFLECTIONMAP_PROJECTION)
-		uniform mat4 reflectionMatrix;
-	#endif
-	#if defined(REFLECTIONMAP_SPHERICAL) || defined(REFLECTIONMAP_PROJECTION)
-		uniform mat4 view;
-	#endif
+#if defined(REFLECTIONMAP_PLANAR) || defined(REFLECTIONMAP_CUBIC) || defined(REFLECTIONMAP_PROJECTION)
+uniform mat4 reflectionMatrix;
+#endif
+#if defined(REFLECTIONMAP_SPHERICAL) || defined(REFLECTIONMAP_PROJECTION)
+uniform mat4 view;
+#endif
 #endif
 
 vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
@@ -287,10 +287,11 @@ float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float dar
 	return 1.0;
 }
 
-float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float bias, float darkness)
+float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float mapSize, float bias, float darkness)
 {
 	vec3 directionToLight = vPositionW - lightPosition;
 	float depth = length(directionToLight);
+	float diskScale = (1.0 - (1.0 + depth * 3.0)) / mapSize;
 
 	depth = clamp(depth, 0., 1.);
 
@@ -299,18 +300,18 @@ float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, fl
 	float visibility = 1.;
 
 	vec3 poissonDisk[4];
-	poissonDisk[0] = vec3(-0.094201624, 0.04, -0.039906216);
-	poissonDisk[1] = vec3(0.094558609, -0.04, -0.076890725);
-	poissonDisk[2] = vec3(-0.094184101, 0.01, -0.092938870);
-	poissonDisk[3] = vec3(0.034495938, -0.01, 0.029387760);
+	poissonDisk[0] = vec3(-1.0, 1.0, -1.0);
+	poissonDisk[1] = vec3(1.0, -1.0, -1.0);
+	poissonDisk[2] = vec3(-1.0, -1.0, -1.0);
+	poissonDisk[3] = vec3(1.0, -1.0, 1.0);
 
 	// Poisson Sampling
 	float biasedDepth = depth - bias;
 
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[0])) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[1])) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2])) < biasedDepth) visibility -= 0.25;
-	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3])) < biasedDepth) visibility -= 0.25;
+	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[0] * diskScale)) < biasedDepth) visibility -= 0.25;
+	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[1] * diskScale)) < biasedDepth) visibility -= 0.25;
+	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2] * diskScale)) < biasedDepth) visibility -= 0.25;
+	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3] * diskScale)) < biasedDepth) visibility -= 0.25;
 
 	return  min(1.0, visibility + darkness);
 }
@@ -679,17 +680,17 @@ void main(void) {
 	shadow = computeShadowWithVSM(vPositionFromLight0, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x);
 #else
 #ifdef SHADOWPCF0
-	#if defined(POINTLIGHT0)
-	shadow = computeShadowWithPCFCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x);
-	#else
+#if defined(POINTLIGHT0)
+	shadow = computeShadowWithPCFCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
+#else
 	shadow = computeShadowWithPCF(vPositionFromLight0, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
-	#endif
+#endif
 #else
-	#if defined(POINTLIGHT0)
+#if defined(POINTLIGHT0)
 	shadow = computeShadowCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
-	#else
+#else
 	shadow = computeShadow(vPositionFromLight0, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
-	#endif
+#endif
 #endif
 #endif
 #else
@@ -720,16 +721,16 @@ void main(void) {
 #else
 #ifdef SHADOWPCF1
 #if defined(POINTLIGHT1)
-	shadow = computeShadowWithPCFCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x);
+	shadow = computeShadowWithPCFCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
 #else
 	shadow = computeShadowWithPCF(vPositionFromLight1, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
 #endif
 #else
-	#if defined(POINTLIGHT1)
+#if defined(POINTLIGHT1)
 	shadow = computeShadowCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
-	#else
+#else
 	shadow = computeShadow(vPositionFromLight1, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
-	#endif
+#endif
 #endif
 #endif
 #else
@@ -760,16 +761,16 @@ void main(void) {
 #else
 #ifdef SHADOWPCF2
 #if defined(POINTLIGHT2)
-	shadow = computeShadowWithPCFCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x);
+	shadow = computeShadowWithPCFCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
 #else
 	shadow = computeShadowWithPCF(vPositionFromLight2, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
 #endif
 #else
-	#if defined(POINTLIGHT2)
+#if defined(POINTLIGHT2)
 	shadow = computeShadowCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
-	#else
+#else
 	shadow = computeShadow(vPositionFromLight2, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
-	#endif
+#endif
 #endif	
 #endif	
 #else
@@ -796,20 +797,20 @@ void main(void) {
 #endif
 #ifdef SHADOW3
 #ifdef SHADOWVSM3
-		shadow = computeShadowWithVSM(vPositionFromLight3, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
+	shadow = computeShadowWithVSM(vPositionFromLight3, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
 #else
 #ifdef SHADOWPCF3
 #if defined(POINTLIGHT3)
-	shadow = computeShadowWithPCFCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
+	shadow = computeShadowWithPCFCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
 #else
 	shadow = computeShadowWithPCF(vPositionFromLight3, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
 #endif
 #else
-	#if defined(POINTLIGHT3)
+#if defined(POINTLIGHT3)
 	shadow = computeShadowCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
-	#else
+#else
 	shadow = computeShadow(vPositionFromLight3, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
-	#endif
+#endif
 #endif	
 #endif	
 #else
@@ -843,7 +844,7 @@ void main(void) {
 #endif
 #endif
 
-	reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW, bias).rgb * vReflectionInfos.x ;
+	reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW, bias).rgb * vReflectionInfos.x;
 #else
 	vec2 coords = vReflectionUVW.xy;
 
@@ -917,9 +918,9 @@ void main(void) {
 #ifdef EMISSIVEASILLUMINATION
 	vec3 finalDiffuse = clamp(diffuseBase * diffuseColor + vAmbientColor, 0.0, 1.0) * baseColor.rgb;
 #else
-	#ifdef LINKEMISSIVEWITHDIFFUSE
+#ifdef LINKEMISSIVEWITHDIFFUSE
 	vec3 finalDiffuse = clamp((diffuseBase + emissiveColor) * diffuseColor + vAmbientColor, 0.0, 1.0) * baseColor.rgb;
-	#else
+#else
 	vec3 finalDiffuse = clamp(diffuseBase * diffuseColor + emissiveColor + vAmbientColor, 0.0, 1.0) * baseColor.rgb;
 #endif
 #endif
@@ -944,11 +945,11 @@ void main(void) {
 #ifdef LIGHTMAP
 	vec3 lightmapColor = texture2D(lightmapSampler, vLightmapUV).rgb * vLightmapInfos.y;
 
-	#ifdef USELIGHTMAPASSHADOWMAP
-		color.rgb *= lightmapColor;
-	#else
-		color.rgb += lightmapColor;
-	#endif
+#ifdef USELIGHTMAPASSHADOWMAP
+	color.rgb *= lightmapColor;
+#else
+	color.rgb += lightmapColor;
+#endif
 #endif
 
 #ifdef FOG