Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }