فهرست منبع

Merge pull request #823 from jbousquie/feature.Cylinder.Enclose

Feature.cylinder.enclose
David Catuhe 9 سال پیش
والد
کامیت
6c02cdcd3c
2فایلهای تغییر یافته به همراه65 افزوده شده و 10 حذف شده
  1. 64 9
      src/Mesh/babylon.mesh.vertexData.ts
  2. 1 1
      src/Mesh/babylon.meshBuilder.ts

+ 64 - 9
src/Mesh/babylon.mesh.vertexData.ts

@@ -805,22 +805,30 @@
         }
 
         // Cylinder and cone 
-        public static CreateCylinder(options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], hasRings?: boolean, sideOrientation?: number }): VertexData {
+        public static CreateCylinder(options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], hasRings?: boolean, enclose?: boolean, sideOrientation?: number }): VertexData {
             var height: number = options.height || 2;
             var diameterTop: number = (options.diameterTop === 0) ? 0 : options.diameterTop || options.diameter || 1;
             var diameterBottom: number = options.diameterBottom || options.diameter || 1;
             var tessellation: number = options.tessellation || 24;
             var subdivisions: number = options.subdivisions || 1;
             var hasRings: boolean = options.hasRings;
+            var enclose: boolean = options.enclose;
             var arc: number = (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
             var sideOrientation: number = (options.sideOrientation === 0) ? 0 : options.sideOrientation || Mesh.DEFAULTSIDE;
             var faceUV: Vector4[] = options.faceUV || new Array<Vector4>(3);
             var faceColors: Color4[] = options.faceColors;
+    
             // default face colors and UV if undefined
-            for (var f = 0; f < 3; f++) {
+            var quadNb: number = (arc !==1 && enclose) ? 2 : 0;
+            var ringNb: number = (hasRings) ? subdivisions : 1;
+            var colorNb: number = 2 + (1 + quadNb) * ringNb; 
+            var f: number;
+            for (f = 0; f < colorNb; f++) {
                 if (faceColors && faceColors[f] === undefined) {
                     faceColors[f] = new Color4(1, 1, 1, 1);
                 }
+            }
+            for (f = 0; f < 3; f++) {
                 if (faceUV && faceUV[f] === undefined) {
                     faceUV[f] = new Vector4(0, 0, 1, 1);
                 }
@@ -839,12 +847,17 @@
             var tan = (diameterBottom - diameterTop) / 2 / height;
             var ringVertex: Vector3 = Vector3.Zero();
             var ringNormal: Vector3 = Vector3.Zero();
+            var ringFirstVertex: Vector3 = Vector3.Zero();
+            var ringFirstNormal: Vector3 = Vector3.Zero();
+            var quadNormal: Vector3 = Vector3.Zero();
+            var Y:Vector3 = Axis.Y;
 
             // positions, normals, uvs
             var i: number;
             var j: number;
             var r: number;
-            var ringIdx = 1;
+            var ringIdx: number = 1;
+            
             for (i = 0; i <= subdivisions; i++) {
                 h = i / subdivisions;
                 radius = (h * (diameterTop - diameterBottom) + diameterBottom) / 2;
@@ -852,9 +865,13 @@
                 for (r = 0; r < ringIdx; r++) {
                     for (j = 0; j <= tessellation; j++) {
                         angle = j * angle_step;
+
+                        // position
                         ringVertex.x = Math.cos(-angle) * radius;
                         ringVertex.y = -height / 2 + h * height;
                         ringVertex.z = Math.sin(-angle) * radius;
+
+                        // normal
                         if (diameterTop === 0 && i === subdivisions) {
                             // if no top cap, reuse former normals
                             ringNormal.x = normals[normals.length - (tessellation + 1) * 3];
@@ -867,6 +884,13 @@
                             ringNormal.y = Math.sqrt(ringNormal.x * ringNormal.x + ringNormal.z * ringNormal.z) * tan;
                             ringNormal.normalize();
                         }
+
+                        // keep first values for enclose
+                        if (j === 0) {
+                            ringFirstVertex.copyFrom(ringVertex);
+                            ringFirstNormal.copyFrom(ringNormal);
+                        }
+
                         positions.push(ringVertex.x, ringVertex.y, ringVertex.z);
                         normals.push(ringNormal.x, ringNormal.y, ringNormal.z);
                         uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x) * j / tessellation, faceUV[1].y + (faceUV[1].w - faceUV[1].y) * h);
@@ -874,21 +898,52 @@
                             colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
                         }
                     }
+
+                    // if enclose, add four vertices and their dedicated normals
+                    if (arc !== 1 && enclose) {                 
+                        positions.push(ringVertex.x, ringVertex.y, ringVertex.z);
+                        positions.push(0, ringVertex.y, 0);
+                        positions.push(0, ringVertex.y, 0);
+                        positions.push(ringFirstVertex.x, ringFirstVertex.y, ringFirstVertex.z);
+                        Vector3.CrossToRef(Y, ringNormal, quadNormal);
+                        quadNormal.normalize();
+                        normals.push(quadNormal.x, quadNormal.y, quadNormal.z, quadNormal.x, quadNormal.y, quadNormal.z);
+                        Vector3.CrossToRef(ringFirstNormal, Y, quadNormal);
+                        quadNormal.normalize();
+                        normals.push(quadNormal.x, quadNormal.y, quadNormal.z, quadNormal.x, quadNormal.y, quadNormal.z);                        
+                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
+                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
+                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
+                        uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
+                        if (faceColors) {
+                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
+                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
+                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
+                            colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
+                        }
+                    }
                 }
             }
 
             // indices
-            var s;
+            var e: number = (arc !== 1 && enclose) ? tessellation + 4 : tessellation;     // correction of number of iteration if enclose
+            var s: number;
             i = 0;
             for (s = 0; s < subdivisions; s++) {
                 for (j = 0; j < tessellation; j++) {
-                    var i0 = i * (tessellation + 1) + j;
-                    var i1 = (i + 1) * (tessellation + 1) + j;
-                    var i2 = i * (tessellation + 1) + (j + 1);
-                    var i3 = (i + 1) * (tessellation + 1) + (j + 1);
+                    var i0 = i * (e + 1) + j;
+                    var i1 = (i + 1) * (e + 1) + j;
+                    var i2 = i * (e + 1) + (j + 1);
+                    var i3 = (i + 1) * (e + 1) + (j + 1);
                     indices.push(i0, i1, i2);
                     indices.push(i3, i2, i1);
                 }
+                if (arc != 1 && enclose) {      // if enclose, add two quads
+                    indices.push(i0 + 2, i1 + 2, i2 + 2);
+                    indices.push(i3 + 2, i2 + 2, i1 + 2);
+                    indices.push(i0 + 4, i1 + 4, i2 + 4);
+                    indices.push(i3 + 4, i2 + 4, i1 + 4);
+                }
                 i = (hasRings) ? (i + 2) : (i + 1);
             }
 
@@ -906,7 +961,7 @@
                 var u: Vector4 = (isTop) ? faceUV[2] : faceUV[0];
                 var c: Color4;
                 if (faceColors) {
-                    c = (isTop) ? faceColors[2] : faceColors[0];
+                    c = (isTop) ? faceColors[colorNb - 1] : faceColors[0];
                 }
                 // cap center
                 var vbase = positions.length / 3;

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

@@ -125,7 +125,7 @@
             }
         }
 
-        public static CreateCylinder(name: string, options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], updatable?: boolean, sideOrientation?: number }, scene: any): Mesh {
+        public static CreateCylinder(name: string, options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], updatable?: boolean, hasRings?: boolean, enclose?: boolean, sideOrientation?: number }, scene: any): Mesh {
             var cylinder = new Mesh(name, scene);
             var vertexData = VertexData.CreateCylinder(options);