Esempio n. 1
0
        //fix pole vertices incorrect U
        private static Dictionary <int, float> FindAndFixPoleVertices(IPlatonicSolid solid, ref List <TriangleFace> faces, ref List <Vector3> vertices)
        {
            Vector3 north = solid.NorthPole;
            Vector3 south = -solid.NorthPole;

            List <int> poleVerticeInd = new List <int>();
            Dictionary <int, float> poleVertIndicesCorrectU = new Dictionary <int, float>();

            foreach (TriangleFace face in faces)
            {
                if (vertices[face.IndA] == north || vertices[face.IndA] == south)
                {
                    if (!poleVerticeInd.Contains(face.IndA))
                    {
                        poleVerticeInd.Add(face.IndA);
                    }
                    else
                    {
                        vertices.Add(vertices[face.IndA] == north ? north : south);
                        face.SetIndA(vertices.Count - 1);
                    }
                    float xCoordB    = GetUvCoordinates(vertices[face.IndB]).x;
                    float xCoordC    = GetUvCoordinates(vertices[face.IndC]).x;
                    float correctedU = (xCoordB + xCoordC) / 2f + 0.5f; // I am not sure why it is needed but it seems needed...

                    poleVertIndicesCorrectU[face.IndA] = correctedU;
                }
            }

            return(poleVertIndicesCorrectU);
        }
 private void GenerateSphereMeshThread(object obj)
 {
     if (SphereType == SphereType.uvsphere)
     {
         _sphereMesh = UvSphereBuilder.Generate(Radius, Resolution);
     }
     else
     {
         IPlatonicSolid baseSolid = GetBaseSolid(SphereType);
         _sphereMesh = SphereBuilder.Build(baseSolid, Radius, Resolution, Smooth, RemapVertices);
     }
     Debug.Log(SphereType.ToString() + " generated: " + _sphereMesh.Triangles.Length + " tris and " + _sphereMesh.Vertices.Length + " verts.");
 }
Esempio n. 3
0
        /// <summary>
        /// Generate a UV sphere.
        /// </summary>
        /// <param name="resolution">Number of latitude lines (vertices on the y axis).</param>
        public static MeshData Build(IPlatonicSolid platonic, float radius, int resolution, bool smooth, bool remapVertices)
        {
            List <Vector3>          vertices                = new List <Vector3>();
            List <int>              triangles               = new List <int>();
            List <TriangleFace>     faces                   = new List <TriangleFace>();
            Dictionary <long, int>  middlePointIndexCache   = new Dictionary <long, int>();
            Dictionary <int, int>   vertWithWarpedU         = new Dictionary <int, int>();
            Dictionary <int, float> poleVertIndicesCorrectU = new Dictionary <int, float>();

            Vector2[] uv;
            Vector3[] normals;
            Vector4[] tangents;

            Vector4 tangent = new Vector4(1f, 0f, 0f, -1f);

            // create the base cube primitive
            vertices = platonic.Vertices;
            faces    = platonic.Faces;

            // subdivide the triangles faces
            for (int i = 1; i < resolution; i++)
            {
                List <TriangleFace> newFaces = new List <TriangleFace>();
                foreach (var tri in faces)
                {
                    // replace triangle by 4 triangles
                    int a = GetMiddlePoint(tri.IndA, tri.IndB, ref vertices, ref middlePointIndexCache);
                    int b = GetMiddlePoint(tri.IndB, tri.IndC, ref vertices, ref middlePointIndexCache);
                    int c = GetMiddlePoint(tri.IndC, tri.IndA, ref vertices, ref middlePointIndexCache);

                    newFaces.Add(new TriangleFace(tri.IndA, a, c));
                    newFaces.Add(new TriangleFace(tri.IndB, b, a));
                    newFaces.Add(new TriangleFace(tri.IndC, c, b));
                    newFaces.Add(new TriangleFace(a, b, c));
                }
                faces = newFaces;
            }

            // fix warped uv on seam
            vertWithWarpedU         = FindAndFixeWarpedFaces(ref faces, ref vertices);
            poleVertIndicesCorrectU = FindAndFixPoleVertices(platonic, ref faces, ref vertices);

            // makes unique vertice to have a non smooth sphere
            if (!smooth)
            {
                MakeVerticesUnique(ref faces, ref vertices, ref vertWithWarpedU, ref poleVertIndicesCorrectU);
            }

            // create mesh triangles
            for (int i = 0; i < faces.Count; i++)
            {
                triangles.Add(faces[i].IndA);
                triangles.Add(faces[i].IndB);
                triangles.Add(faces[i].IndC);
            }

            if (remapVertices)
            {
                vertices = platonic.RemapVertices(vertices, faces);
            }

            // generate uv, normals, and tangents
            uv       = new Vector2[vertices.Count];
            normals  = new Vector3[vertices.Count];
            tangents = new Vector4[vertices.Count];

            for (int i = 0; i < vertices.Count; i++)
            {
                Vector3 normal = vertices[i].normalized;
                float   u      = (Mathf.Atan2(normal.z, normal.x) / (2f * Mathf.PI)) + 0.5f;          // remove the 0.5f
                float   v      = (Mathf.Asin(normal.y) / Mathf.PI) + 0.5f;

                vertices[i] = normal * radius;

                // correct uv issues
                if (poleVertIndicesCorrectU.ContainsKey(i))
                {
                    u = poleVertIndicesCorrectU[i];
                }

                if (vertWithWarpedU.ContainsValue(i))
                {
                    u += 1;
                }

                if (vertWithWarpedU.ContainsValue(i) && poleVertIndicesCorrectU.ContainsKey(i))
                {
                    u -= 0.5f;                     // found through trial and error, it was working so I had to remove the 0.5 added when recalculating
                }

                uv[i]       = new Vector2(u, v);
                normals[i]  = normal;
                tangents[i] = tangent;
            }

            // recompute normals
            if (!smooth)
            {
                foreach (TriangleFace face in faces)
                {
                    Vector3 normal = GetFaceCenter(face, vertices);
                    normals[face.IndA] = normal;
                    normals[face.IndB] = normal;
                    normals[face.IndC] = normal;
                }
            }

            return(new MeshData(vertices.ToArray(), triangles.ToArray(), uv, normals, tangents));
        }