Exemplo n.º 1
0
    /// <summary>
    /// Gets the next safe edge for the mst
    /// </summary>
    /// <param name="parents"></param>
    /// <returns></returns>
    private VertexPair GetNextSafeEdge(Dictionary <Vertex, Vertex> parents)
    {
        List <VertexPair> safeEdges = new List <VertexPair>();

        foreach (var kV in connectedVertices)
        {
            foreach (var vertex in kV.Value)
            {
                Vertex v0 = kV.Key;
                Vertex v1 = vertex;
                // If one vertex is a part of the mst, and one is not
                if ((parents[v0] == null && parents[v1] != null) || (parents[v1] == null && parents[v0] != null))
                {
                    safeEdges.Add(new VertexPair(v0, v1));
                }
            }
        }

        // Find the safe edge with the smallest distance
        VertexPair closestSafeEdge  = null;
        float      smallestDistance = float.PositiveInfinity;

        foreach (var edge in safeEdges)
        {
            float distance = EdgeLength(edge);
            if (distance < smallestDistance)
            {
                closestSafeEdge  = edge;
                smallestDistance = distance;
            }
        }

        return(closestSafeEdge);
    }
Exemplo n.º 2
0
    /// <summary>
    /// Calculate length of an edge
    /// </summary>
    /// <param name="edge"></param>
    /// <returns></returns>
    public float EdgeLength(VertexPair edge)
    {
        Vector2 vec1 = new Vector2((float)edge.v0.X, (float)edge.v0.Y);
        Vector2 vec2 = new Vector2((float)edge.v1.X, (float)edge.v1.Y);

        return(Vector2.Distance(vec2, vec1));
    }
Exemplo n.º 3
0
    /// <summary>
    /// Remove long and short edges from the connections so we don't choose really long or stubby connections accidentally
    /// </summary>
    /// <param name="num"></param>
    private void RemoveLongShortEdges(int num)
    {
        num = Mathf.RoundToInt(num / 2f);
        for (int i = 0; i < num; i++)
        {
            float      longestLength  = 0;
            VertexPair longestEdge    = null;
            float      shortestLength = float.PositiveInfinity;
            VertexPair shortestEdge   = null;
            foreach (var kV in triangulator.connectedVertices)
            {
                foreach (var vertex in kV.Value)
                {
                    VertexPair edge     = new VertexPair(kV.Key, vertex);
                    float      distance = triangulator.EdgeLength(edge);
                    if (distance > longestLength)
                    {
                        longestLength = distance;
                        longestEdge   = edge;
                    }

                    if (distance < shortestLength)
                    {
                        shortestLength = distance;
                        shortestEdge   = edge;
                    }
                }
            }

            triangulator.connectedVertices[longestEdge.v1].Remove(longestEdge.v0);
            triangulator.connectedVertices[longestEdge.v0].Remove(longestEdge.v1);
            triangulator.connectedVertices[shortestEdge.v1].Remove(shortestEdge.v0);
            triangulator.connectedVertices[shortestEdge.v0].Remove(shortestEdge.v1);
        }
    }
Exemplo n.º 4
0
    /// <summary>
    /// Get the DungeonLevel graph from a list of vectors
    /// </summary>
    /// <param name="vectors"></param>
    /// <param name="connectedness"></param> Determines how connected the DungeonLevel is - 0.0 being a minimum spanning tree
    /// <returns></returns>
    public Dictionary <Vector2Int, List <Vector2Int> > GetDungeonMap(List <Vector2Int> vectors, float connectedness)
    {
        triangulator = new Triangulator();
        triangulator.GenerateMst(vectors);
        dungeonExits = FindStartAndEnd();

        // Prime mst to be more like DungeonLevel hallways
        RemoveMstFromGraph();
        RemoveLongShortEdges(Mathf.RoundToInt(triangulator.connectedVertices.Count / 3f));
        AddRandomEdgesToMst(Mathf.RoundToInt(triangulator.connectedVertices.Count * connectedness));

        // Convert back to vectors
        Dictionary <Vector2Int, List <Vector2Int> > links = new Dictionary <Vector2Int, List <Vector2Int> >();

        foreach (var kV in triangulator.mst)
        {
            List <Vector2Int> adj = new List <Vector2Int>();
            foreach (var vertex in kV.Value)
            {
                adj.Add(new Vector2Int(Mathf.RoundToInt((float)vertex.X), Mathf.RoundToInt((float)vertex.Y)));
            }

            links.Add(new Vector2Int(Mathf.RoundToInt((float)kV.Key.X), Mathf.RoundToInt((float)kV.Key.Y)), adj);
        }

        return(links);
    }
