public void AddNeighbor(PRVertex v) { if (!neighbor.Contains(v) && v != this) { neighbor.Add(v); } }
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); }
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(); }
public PRTriangle(int id, PRVertex v1, PRVertex v2, PRVertex v3) { this.id = id; vertex[0] = v1; vertex[1] = v2; vertex[2] = v3; ComputeNormal(); }
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); }
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."); } }
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; } } }
/// <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(); } }
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]]; } }
/// <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); }
//顶点和边的坍塌操作 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]); } }
public bool HasVertex(PRVertex v) { return(v == vertex[0] || v == vertex[1] || v == vertex[2]); }