Ejemplo n.º 1
0
        /**
         *	Given a face and a point, this will add a vertex to the pb_Object and retriangulate the face.
         */
        public static bool AppendVerticesToFace(this pb_Object pb, pb_Face face, List <Vector3> points, out pb_Face newFace)
        {
            if (!face.isValid())
            {
                newFace = face;
                return(false);
            }

            // First order of business - project face to 2d
            int[]     distinctIndices = face.distinctIndices;
            Vector3[] verts           = pb.GetVertices(distinctIndices);

            // Get the face normal before modifying the vertex array
            Vector3 nrm      = pb_Math.Normal(pb.GetVertices(face.indices));
            Vector3 projAxis = pb_Math.GetProjectionAxis(nrm).ToVector3();

            // Add the new point
            Vector3[] t_verts = new Vector3[verts.Length + points.Count];
            System.Array.Copy(verts, 0, t_verts, 0, verts.Length);
            System.Array.Copy(points.ToArray(), 0, t_verts, verts.Length, points.Count);

            verts = t_verts;

            // Project
            List <Vector2> plane = new List <Vector2>(pb_Math.VerticesTo2DPoints(verts, projAxis));

            // Save the sharedIndices index for each distinct vertex
            pb_IntArray[] sharedIndices = pb.sharedIndices;
            int[]         sharedIndex   = new int[distinctIndices.Length + points.Count];
            for (int i = 0; i < distinctIndices.Length; i++)
            {
                sharedIndex[i] = sharedIndices.IndexOf(distinctIndices[i]);
            }

            for (int i = distinctIndices.Length; i < distinctIndices.Length + points.Count; i++)
            {
                sharedIndex[i] = -1;            // add the new vertex to it's own sharedIndex
            }
            // Triangulate the face with the new point appended
            int[] tris = Delauney.Triangulate(plane).ToIntArray();

            // Check to make sure the triangulated face is facing the same direction, and flip if not
            Vector3 del = Vector3.Cross(verts[tris[2]] - verts[tris[0]], verts[tris[1]] - verts[tris[0]]).normalized;

            if (Vector3.Dot(nrm, del) > 0)
            {
                System.Array.Reverse(tris);
            }

            // Compose new face
            newFace = pb.AppendFace(verts, new pb_Face(tris, face.material, new pb_UV(face.uv), face.smoothingGroup, face.textureGroup, -1, face.color), sharedIndex);

            // And delete the old
            pb.DeleteFace(face);

            return(true);
        }
Ejemplo n.º 2
0
        /**
         *	Given a face and a point, this will add a vertex to the pb_Object and retriangulate the face.
         */
        public static bool AppendVerticesToFace(this pb_Object pb, pb_Face face, Vector3[] points, Color[] addColors, out pb_Face newFace)
        {
            if (!face.IsValid())
            {
                newFace = face;
                return(false);
            }

            // First order of business - project face to 2d
            int[]     distinctIndices = face.distinctIndices;
            Vector3[] verts           = pb.GetVertices(distinctIndices);
            Color[]   cols            = pbUtil.ValuesWithIndices(pb.colors, distinctIndices);
            Vector2[] uvs             = new Vector2[distinctIndices.Length + points.Length];
            System.Array.Copy(pb.GetUVs(distinctIndices), 0, uvs, 0, distinctIndices.Length);

            // Add the new point
            Vector3[] t_verts = new Vector3[verts.Length + points.Length];
            System.Array.Copy(verts, 0, t_verts, 0, verts.Length);
            System.Array.Copy(points, 0, t_verts, verts.Length, points.Length);
            verts = t_verts;

            // Add the new color
            Color[] t_col = new Color[cols.Length + addColors.Length];
            System.Array.Copy(cols, 0, t_col, 0, cols.Length);
            System.Array.Copy(addColors, 0, t_col, cols.Length, addColors.Length);
            cols = t_col;

            // Get the face normal before modifying the vertex array
            Vector3 nrm      = pb_Math.Normal(pb.GetVertices(face.indices));
            Vector3 projAxis = pb_Math.ProjectionAxisToVector(pb_Math.VectorToProjectionAxis(nrm));

            // Project
            List <Vector2> plane = new List <Vector2>(pb_Math.PlanarProject(verts, projAxis));

            // Save the sharedIndices index for each distinct vertex
            pb_IntArray[] sharedIndices = pb.sharedIndices;
            int[]         sharedIndex   = new int[distinctIndices.Length + points.Length];
            for (int i = 0; i < distinctIndices.Length; i++)
            {
                sharedIndex[i] = sharedIndices.IndexOf(distinctIndices[i]);
            }

            for (int i = distinctIndices.Length; i < distinctIndices.Length + points.Length; i++)
            {
                sharedIndex[i] = -1;            // add the new vertex to it's own sharedIndex
            }
            // Triangulate the face with the new point appended
            int[] tris = Delaunay.Triangulate(plane).ToIntArray();

            // Check to make sure the triangulated face is facing the same direction, and flip if not
            Vector3 del = Vector3.Cross(verts[tris[2]] - verts[tris[0]], verts[tris[1]] - verts[tris[0]]).normalized;

            if (Vector3.Dot(nrm, del) > 0)
            {
                System.Array.Reverse(tris);
            }

            // Build the new face
            pb_Face triangulated_face = new pb_Face(tris, face.material, new pb_UV(face.uv), face.smoothingGroup, face.textureGroup, -1, face.manualUV);

            /**
             * Attempt to figure out where the new UV point(s) should go (if auto uv'ed face)
             */
            if (triangulated_face.manualUV)
            {
                for (int n = distinctIndices.Length; n < uvs.Length; n++)
                {
                    // these are the two vertices that are split by the new vertex
                    int[] adjacent_vertex = System.Array.FindAll(triangulated_face.edges, x => x.Contains(n)).Select(x => x.x != n ? x.x : x.y).ToArray();

                    if (adjacent_vertex.Length == 2)
                    {
                        uvs[n] = (uvs[adjacent_vertex[0]] + uvs[adjacent_vertex[1]]) / 2f;
                    }
                    else
                    {
                        Debug.LogWarning("Failed to find appropriate UV coordinate for new vertex point.  Setting face to AutoUV.");
                        triangulated_face.manualUV = false;
                    }
                }
            }

            // Compose new face
            newFace = pb.AppendFace(verts, cols, uvs, triangulated_face, sharedIndex);

            // And delete the old
            pb.DeleteFace(face);

            return(true);
        }