public override void CreateMesh() { GeneratedMesh = MeshGenerator.CreatePlane(Direction, Width, Height, WidthSegments, HeightSegments, GenerateNormals, GenerateUVs); }
public override void CreateMesh() { GeneratedMesh = MeshGenerator.CreateTorus(Radius, Thickness, Tessellation * 2, Tessellation, GenerateNormals, GenerateUVs); }
public override void CreateMesh() { GeneratedMesh = MeshGenerator.CreateWireBox(SizeX, SizeY, SizeZ); }
private Mesh Create(float radius, int tessellation, bool generateNormals, bool generateUVs, bool invert) { if (tessellation < 0) { tessellation = 0; } subdividedEdges = new Dictionary <UndirectedEdge, int>(); // Start with an octahedron; copy the data into the vertex/index collection. vertexPositions = new List <Vector3>(OctahedronVertices); indexList = new List <int>(OctahedronIndices); // We know these values by looking at the above index list for the octahedron. Despite the subdivisions that are // about to go on, these values aren't ever going to change because the vertices don't move around in the array. // We'll need these values later on to fix the singularities that show up at the poles. int northPoleIndex = 0; int southPoleIndex = 5; for (int iSubdivision = 0; iSubdivision < tessellation; ++iSubdivision) { // The new index collection after subdivision. var newIndices = new List <int>(); subdividedEdges.Clear(); int triangleCount = indexList.Count / 3; for (int iTriangle = 0; iTriangle < triangleCount; ++iTriangle) { // For each edge on this triangle, create a new vertex in the middle of that edge. // The winding order of the triangles we output are the same as the winding order of the inputs. // Indices of the vertices making up this triangle int iv0 = indexList[iTriangle * 3]; int iv1 = indexList[iTriangle * 3 + 1]; int iv2 = indexList[iTriangle * 3 + 2]; // Get the new vertices Vector3 v01; // vertex on the midpoint of v0 and v1 Vector3 v12; // ditto v1 and v2 Vector3 v20; // ditto v2 and v0 int iv01; // index of v01 int iv12; // index of v12 int iv20; // index of v20 // Add/get new vertices and their indices DivideEdge(iv0, iv1, out v01, out iv01); DivideEdge(iv1, iv2, out v12, out iv12); DivideEdge(iv0, iv2, out v20, out iv20); // Add the new indices. We have four new triangles from our original one: // v0 // o // /a\ // v20 o---o v01 // /b\c/d\ // v2 o---o---o v1 // v12 // a newIndices.Add(iv0); newIndices.Add(iv01); newIndices.Add(iv20); // b newIndices.Add(iv20); newIndices.Add(iv12); newIndices.Add(iv2); // d newIndices.Add(iv20); newIndices.Add(iv01); newIndices.Add(iv12); // d newIndices.Add(iv01); newIndices.Add(iv1); newIndices.Add(iv12); } indexList.Clear(); indexList.AddRange(newIndices); } // Now that we've completed subdivision, fill in the final vertex collection int vertexCount = vertexPositions.Count; vertices = new List <Vector3>(vertexCount); normals = new List <Vector3>(vertexCount); uvs = new List <Vector2>(vertexCount); for (int i = 0; i < vertexPositions.Count; ++i) { var vertexValue = vertexPositions[i]; var normal = vertexValue; normal.Normalize(); var pos = normal * radius; // calculate texture coordinates for this vertex float longitude = Mathf.Atan2(normal.x, -normal.z); float latitude = Mathf.Acos(normal.y); float u = (float)(longitude / (Mathf.PI * 2.0) + 0.5); float v = 1f - (float)(latitude / Mathf.PI); Vector2 texcoord = new Vector2(u, v); vertices.Add(pos); normals.Add(normal); uvs.Add(texcoord); } float eps = 1e-7f; // There are a couple of fixes to do. One is a texture coordinate wraparound fixup. At some point, there will be // a set of triangles somewhere in the mesh with texture coordinates such that the wraparound across 0.0/1.0 // occurs across that triangle. Eg. when the left hand side of the triangle has a U coordinate of 0.98 and the // right hand side has a U coordinate of 0.0. The intent is that such a triangle should render with a U of 0.98 to // 1.0, not 0.98 to 0.0. If we don't do this fixup, there will be a visible seam across one side of the sphere. // // Luckily this is relatively easy to fix. There is a straight edge which runs down the prime meridian of the // completed sphere. If you imagine the vertices along that edge, they circumscribe a semicircular arc starting at // y=1 and ending at y=-1, and sweeping across the range of z=0 to z=1. x stays zero. It's along this edge that we // need to duplicate our vertices - and provide the correct texture coordinates. int preCount = vertices.Count; indices = indexList.ToArray(); for (int i = 0; i < preCount; ++i) { // This vertex is on the prime meridian if position.x and texcoord.u are both zero (allowing for small epsilon). bool isOnPrimeMeridian = Mathf.Abs(vertices[i].x) < eps && Mathf.Abs(1f - uvs[i].x) < eps; if (isOnPrimeMeridian) { int newIndex = vertices.Count; // copy this vertex, correct the texture coordinate, and add the vertex vertices.Add(vertices[i]); normals.Add(normals[i]); uvs.Add(new Vector2(0f, uvs[i].y)); // Now find all the triangles which contain this vertex and update them if necessary for (int j = 0; j < indexList.Count; j += 3) { int triIndex0 = indices[j]; int triIndex1 = indices[j + 1]; int triIndex2 = indices[j + 2]; int jTemp = j; if (triIndex0 == i) { // nothing; just keep going } else if (triIndex1 == i) { int temp = triIndex0; triIndex0 = triIndex1; triIndex1 = temp; jTemp = j + 1; } else if (triIndex2 == i) { int temp = triIndex0; triIndex0 = triIndex2; triIndex2 = temp; jTemp = j + 2; } else { // this triangle doesn't use the vertex we're interested in continue; } // check the other two vertices to see if we might need to fix this triangle if (Mathf.Abs(uvs[triIndex0].x - uvs[triIndex1].x) > 0.5f || Mathf.Abs(uvs[triIndex0].x - uvs[triIndex2].x) > 0.5f) { // yep; replace the specified index to point to the new, corrected vertex indices[jTemp] = newIndex; } } } } FixPole(northPoleIndex); FixPole(southPoleIndex); Mesh m = new Mesh(); m.name = "GeoSphere"; m.vertices = vertices.ToArray(); m.SetIndices(indices, MeshTopology.Triangles, 0); if (generateNormals) { m.normals = normals.ToArray(); } if (generateUVs) { m.uv = uvs.ToArray(); } if (invert) { MeshGenerator.Invert(m); } return(m); }
public override void CreateMesh() { GeneratedMesh = MeshGenerator.CreateCylinder(Radius, Height, Sides, GenerateCaps, GenerateNormals, GenerateUVs, Invert); }
public override void CreateMesh() { GeneratedMesh = MeshGenerator.CreateArrow(Direction, LineLength, LineThickness, CapLength, CapThickness, CapOverhang, GenerateNormals); }
public override void CreateMesh() { GeneratedMesh = MeshGenerator.CreateTube(OuterRadius, InnerRadius, Height, Sides, GenerateNormals, GenerateUVs); }
public override void CreateMesh() { GeneratedMesh = MeshGenerator.CreateOutlinedBox(SizeX, SizeY, SizeZ, Outline, GenerateNormals, GenerateUVs); }