Esempio n. 1
0
 public override void CreateMesh()
 {
     GeneratedMesh = MeshGenerator.CreatePlane(Direction, Width, Height, WidthSegments, HeightSegments, GenerateNormals, GenerateUVs);
 }
Esempio n. 2
0
 public override void CreateMesh()
 {
     GeneratedMesh = MeshGenerator.CreateTorus(Radius, Thickness, Tessellation * 2, Tessellation, GenerateNormals, GenerateUVs);
 }
Esempio n. 3
0
 public override void CreateMesh()
 {
     GeneratedMesh = MeshGenerator.CreateWireBox(SizeX, SizeY, SizeZ);
 }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
 public override void CreateMesh()
 {
     GeneratedMesh = MeshGenerator.CreateCylinder(Radius, Height, Sides, GenerateCaps, GenerateNormals, GenerateUVs, Invert);
 }
Esempio n. 6
0
 public override void CreateMesh()
 {
     GeneratedMesh = MeshGenerator.CreateArrow(Direction, LineLength, LineThickness, CapLength, CapThickness, CapOverhang, GenerateNormals);
 }
Esempio n. 7
0
 public override void CreateMesh()
 {
     GeneratedMesh = MeshGenerator.CreateTube(OuterRadius, InnerRadius, Height, Sides, GenerateNormals, GenerateUVs);
 }
Esempio n. 8
0
 public override void CreateMesh()
 {
     GeneratedMesh = MeshGenerator.CreateOutlinedBox(SizeX, SizeY, SizeZ, Outline, GenerateNormals, GenerateUVs);
 }