Exemplo n.º 5
0
        private void Render()
        {
            for (int p = 0; p < generator.IterableVertices.Count; p++)
            {
                generator.IterableVertices[p].isFaded = true;
            }

            for (int p = 0; p < added.Count; p++)
            {
                added[p].isFaded = false;
            }

            List <VertexPair> vertexPairs = new List <VertexPair>();

            for (int t = 0; t < container.Count; t++)
            {
                Triangle tri = container[t];
                var      e1  = new VertexPair(tri.a, tri.b);
                var      e2  = new VertexPair(tri.b, tri.c);
                var      e3  = new VertexPair(tri.c, tri.a);
                if (tri.isHighlighted)
                {
                    e1.isHighlighted = true;
                    e2.isHighlighted = true;
                    e3.isHighlighted = true;
                }

                vertexPairs.Add(e1);
                vertexPairs.Add(e2);
                vertexPairs.Add(e3);
            }

            for (int i = 0; i < vertexPairs.Count; i++)
            {
                if (i >= edges.Count)
                {
                    Edge edge = Instantiate(edgePrefab).GetComponent <Edge>();
                    edges.Add(edge);
                }

                edges[i].Point1 = vertexPairs[i].a;
                edges[i].Point2 = vertexPairs[i].b;
                edges[i].transform.SetParent(transform);
                edges[i].isHighlighted = vertexPairs[i].isHighlighted;

                edges[i].gameObject.SetActive(true);
            }

            for (int i = vertexPairs.Count; i < edges.Count; i++)
            {
                edges[i].gameObject.SetActive(false);
            }
        }
Exemplo n.º 6
0
            internal Triangle FindNeighbor(Triangle triangle, VertexPair edge)
            {
                foreach (var t in triangles)
                {
                    if (t.IsNeighbor(edge) && t != triangle)
                    {
                        return(t);
                    }
                }

                return(null);
            }
Exemplo n.º 7
0
            /// given a vertex in the graph, find its upper and lower neighbor vertices
            protected Tuple <Vertex, Vertex> find_neighbor_vertices(VertexPair v_pair, Interval ival)
            {
                Interval.VertexPairIterator itr = ival.intersections2.lower_bound(v_pair); // returns first that is not less than argument (equal or greater)
                Debug.Assert(itr != ival.intersections2.end());                            // we must find a lower_bound
                Interval.VertexPairIterator v_above = itr;                                 // lower_bound returns one beyond the give key, i.e. what we want
                Interval.VertexPairIterator v_below = --itr;                               // this is the vertex below the give vertex
                Tuple <Vertex, Vertex>      @out    = new Tuple <Vertex, Vertex>(null, null);

                @out.Item1 = v_above.first;         // vertex above v (xu)
                @out.Item2 = v_below.first;         // vertex below v (xl)
                Debug.Assert(@out.Item1 != @out.Item2);
                return(new Tuple <Vertex, Vertex>(@out.Item1, @out.Item2));
            }
    /// <summary>
    /// Generates the DungeonLevel and writes it to the map 2d array
    /// </summary>
    private void GenerateDungeon()
    {
        DungeonMst    dungeonMst    = new DungeonMst();
        RoomGenerator roomGenerator = new RoomGenerator();

        rooms = roomGenerator.GenerateRooms(
            DungeonLevel.InitialRoomDensity,
            DungeonLevel.Width,
            DungeonLevel.Height,
            new Vector2Int(DungeonLevel.MinRoomHeight, DungeonLevel.MaxRoomHeight),
            new Vector2Int(DungeonLevel.MinRoomWidth, DungeonLevel.MaxRoomWidth)
            );
        links = dungeonMst.GetDungeonMap(rooms.Keys.ToList(), DungeonLevel.RoomConnectedness);
        LinksIntoHallways();
        dungeonExits = dungeonMst.dungeonExits;

        // Adds hubs
        foreach (var room in rooms.Values)
        {
            WriteRoomToMap(room);
        }

        foreach (var edge in hallways)
        {
            WriteEdgeToMap(edge);
        }

        CellularAutomata          caveGen   = new CellularAutomata(DungeonLevel);
        List <List <Vector2Int> > caveRooms = caveGen.Generate();

        foreach (var caveRoom in caveRooms)
        {
            foreach (var tile in caveRoom)
            {
                map[tile.x, tile.y] = Tiles.caveTile;
            }
        }

        // Place the physical objects into the world
        PlaceExits();
        AddFloorsAndWalls();
        PlaceDoors();
        foreach (WeightedGeneratedStructure type in DungeonLevel.generatedStructures)
        {
            PlaceGeneratedStructures(type.structure, type.amountPerLevel);
        }
        PlaceObjects(PlaceChest, DungeonLevel.ChestsPerLevel);
        PlaceObjects(PlaceDecorObjects, DungeonLevel.FreeStandingDecorationCount);
        PlaceObjects(PlaceEnemy, DungeonLevel.EnemiesPerLevel);
        PlaceObjects(PlaceDestrucibleObjects, DungeonLevel.DestructibleObjectCount);
    }
