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); }
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); }
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); }