コード例 #1
0
        private List <List <Vector2> > TraceLines(int sector)
        {
            List <Linedef> lines = GetSectorLinedefs(sector);

            List <List <Vector2> > output = new List <List <Vector2> >();

            int i;
            int safe1 = 1000;
            int safe2 = 1;
            int imax;

            // First check all vertexes reference two linedefs! This is to find unclosed sectors
            Dictionary <int, int> vertexLines = new Dictionary <int, int>();

            imax = lines.Count;
            for (int v = 0; v < imax; v++)
            {
                if (!vertexLines.ContainsKey(lines[v].start))
                {
                    vertexLines.Add(lines[v].start, 1);
                }
                else
                {
                    vertexLines[lines[v].start] += 1;
                }

                if (!vertexLines.ContainsKey(lines[v].end))
                {
                    vertexLines.Add(lines[v].end, 1);
                }
                else
                {
                    vertexLines[lines[v].end] += 1;
                }
            }

            int foundUnclosedSector = 0;

            foreach (KeyValuePair <int, int> entry in vertexLines)
            {
                if (vertexLines[entry.Key] < 2)
                {
                    foundUnclosedSector += 1;
                }
            }

            if (foundUnclosedSector > 0)
            {
                Debug.LogError("Unclosed sector: " + sector);
                return(null);
            }

            while (lines.Count > 0 && safe1 > 0)               // be careful
            {
                safe1--;

                List <int> trace = new List <int>();
                Linedef    line  = lines[0];

                lines.RemoveAt(0);
                trace.Add(line.start);
                int next = line.end;

                safe2 = 1000;
                while (trace[0] != next && safe2 > 0)                    // be careful!!!!
                {
                    safe2--;

                    // New approach: find all connected lines and pick the most acute angle
                    List <int>  connectedLines     = new List <int>(10);              // Just use the line index
                    List <bool> connectedLineFront = new List <bool>(10);
                    imax = lines.Count;
                    for (i = 0; i < imax; i++)
                    {
                        if (lines[i].start == next)
                        {
                            connectedLines.Add(i);
                            connectedLineFront.Add(true);
                        }
                        else if (lines[i].end == next)
                        {
                            connectedLines.Add(i);
                            connectedLineFront.Add(false);
                        }
                    }
                    int conLines = connectedLines.Count;
                    if (connectedLines.Count == 1)
                    {
                        trace.Add(next);
                        next = connectedLineFront[0]?lines[connectedLines[0]].end:lines[connectedLines[0]].start;
                        lines.RemoveAt(Mathf.Abs(connectedLines[0]));
                    }
                    else
                    {
                        Vector2 v1         = VertexToVector2(trace[trace.Count - 1]);
                        Vector2 v2         = VertexToVector2(next);
                        int     pointIndex = connectedLineFront[0]?lines[connectedLines[0]].end:lines[connectedLines[0]].start;
                        Vector2 v3         = VertexToVector2(pointIndex);
                        float   minAngle   = Mathf.Abs(LineAngle(v1, v2) - LineAngle(v3, v2));
                        int     minIndex   = 0;
                        for (i = 1; i < conLines; i++)
                        {
                            pointIndex = connectedLineFront[i]?lines[connectedLines[i]].end:lines[connectedLines[i]].start;
                            v3         = VertexToVector2(pointIndex);
                            float newAngle = Mathf.Abs(LineAngle(v1, v2) - LineAngle(v3, v2));
                            if (newAngle < minAngle)
                            {
                                minIndex = i;
                                minAngle = newAngle;
                            }
                        }
                        trace.Add(next);
                        next = connectedLineFront[minIndex]?lines[connectedLines[minIndex]].end:lines[connectedLines[minIndex]].start;
                        lines.RemoveAt(Mathf.Abs(connectedLines[minIndex]));
                    }
                }

                // Convert it to vector2 for actual use.
                // I used the index above for speed.
                imax = trace.Count;
                List <Vector2> vector2trace = new List <Vector2>(imax);
                for (i = 0; i < imax; i++)
                {
                    vector2trace.Add(VertexToVector2(trace[i]));
                }
                output.Add(vector2trace);
            }

            if (safe1 <= 0)
            {
                Debug.LogError("First while loop exceeded limit!");
            }
            if (safe2 <= 0)
            {
                Debug.LogError("Second while loop exceeded limit! Sector: " + sector + " Lines left: " + lines.Count);
            }

            return(output);
        }