Exemplo n.º 9
0
        Edge addEdge(Vertex v0, Vertex v1)
        {
            var pair = new VertexPair(v0, v1);

            if (edges.TryGetValue(pair, out var found))
            {
                return(found);
            }

            var result = new Edge();

            result.a = v0;
            result.b = v1;
            edges.Add(pair, result);
            return(result);
        }
Exemplo n.º 10
0
            internal Vertex OppositeVertex(VertexPair edge)
            {
                if (a != edge.a && a != edge.b)
                {
                    return(a);
                }
                else if (b != edge.a && b != edge.b)
                {
                    return(b);
                }
                else if (c != edge.a && c != edge.b)
                {
                    return(c);
                }

                return(null);
            }
Exemplo n.º 11
0
 /// <summary>
 /// Shuffles the vertex indices so the two vertex indices contained in the given vertex pair correspond with Vertex0Index and Vertex1Index.
 /// </summary>
 /// <param name="vertexPair">The vertex pair whose vertex indices we want up front.</param>
 public void ShuffleVertexIndices(VertexPair vertexPair)
 {
     if (new VertexPair(vertex1Index, vertex2Index) == vertexPair)
     {
         int temp = vertex1Index;
         vertex1Index = vertex2Index;
         vertex2Index = vertex0Index;
         vertex0Index = temp;
     }
     else if (new VertexPair(vertex0Index, vertex2Index) == vertexPair)
     {
         int temp = vertex2Index;
         vertex2Index = vertex1Index;
         vertex1Index = vertex0Index;
         vertex0Index = temp;
     }
 }
Exemplo n.º 12
0
    /// <summary>
    /// Add in some edges back to make the DungeonLevel more connected
    /// </summary>
    /// <param name="num"></param>
    private void AddRandomEdgesToMst(int num)
    {
        for (int i = 0; i < num; i++)
        {
            List <VertexPair> allEdges = new List <VertexPair>();
            foreach (var kV in triangulator.connectedVertices)
            {
                foreach (var vertex in kV.Value)
                {
                    allEdges.Add(new VertexPair(kV.Key, vertex));
                }
            }

            VertexPair randomEdge = allEdges[Random.Range(0, allEdges.Count)];
            triangulator.mst[randomEdge.v0].Add(randomEdge.v1);
            triangulator.mst[randomEdge.v1].Add(randomEdge.v0);
        }
    }
