Пример #1
0
 public void AddNeighbor(PRVertex v)
 {
     if (!neighbor.Contains(v) && v != this)
     {
         neighbor.Add(v);
     }
 }
Пример #2
0
    private float ComputeEdgeCollapseCost(PRVertex u, PRVertex v)
    {
        float             edgeLength = Vector3.Distance(u.pos, v.pos);
        float             curvature  = 0f;
        List <PRTriangle> sides      = new List <PRTriangle>();

        for (int i = 0; i < u.face.Count; i++)
        {
            if (u.face[i].HasVertex(v))
            {
                sides.Add(u.face[i]);
            }
        }
        for (int i = 0; i < u.face.Count; i++)
        {
            float mincurv = 1f;
            for (int j = 0; j < sides.Count; j++)
            {
                float dotprod = Vector3.Dot(u.face[i].normal, sides[j].normal);
                mincurv = Mathf.Min(mincurv, (1f - dotprod) * 0.5f);
            }
            curvature = Mathf.Max(curvature, mincurv);
        }
        return(edgeLength * curvature);
    }
Пример #3
0
    public void ReplaceVertex(PRVertex u, PRVertex v)
    {
        if (u == null || v == null)
        {
            Debug.Log("a certain vertex is null.");
            return;
        }
        if (!(u == vertex[0] || u == vertex[1] || u == vertex[2]))
        {
            Debug.Log("old vertice is not one of the vertices in the triangle.");
            return;
        }
        if (v == vertex[0] || v == vertex[1] || v == vertex[2])
        {
            Debug.Log("new vertex can not be equal to vertex 0|1|2.");
            return;
        }
        if (vertex[0] == u)
        {
            vertex[0] = v;
        }
        else if (vertex[1] == u)
        {
            vertex[1] = v;
        }
        else if (vertex[2] == u)
        {
            vertex[2] = v;
        }
        else
        {
            Debug.Log("old vertex is not any of the tri verts.");
        }
        u.RemoveFace(this);
        v.AddFace(this);
        if (!v.face.Contains(this))
        {
            Debug.Log("v is not contain this face.");
        }
        for (int i = 0; i < 3; i++)
        {
            u.RemoveIfNonNeighbor(vertex[i]);
            vertex[i].RemoveIfNonNeighbor(u);
        }

        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                if (i != j)
                {
                    if (!vertex[i].neighbor.Contains(vertex[j]))
                    {
                        vertex[i].neighbor.Add(vertex[j]);
                    }
                }
            }
        }
        ComputeNormal();
    }
Пример #4
0
 public PRTriangle(int id, PRVertex v1, PRVertex v2, PRVertex v3)
 {
     this.id   = id;
     vertex[0] = v1;
     vertex[1] = v2;
     vertex[2] = v3;
     ComputeNormal();
 }
Пример #5
0
    private PRVertex MinCostVertex()
    {
        PRVertex vert = prVertices[0];

        for (int i = 0; i < prVertices.Count; i++)
        {
            if (prVertices[i].cost < vert.cost)
            {
                vert = prVertices[i];
            }
        }
        return(vert);
    }
Пример #6
0
 public void RemoveIfNonNeighbor(PRVertex n)
 {
     if (!neighbor.Contains(n))
     {
         return;
     }
     for (int i = 0; i < face.Count; i++)
     {
         if (face[i].HasVertex(n))
         {
             return;
         }
     }
     neighbor.Remove(n);
     if (neighbor.Contains(n))
     {
         Debug.Log("still exsist vertex n.");
     }
 }
Пример #7
0
 private void ComputeCostPerVertex(PRVertex v)
 {
     if (v.neighbor.Count == 0)
     {
         v.collapse = null;
         v.cost     = 100000f;
         return;
     }
     v.collapse = null;
     v.cost     = 1000000f;
     for (int i = 0; i < v.neighbor.Count; i++)
     {
         float c = ComputeEdgeCollapseCost(v, v.neighbor[i]);
         if (c < v.cost)
         {
             v.collapse = v.neighbor[i];
             v.cost     = c;
         }
     }
 }
