public static List <face> iterate(List <face> face_list) { UnityEngine.Debug.Log("Running iterate function"); if (face_list.Count <= 0) { // return an empty list if face_list provided is empty return(new List <face>()); } // select a single element from the active face list face face_element = face_list[0]; // if the selected face has conflicts, initate search for the horizon if (face_element.Conflict_List.Count >= 1) { // We select the furthest point from the face (found by accessing the face's sorted List) Vector3 furthest_from_face = face_element.Conflict_List.OrderByDescending(element => Distance_from_Plane(face_element.corners[0], face_element.corners[2] - face_element.corners[0], face_element.corners[1] - face_element.corners[0], element, false)).First(); // Flood search based off what this furthest point can see var horizon_edge_list = new Stack <edge>(); var current_face = face_element; var visited_faces = new Stack <face>(); string path = ""; List <face> daughter_faces = new List <face>(); // Use a Flood Fill algorithm to search for horizon edges path = Flood_Fill_and_Make(furthest_from_face, current_face, horizon_edge_list, visited_faces, daughter_faces); // Check for any obvious error in the results of the flood search UnityEngine.Debug.Log("Flooded, entering main debugging area"); UnityEngine.Debug.Log("Flood path: " + path); UnityEngine.Debug.Log("Number of Horizons found: " + horizon_edge_list.Count); UnityEngine.Debug.Log("Number of visible faces: " + visited_faces.Count); UnityEngine.Debug.Log("Number of daughter: " + daughter_faces.Count); if (visited_faces.Count == 0) { UnityEngine.Debug.Log("ERROR: current point assigned to wrong face"); face_element.hidden = true; return(face_list); } if (horizon_edge_list.Count < 3) { UnityEngine.Debug.Log("ERROR: improper flood"); face_element.hidden = true; return(face_list); } // Make and link edges that exsist inbetween the newly formed faces var new_edges = new List <edge>(); foreach (face f1 in daughter_faces) { foreach (face f2 in daughter_faces) { if (f1 != f2) { foreach (Vector3 c1A in f1.corners) { foreach (Vector3 c1B in f1.corners) { if (c1A != c1B) { if (f2.corners.Contains(c1A) && f2.corners.Contains(c1B)) { bool unique = true; foreach (edge e in horizon_edge_list) { unique = unique && !(e.vertices.Contains(c1A) && e.vertices.Contains(c1B)); } foreach (edge e in new_edges) { unique = unique && !(e.vertices.Contains(c1A) && e.vertices.Contains(c1B)); } if (unique) { var new_edge = new edge(c1A, c1B); new_edge.Connect_to_Face(f1); new_edge.Connect_to_Face(f2); new_edges.Add(new_edge); } } } } } } } } UnityEngine.Debug.Log("new edge count: " + new_edges.Count); // Checking that all new faces are connected to 3 other faces (like triangles should) foreach (face f in daughter_faces) { if (f.edges.Count != 3) { UnityEngine.Debug.Log("ERROR: daughter face isn't connected to 3 other faces"); UnityEngine.Debug.Log(f.edges.Count); f.hidden = true; return(face_list); } } // Marking all hidden faces as such for clean up later face[] hidden_faces = visited_faces.ToArray(); foreach (face f in hidden_faces) { f.hidden = true; } // Combine the conflict list of obsolete hidden faces Vector3[] compound_conflict_list = (from face in hidden_faces from point in face.Conflict_List select point).ToArray(); UnityEngine.Debug.Log(compound_conflict_list.Length); // Remove points which are now hidden by the new faces foreach (face f in hidden_faces) { compound_conflict_list = Clear_Simplex_Volume(compound_conflict_list, new Vector3[] { f.corners[0], f.corners[1], f.corners[2], furthest_from_face }).ToArray(); } var remaining_conflicts = compound_conflict_list; UnityEngine.Debug.Log(remaining_conflicts.Length); // Redistribute conflicts between the new faces Distribute_Conflicts(remaining_conflicts, daughter_faces); // Check if new faces are complete (and mark them as such if so) and finally add them to the face list foreach (face daughter in daughter_faces) { if (daughter.Conflict_List.Count <= 0) { daughter.complete = true; } face_list.Add(daughter); } } else { // else, face is complete and should be marked as such UnityEngine.Debug.Log("Empty conflict list"); face_element.complete = true; } return(face_list); }
public static string Flood_Fill_and_Make(Vector3 furthest_from_face, face current_face, Stack <edge> horizon_edge_list, Stack <face> visited_faces, List <face> daughter_faces) { UnityEngine.Debug.Log("Flooding... " + current_face); if (visited_faces.Count > 0) { // Testing if face is a conflict (not visible or already visited) // There is some conflict, either the current face has already been visited or it is not visible from the point if (visited_faces.Contains(current_face)) { return("C"); } if (!current_face.Is_Visible_from_Point(furthest_from_face)) { face last_face = visited_faces.Peek(); edge horizon_edge = current_face.edges.Find(element1 => element1.connected_faces.Exists(element2 => element2 == last_face)); UnityEngine.Debug.Log("last face: " + last_face); UnityEngine.Debug.Log("current face: " + current_face); // Adding the relevant edge to the edge list horizon_edge_list.Push(horizon_edge); List <Vector3> new_face_corners = new List <Vector3>(horizon_edge.vertices); new_face_corners.Add(furthest_from_face); //new stuff - generate and filter var possible_faces = from c1 in new_face_corners from c2 in new_face_corners from c3 in new_face_corners where c1 != c2 && c1 != c3 && c2 != c3 select new face(c1, c2, c3); var front_facing_faces = from t in possible_faces where Distance_from_Plane(t.corners[0], t.corners[1] - t.corners[0], t.corners[2] - t.corners[0], Array.Find(last_face.corners, corner => !Array.Exists(t.corners, c => c == corner)), false) < 0 select t; var new_face = front_facing_faces.First(); // Modify horizon edges so they point to new face horizon_edge.connected_faces.Remove(last_face); horizon_edge.Connect_to_Face(new_face); daughter_faces.Add(new_face); UnityEngine.Debug.Log("ITEM: "); return("H"); } } else { if (!current_face.Is_Visible_from_Point(furthest_from_face)) { return("H"); } } string path = ""; UnityEngine.Debug.Log("Visit: "); path += 'V'; foreach (edge e in current_face.edges) { visited_faces.Push(current_face); //testing if (e.connected_faces.Count < 2 || !e.connected_faces.Contains(current_face)) { UnityEngine.Debug.Log("WARNING, MAKING ONE WAY TRIP: " + !e.connected_faces.Contains(current_face)); } UnityEngine.Debug.Log("Flag: " + !e.connected_faces.Contains(current_face)); UnityEngine.Debug.Log("current face: " + current_face); UnityEngine.Debug.Log("top of stack: " + visited_faces.Peek()); UnityEngine.Debug.Log("traversing edge: " + e); //testing face next_face = e.connected_faces.Find(element => element != current_face); UnityEngine.Debug.Log("next face: " + next_face); path += '['; path += Flood_Fill_and_Make(furthest_from_face, next_face, horizon_edge_list, visited_faces, daughter_faces); path += ']'; } return(path); }