Exemplo n.º 13
0
        private IEnumerator MakeDelaunay(Triangle triangle, VertexPair edge, Vertex point)
        {
            Triangle neighbor = container.FindNeighbor(triangle, edge);

            if (neighbor != null)
            {
                if (neighbor.PointInCircumcircle(point))
                {
                    triangle.isHighlighted = true;
                    neighbor.isHighlighted = true;

                    yield return(new WaitForSecondsRealtime(speed));

                    container.Remove(triangle);
                    container.Remove(neighbor);

                    Vertex n = neighbor.OppositeVertex(edge);


                    Triangle t1 = new Triangle(n, edge.a, point);
                    Triangle t2 = new Triangle(n, edge.b, point);
                    t1.isHighlighted = true;
                    t2.isHighlighted = true;

                    container.Add(t1);
                    container.Add(t2);

                    yield return(new WaitForSecondsRealtime(speed));

                    t1.isHighlighted = false;
                    t2.isHighlighted = false;

                    yield return(MakeDelaunay(t1, new VertexPair(n, edge.a), point));

                    yield return(MakeDelaunay(t2, new VertexPair(n, edge.b), point));
                }
            }
            else
            {
                //Debug.Log("No neighbor!");
            }

            yield return(null);
        }
Exemplo n.º 14
0
            // given a VertexPair and an Interval, in the Interval find the Vertex above and below the given vertex
            protected Tuple <Vertex, Vertex> find_neighbor_vertices(VertexPair v_pair, Interval ival, bool above_equality)
            {
                Interval.VertexPairIterator itr = ival.intersections2.lower_bound(v_pair); // returns first that is not less than argument (equal or greater)
                Debug.Assert(itr != ival.intersections2.end());                            // we must find a lower_bound
                Interval.VertexPairIterator v_above = new Interval.VertexPairIterator();
                if (above_equality)
                {
//C++ TO C# CONVERTER TODO TASK: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created:
//ORIGINAL LINE: v_above = itr;
                    v_above.CopyFrom(itr);             // lower_bound returns one beyond the give key, i.e. what we want
                }
                else
                {
                    v_above = ++itr;
                    --itr;
                }
                Interval.VertexPairIterator v_below = --itr;         // this is the vertex below the given vertex
                Tuple <Vertex, Vertex>      @out    = new Tuple <Vertex, Vertex>(null, null);

                @out.Item1 = v_above.first;         // vertex above v (xu)
                @out.Item2 = v_below.first;         // vertex below v (xl)
                return(new Tuple <Vertex, Vertex>(@out.Item1, @out.Item2));
            }
Exemplo n.º 15
0
        private VertexPair Split(Vertex root, int key)
        {
            VertexPair result      = new VertexPair();
            VertexPair findAndRoot = FindInRoot(root, key);

            root         = findAndRoot.Right;
            result.Right = findAndRoot.Left;
            if (result.Right == null)
            {
                result.Left = root;
                return(result);
            }
            result.Right      = Splay(result.Right);
            result.Left       = result.Right.Left;
            result.Right.Left = null;
            if (result.Left != null)
            {
                result.Left.Parent = null;
            }
            Update(result.Left);
            Update(result.Right);
            return(result);
        }
Exemplo n.º 16
0
    /// <summary>
    /// Find the mst of the triangulated vertices
    /// </summary>
    /// <returns></returns>
    private void JarnikPrimsMst()
    {
        // Keeps track of the parents for every vertex
        Dictionary <Vertex, Vertex> parents = new Dictionary <Vertex, Vertex>();

        mst = new Dictionary <Vertex, List <Vertex> >();
        foreach (var vertex in connectedVertices.Keys)
        {
            parents.Add(vertex, null);
        }

        Vertex root = mesh.vertices[0];

        parents[root] = root; // Make the root's parent not null
        mst.Add(root, new List <Vertex>());
        while (mst.Count < connectedVertices.Count)
        {
            VertexPair edge = GetNextSafeEdge(parents);

            //Add the new vertex - it has to be one or the other
            if (mst.ContainsKey(edge.v0))
            {
                mst.Add(edge.v1, new List <Vertex>());
                parents[edge.v1] = edge.v0;
            }
            else
            {
                mst.Add(edge.v0, new List <Vertex>());
                parents[edge.v0] = edge.v1;
            }

            //Add the edge that connects the two
            mst[edge.v0].Add(edge.v1);
            mst[edge.v1].Add(edge.v0);
        }
    }