Пример #8
0
    /// <summary>
    /// Paste the transformations on the original object to the this duplicated object.
    /// </summary>
    /// <param name="vertexHolderColl"> The list of the original object vertexHolders. </param>
    public void PasteAllGeoProperties(List <PRVertexHolder> vertexHolderColl)
    {
        for (int j = 0; j < vertexHolderColl.Count; j++)
        {
            PRVertexHolder vertHolder = vertexHolderColl[j];
            PRVertex       vertCO     = PR_VERTEX_GO.GetComponent <ParentVertex>().GEO_VERTEX_COLL_CO[j];
            // Update the vertexHolder.
            vertCO.VertexHolder = vertHolder;
            Vector3[] meshVertices = GeoMesh.vertices;
            // Update Mesh vertices.
            for (int i = 0; i < vertHolder.SameVIndexColl.Count; i++)
            {
                meshVertices[vertHolder.SameVIndexColl[i]] = vertHolder.V;
            }
            GeoMesh.vertices = meshVertices;
            GeoMesh.RecalculateBounds();

            // Update VertexGO position.
            vertCO.UpdateVertexPosition();
        }
    }
Пример #9
0
    public void ProgressiveMesh()
    {
        permutation  = new int[prVertices.Count];
        collapse_map = new int[prVertices.Count];
        while (prVertices.Count > 0)
        {
            PRVertex mn = MinCostVertex();
            permutation[mn.id] = prVertices.Count - 1;
            collapse_map[prVertices.Count - 1] = (mn.collapse != null) ? mn.collapse.id : -1;
            Collapse(mn, mn.collapse);
            if (mn.collapse != null)
            {
                Debug.Log((prVertices.Count - 1) + " " + mn.id + " " + mn.collapse.id);
            }
        }

        for (int i = 0; i < collapse_map.Length; i++)
        {
            collapse_map[i] = (collapse_map[i] == -1) ? 0 : permutation[collapse_map[i]];
        }
    }
Пример #10
0
    /// <summary>
    /// Clean up the duplicate vertices that share the same coordinates and Instantiate the Vertex prefabs.
    /// </summary>
    /// <param name="vertexColl"> Dirty array with vertex holders. </param>
    /// <returns> Clean array of Vertex holders. </returns>
    public PRVertexHolder[] CreateUniqVertexPrefabs(PRVertexHolder[] vertexColl)
    {
        // Group the vertices according to the position. For the cube I will have groups of 4 overlaping vertices.
        var result = vertexColl.GroupBy(vertex => vertex.V);

        PRVertexHolder[] cleanVertexColl = new PRVertexHolder[result.Count()];
        for (int i = 0; i < result.Count(); i++)
        {
            // Get only the first elemnt from each group and assign it to the clean array.
            cleanVertexColl[i] = result.ToArray()[i].ToArray()[0];
            // Create the objects.
            GameObject obj = GameObject.Instantiate(VertexPref, transform.TransformPoint(cleanVertexColl[i].V),
                                                    Quaternion.identity, PR_VERTEX_GO.transform);
            obj.name = "Vertex" + i;
            obj.SetActive(true);
            // Setup the PRVertex file
            PRVertex vertexCO = obj.GetComponent <PRVertex>();
            vertexCO.VertexHolder = cleanVertexColl[i];
        }

        return(cleanVertexColl);
    }
Пример #11
0
    //顶点和边的坍塌操作
    private void Collapse(PRVertex u, PRVertex v)
    {
        if (v == null)
        {
            u.DeleteVertex();
            prVertices.Remove(u);
            return;
        }
        List <PRVertex> tmp = new List <PRVertex>();

        for (int i = 0; i < u.neighbor.Count; i++)
        {
            tmp.Add(u.neighbor[i]);
        }
        for (int i = u.face.Count - 1; i >= 0; i--)
        {
            if (u.face[i].HasVertex(v))
            {
                prTriangles.Remove(u.face[i]);
                u.face[i].DeleteFace();
            }
        }

        for (int i = u.face.Count - 1; i >= 0; i--)
        {
            u.face[i].ReplaceVertex(u, v);
        }

        u.DeleteVertex();
        prVertices.Remove(u);

        for (int i = 0; i < tmp.Count; i++)
        {
            ComputeCostPerVertex(tmp[i]);
        }
    }
Пример #12
0
 public bool HasVertex(PRVertex v)
 {
     return(v == vertex[0] || v == vertex[1] || v == vertex[2]);
 }