예제 #1
0
        public static BasicMeshData GenerateIcosphere(int divs)
        {
            BasicMeshData mesh = new BasicMeshData();

            mesh.normals = new List <Vector3>();

            // foreach face, generate all vertices and triangles
            for (int i = 0; i < 20; i++)
            {
                Vector3 v0 = Icosahedron.verts[Icosahedron.tris[i * 3]];
                Vector3 v1 = Icosahedron.verts[Icosahedron.tris[i * 3 + 1]];
                Vector3 v2 = Icosahedron.verts[Icosahedron.tris[i * 3 + 2]];
                // add this icosa face to the global list
                int       n             = divs + 1; // n is number of verts along one side of the triangle
                int       prevVertCount = mesh.verts.Count;
                Vector3[] verts         = BarycentricVertices(n, v0, v1, v2).ToArray();
                mesh.verts.AddRange(verts);
                mesh.normals.AddRange(verts);
                mesh.tris.AddRange(BarycentricTriangulation(n, globalOffset: prevVertCount));
            }

            // cleanup duplicate verts
            mesh.RemoveDuplicateVertices();

            return(mesh);
        }
예제 #2
0
        public static BasicMeshData GenerateUVSphere(int divsLong, int divsLat)
        {
            BasicMeshData mesh = new BasicMeshData();

            mesh.normals = new List <Vector3>();

            int vertCount = divsLong * divsLat;
            int triCount  = divsLong * (divsLat - 1) * 2 - divsLong * 2;              // subtracting is to remove quads at the pole

            Vector3[] verts = new Vector3[vertCount];
            int       iVert = 0;

            // generate verts
            for (int iLo = 0; iLo < divsLong; iLo++)
            {
                float   tLong   = iLo / (float)divsLong;
                float   angLong = tLong * ShapesMath.TAU;
                Vector2 dirXZ   = ShapesMath.AngToDir(angLong);
                Vector3 dirLong = new Vector3(dirXZ.x, 0f, dirXZ.y);
                for (int iLa = 0; iLa < divsLat; iLa++)
                {
                    float   tLat    = iLa / (divsLat - 1f);
                    float   angLat  = Mathf.Lerp(-0.25f, 0.25f, tLat) * ShapesMath.TAU;
                    Vector2 dirProj = ShapesMath.AngToDir(angLat);
                    verts[iVert++] = dirLong * dirProj.x + Vector3.up * dirProj.y;
                }
            }

            // generate tris
            int[] tris = new int[triCount * 3];
            int   iTri = 0;

            for (int iLo = 0; iLo < divsLong; iLo++)
            {
                for (int iLa = 0; iLa < divsLat - 1; iLa++)
                {
                    int iRoot     = iLo * divsLat + iLa;
                    int iRootNext = (iRoot + divsLat) % vertCount;
                    if (iLa < divsLat - 2)                        // skip first and last (triangles at the poles)
                    {
                        tris[iTri++] = iRoot;
                        tris[iTri++] = iRoot + 1;
                        tris[iTri++] = iRootNext + 1;
                    }

                    if (iLa > 0)
                    {
                        tris[iTri++] = iRootNext + 1;
                        tris[iTri++] = iRootNext;
                        tris[iTri++] = iRoot;
                    }
                }
            }

            mesh.verts.AddRange(verts);
            mesh.tris.AddRange(tris);
            mesh.normals.AddRange(verts);
            mesh.RemoveDuplicateVertices();

            return(mesh);
        }
예제 #3
0
        public static BasicMeshData GenerateCapsule(int divs)
        {
            BasicMeshData mesh = new BasicMeshData();

            mesh.normals = new List <Vector3>();

            int sides = divs * 4;

            for (int z = 0; z < 2; z++)
            {
                for (int i = 0; i < sides; i++)
                {
                    float   t = i / (float)sides;
                    Vector3 v = ShapesMath.AngToDir(t * ShapesMath.TAU);
                    mesh.normals.Add(v);
                    v.z = z;
                    mesh.verts.Add(v);
                }
            }

            // sides
            for (int i = 0; i < sides; i++)
            {
                int low0 = i;
                int top0 = sides + i;
                int low1 = (i + 1) % sides;
                int top1 = sides + (i + 1) % sides;
                mesh.tris.Add(low0);
                mesh.tris.Add(low1);
                mesh.tris.Add(top1);
                mesh.tris.Add(top1);
                mesh.tris.Add(top0);
                mesh.tris.Add(low0);
            }

            // round caps!
            int n = divs + 1;

            Vector3[] octaBaseVerts = { Vector3.right, Vector3.up, Vector3.left, Vector3.down };
            for (int z = 0; z < 2; z++)
            {
                // half-octahedron
                for (int s = 0; s < 4; s++)
                {
                    Vector3 v0 = z == 0 ? Vector3.back : Vector3.forward;                     // reverse depending on z
                    Vector3 v1 = octaBaseVerts[s];
                    Vector3 v2 = octaBaseVerts[(s + 1) % 4];

                    Vector3[] verts = BarycentricVertices(n, v0, v1, v2).ToArray();
                    mesh.normals.AddRange(verts);
                    if (z == 0)
                    {
                        mesh.tris.AddRange(BarycentricTriangulation(n, mesh.verts.Count).Reverse());
                        mesh.verts.AddRange(verts.Select(x => x));
                    }
                    else
                    {
                        mesh.tris.AddRange(BarycentricTriangulation(n, mesh.verts.Count));
                        mesh.verts.AddRange(verts.Select(x => x + Vector3.forward));
                    }
                }
            }

            mesh.RemoveDuplicateVertices();

            return(mesh);
        }