Exemplo n.º 17
0
 internal bool IsNeighbor(VertexPair edge)
 {
     return((a == edge.a || b == edge.a || c == edge.a) && (a == edge.b || b == edge.b || c == edge.b));
 }
Exemplo n.º 18
0
 public LogFailureVerbose(VertexPair n, ReadOnlyCollection <VertexPair> fn) :
     base(n)
 {
     FailureNotifications = fn;
 }
Exemplo n.º 19
0
        private void Contract(int targetTriangles, IProgressListener listener = null)
        {
            SelectValidPairs();

            if (listener != null)
            {
                listener.OnStarted("Compacting");
            }

            int totalTriangles = m_Faces.Count - targetTriangles;
            int currentTriangle = 0;
            while (m_Faces.Count > targetTriangles)
            {
                if (listener != null)
                {
                    listener.OnStep(currentTriangle, totalTriangles);
                }
                ++currentTriangle;
                double minError = (double)int.MaxValue;

                //KeyValuePair<VertexPair, double> min;
                VertexPair minPair = new VertexPair() { First = 0, Second = 0 };

                foreach (KeyValuePair<VertexPair, double> e in m_Errors)
                {
                    if (e.Value < minError)
                    {
                        minError = e.Value;
                        minPair = e.Key;
                    }
                }

                Vector3 error;
                ComputeError(minPair.First, minPair.Second, out error);

#if false
                VertexSplit split = new VertexSplit();

                //var fv

                split.First.Position = m_Vertices[minPair.First].Position;
                split.Second.Position = m_Vertices[minPair.Second].Position;
                split.Target.Position = error;
                m_Splits.Add(split);
#endif
                var vertex = m_Vertices[minPair.First];
                vertex.Position = error;

                m_Quadrics[minPair.First] = m_Quadrics[minPair.First] + m_Quadrics[minPair.Second];

                for (int i = m_Faces.Count - 1; i != 0; )
                {
                    var face = m_Faces[i];

                    for (int j = 0; j < 3; ++j)
                    {
                        if (face[j] == minPair.Second)
                        {
                            if (face[0] == minPair.First || face[1] == minPair.First || face[2] == minPair.First)
                            {
                                m_Faces.Remove(face);
                            }
                            else
                            {
                                face[j] = minPair.First;
                            }
                            --i;
                            break;
                        }
                        else if (j == 2)
                        {
                            --i;
                        }
                    }
                }

                m_Vertices.Remove(minPair.Second);

                KeyValuePair<VertexPair, double> pair;

#if false
                for (int iter = m_Errors.Count - 1; iter != 0; )
                {
                    pair = m_Errors.ElementAt(iter);

                    if (pair.Key.First == minPair.Second && pair.Key.Second != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(iter).Key);

                        m_Errors.Add(
                            new VertexPair() { First = Math.Min(minPair.First, pair.Key.Second), Second = Math.Max(minPair.First, pair.Key.Second) },
                            0.0);
                        --iter;
                    }
                    else if (pair.Key.Second == minPair.Second && pair.Key.First != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(iter).Key);

                        m_Errors.Add(
                            new VertexPair() { First = Math.Min(minPair.First, pair.Key.First), Second = Math.Max(minPair.First, pair.Key.First) },
                            0.0);
                        --iter;
                    }
                    else
                    {
                        --iter;
                    }
                }
#else
                for (int it = 0; it < m_Errors.Count; ++it)
                {
                    pair = m_Errors.ElementAt(it);

                    if (pair.Key.First == minPair.Second && pair.Key.Second != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(it).Key);

                        var key = new VertexPair()
                        {
                            First = Math.Min(minPair.First, pair.Key.Second),
                            Second = Math.Max(minPair.First, pair.Key.Second)
                        };

                        if (!m_Errors.ContainsKey(key))
                        {
                            m_Errors.Add(
                                key,
                                0.0);
                        }
                    }
                    else if (pair.Key.Second == minPair.Second && pair.Key.First != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(it).Key);

                        var key = new VertexPair()
                        {
                            First = Math.Min(minPair.First, pair.Key.First),
                            Second = Math.Max(minPair.First, pair.Key.First)
                        };

                        if (!m_Errors.ContainsKey(key))
                        {
                            m_Errors.Add(
                                key,
                                0.0);
                        }
                    }
                }
#endif
                m_Errors.Remove(minPair);

                for (int it = 0; it < m_Errors.Count; ++it)
                {
                    var key = m_Errors.ElementAt(it).Key;

                    if (key.First == minPair.First)
                    {
                        m_Errors[key] = ComputeError(minPair.First, key.Second);
                    }

                    if (key.Second == minPair.First)
                    {
                        m_Errors[key] = ComputeError(minPair.First, key.First);
                    }
                }
                /*foreach (var e in m_Errors)
                {
                    var p = e.Key;
                    if (p.First == minPair.First)
                    {
                        m_Errors[p] = ComputeError(minPair.First, p.Second);
                    }

                    if (p.Second == minPair.First)
                    {
                        m_Errors[p] = ComputeError(minPair.First, p.First);
                    }
                }*/

            }
            if (listener != null)
            {
                listener.OnComplete("Compacting");
            }
        }
Exemplo n.º 20
0
 /// <summary>
 /// Returns whether the given vertex pair is considered equal to this object.
 /// </summary>
 /// <param name="other">The other vertex pair.</param>
 /// <returns>Whether the given vertex pair is considered equal to this object.</returns>
 public bool Equals(VertexPair other)
 {
     return
         (((vertex0Index == other.vertex0Index) && (vertex1Index == other.vertex1Index)) ||
          ((vertex0Index == other.vertex1Index) && (vertex1Index == other.vertex0Index)));
 }
Exemplo n.º 21
0
        static void RepairSector(SECTORS sector, List <Line> lines)
        {
            if (lines.Count < 2)
            {
                // sector with a single line, don't repair
                return;
            }

            // generate a list of all vertices
            List <Vertex> vertices = new List <Vertex>();

            foreach (Line line in lines)
            {
                if (!vertices.Contains(line.vertices[0]))
                {
                    vertices.Add(line.vertices[0]);
                }

                if (!vertices.Contains(line.vertices[1]))
                {
                    vertices.Add(line.vertices[1]);
                }
            }

            // find all vertices that only have one line
            List <Vertex> loneVertices = new List <Vertex>();

            foreach (Vertex vertex in vertices)
            {
                int count = 0;

                foreach (Line line in lines)
                {
                    if (line.vertices.Contains(vertex))
                    {
                        count++;
                    }
                }

                if (count < 2)
                {
                    loneVertices.Add(vertex);
                }
            }

            if (loneVertices.Count == 0)
            {
                // nothing wrong here
                return;
            }

            Debug.Log("BAD SECTOR: " + sector.sectorIndex);

            // find lines that intersect
            foreach (Line line1 in lines)
            {
                foreach (Line line2 in lines)
                {
                    if (line1 == line2)
                    {
                        continue;
                    }

                    Vertex intersect = line1.Intersection(line2);
                    if (intersect == null)
                    {
                        continue;
                    }

                    Debug.Log("REPAIRING: intersection, SECTOR: " + sector.sectorIndex);

                    // find closest vertex to intersection point
                    Vertex closestVertex = line1.vertices[0];
                    foreach (Vertex vertex in line1.vertices)
                    {
                        if (vertex.DistanceTo(intersect) < closestVertex.DistanceTo(intersect))
                        {
                            closestVertex = vertex;
                        }
                    }
                    foreach (Vertex vertex in line2.vertices)
                    {
                        if (vertex.DistanceTo(intersect) < closestVertex.DistanceTo(intersect))
                        {
                            closestVertex = vertex;
                        }
                    }

                    // move closest to intersection point
                    closestVertex.x = intersect.x;
                    closestVertex.y = intersect.y;

                    // replace closest line1 vertex with closest vertex
                    if (line1.vertices[0].DistanceTo(intersect) < line1.vertices[1].DistanceTo(intersect))
                    {
                        line1.vertices[0] = closestVertex;
                        loneVertices.Remove(line1.vertices[0]);
                    }
                    else
                    {
                        line1.vertices[1] = closestVertex;
                        loneVertices.Remove(line1.vertices[1]);
                    }

                    // replace closest line2 vertex with closest vertex
                    if (line2.vertices[0].DistanceTo(intersect) < line2.vertices[1].DistanceTo(intersect))
                    {
                        line2.vertices[0] = closestVertex;
                        loneVertices.Remove(line2.vertices[0]);
                    }
                    else
                    {
                        line2.vertices[1] = closestVertex;
                        loneVertices.Remove(line2.vertices[1]);
                    }
                }
            }

            if (loneVertices.Count == 0)
            {
                // sector was repaired
                return;
            }

            // generate every combination of vertices in pairs
            SortedList <double, VertexPair> pairs = new SortedList <double, VertexPair>();

            foreach (Vertex v1 in loneVertices)
            {
                foreach (Vertex v2 in loneVertices)
                {
                    if (v1 == v2)
                    {
                        continue;
                    }

                    // make sure pair is unique
                    foreach (VertexPair pair in pairs.Values)
                    {
                        if (pair.vertices.Contains(v1) && pair.vertices.Contains(v2))
                        {
                            goto nextPair;
                        }
                    }

                    VertexPair vertexPair = new VertexPair(v1, v2);
                    double     dist       = vertexPair.Distance();
                    while (pairs.ContainsKey(dist))
                    {
                        dist += 0.001;
                    }
                    pairs.Add(dist, vertexPair);

                    nextPair :;
                }
            }

            // generate a line for every pair, sorted by distance
            while (pairs.Count > 0)
            {
                // grab a pair with the least distance between them
                VertexPair pair = pairs.Values.First();
                pairs.RemoveAt(0);

                // generate the line between the two vertices
                Line line = new Line(pair.vertices[0], pair.vertices[1], false, false);

                // check for collision
                foreach (Line line2 in lines)
                {
                    if (line.Intersects(line2))
                    {
                        goto nextPair;
                    }
                }

                // add the line to the list
                lines.Add(line);
                Debug.Log("REPAIRING: missing line, SECTOR: " + sector.sectorIndex);
                Debug.DrawLine(new Vector3((float)pair.vertices[0].x, 0, (float)pair.vertices[0].y), new Vector3((float)pair.vertices[1].x, 0, (float)pair.vertices[1].y), Color.red, 10000);

                // remove any pairs that contain a shared vertex to this one
                for (int i = 0; i < pairs.Count; i++)
                {
                    if (pairs.Values[i].vertices.Contains(pair.vertices[0]) || pairs.Values[i].vertices.Contains(pair.vertices[1]))
                    {
                        pairs.RemoveAt(i);
                        i--;
                        continue;
                    }
                }

                nextPair :;
            }
        }
Exemplo n.º 22
0
 public LogFailure(VertexPair n)
 {
     Notification = n;
 }
Exemplo n.º 23
0
            /// comparison operator
//C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#:
//ORIGINAL LINE: bool operator ()(const VertexPair& lhs, const VertexPair& rhs) const
            public static bool functorMethod(VertexPair lhs, VertexPair rhs)
            {
                return(lhs.second < rhs.second);
            }
Exemplo n.º 24
0
 protected bool Equals(VertexPair other)
 {
     return(Vertex1 == other.Vertex1 && Vertex2 == other.Vertex2);
 }
Exemplo n.º 25
0
        private void Contract(int targetTriangles, IProgressListener listener = null)
        {
            SelectValidPairs();

            if (listener != null)
            {
                listener.OnStarted("Compacting");
            }

            int totalTriangles  = m_Faces.Count - targetTriangles;
            int currentTriangle = 0;

            while (m_Faces.Count > targetTriangles)
            {
                if (listener != null)
                {
                    listener.OnStep(currentTriangle, totalTriangles);
                }
                ++currentTriangle;
                double minError = (double)int.MaxValue;

                //KeyValuePair<VertexPair, double> min;
                VertexPair minPair = new VertexPair()
                {
                    First = 0, Second = 0
                };

                foreach (KeyValuePair <VertexPair, double> e in m_Errors)
                {
                    if (e.Value < minError)
                    {
                        minError = e.Value;
                        minPair  = e.Key;
                    }
                }

                Vector3 error;
                ComputeError(minPair.First, minPair.Second, out error);

#if false
                VertexSplit split = new VertexSplit();

                //var fv

                split.First.Position  = m_Vertices[minPair.First].Position;
                split.Second.Position = m_Vertices[minPair.Second].Position;
                split.Target.Position = error;
                m_Splits.Add(split);
#endif
                var vertex = m_Vertices[minPair.First];
                vertex.Position = error;

                m_Quadrics[minPair.First] = m_Quadrics[minPair.First] + m_Quadrics[minPair.Second];

                for (int i = m_Faces.Count - 1; i != 0;)
                {
                    var face = m_Faces[i];

                    for (int j = 0; j < 3; ++j)
                    {
                        if (face[j] == minPair.Second)
                        {
                            if (face[0] == minPair.First || face[1] == minPair.First || face[2] == minPair.First)
                            {
                                m_Faces.Remove(face);
                            }
                            else
                            {
                                face[j] = minPair.First;
                            }
                            --i;
                            break;
                        }
                        else if (j == 2)
                        {
                            --i;
                        }
                    }
                }

                m_Vertices.Remove(minPair.Second);

                KeyValuePair <VertexPair, double> pair;

#if false
                for (int iter = m_Errors.Count - 1; iter != 0;)
                {
                    pair = m_Errors.ElementAt(iter);

                    if (pair.Key.First == minPair.Second && pair.Key.Second != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(iter).Key);

                        m_Errors.Add(
                            new VertexPair()
                        {
                            First = Math.Min(minPair.First, pair.Key.Second), Second = Math.Max(minPair.First, pair.Key.Second)
                        },
                            0.0);
                        --iter;
                    }
                    else if (pair.Key.Second == minPair.Second && pair.Key.First != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(iter).Key);

                        m_Errors.Add(
                            new VertexPair()
                        {
                            First = Math.Min(minPair.First, pair.Key.First), Second = Math.Max(minPair.First, pair.Key.First)
                        },
                            0.0);
                        --iter;
                    }
                    else
                    {
                        --iter;
                    }
                }
#else
                for (int it = 0; it < m_Errors.Count; ++it)
                {
                    pair = m_Errors.ElementAt(it);

                    if (pair.Key.First == minPair.Second && pair.Key.Second != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(it).Key);

                        var key = new VertexPair()
                        {
                            First  = Math.Min(minPair.First, pair.Key.Second),
                            Second = Math.Max(minPair.First, pair.Key.Second)
                        };

                        if (!m_Errors.ContainsKey(key))
                        {
                            m_Errors.Add(
                                key,
                                0.0);
                        }
                    }
                    else if (pair.Key.Second == minPair.Second && pair.Key.First != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(it).Key);

                        var key = new VertexPair()
                        {
                            First  = Math.Min(minPair.First, pair.Key.First),
                            Second = Math.Max(minPair.First, pair.Key.First)
                        };

                        if (!m_Errors.ContainsKey(key))
                        {
                            m_Errors.Add(
                                key,
                                0.0);
                        }
                    }
                }
#endif
                m_Errors.Remove(minPair);

                for (int it = 0; it < m_Errors.Count; ++it)
                {
                    var key = m_Errors.ElementAt(it).Key;

                    if (key.First == minPair.First)
                    {
                        m_Errors[key] = ComputeError(minPair.First, key.Second);
                    }

                    if (key.Second == minPair.First)
                    {
                        m_Errors[key] = ComputeError(minPair.First, key.First);
                    }
                }

                /*foreach (var e in m_Errors)
                 * {
                 *  var p = e.Key;
                 *  if (p.First == minPair.First)
                 *  {
                 *      m_Errors[p] = ComputeError(minPair.First, p.Second);
                 *  }
                 *
                 *  if (p.Second == minPair.First)
                 *  {
                 *      m_Errors[p] = ComputeError(minPair.First, p.First);
                 *  }
                 * }*/
            }
            if (listener != null)
            {
                listener.OnComplete("Compacting");
            }
        }