void OnDrawGizmos()
    {
        bool           success  = false;
        List <Vector3> testLine = test.Line.ToList();

        if (mathTest == MathTest.Collides)
        {
            success = ProcGenHelpers.CollidesWith(testLine[0], testLine[1], reference.Line.ToList(), true, out reference.markIndex);
        }
        else if (mathTest == MathTest.Ray)
        {
            reference.markIndex = -1;
            Vector3 pt = Vector3.one;
            success = ProcGenHelpers.RayInterceptsSegment(testLine[0], testLine[1] - testLine[0], reference.Line.ToList(), out pt);
            if (success)
            {
                Gizmos.color = Color.green;
                Gizmos.DrawSphere(pt, gizmosSize);
            }
        }
        else if (mathTest == MathTest.IsKnown)
        {
            success = ProcGenHelpers.IsKnownSegment(testLine[0], testLine[1], true, reference.Line.ToList());
        }


        test.lineColor = success ? Color.green : Color.gray;
    }
    bool MapCornerStraightWall()
    {
        bool    room = false;
        Vector3 a    = convex[Random.Range(0, convex.Count)];
        //Debug.Log("Building from corner " + a);
        int            idA        = perimeter.IndexOf(a);
        List <Vector3> directions = new List <Vector3>();

        if (idA >= 0)
        {
            directions.Add((a - perimeter[(perimeter.Count + (idA - 1)) % perimeter.Count]).normalized);
            directions.Add((a - perimeter[(idA + 1) % perimeter.Count]).normalized);
            directions.Add((perimeter[(idA + 1) % perimeter.Count] - a).normalized);
            directions.Add((perimeter[(perimeter.Count + (idA - 1)) % perimeter.Count] - a).normalized);

            //AddGizmoWall(a, a + directions[0]);
            //AddGizmoWall(a, a + directions[1]);
        }

        else
        {
            foreach (List <Vector3> iWall in wallLines)
            {
                if (iWall.Contains(a))
                {
                    idA = iWall.IndexOf(a);
                    directions.Add((a - iWall[idA - 1]).normalized);
                    directions.Add((a - iWall[idA + 1]).normalized);
                    directions.Add((iWall[idA - 1] - a).normalized);
                    directions.Add((iWall[idA + 1] - a).normalized);

                    //AddGizmoWall(a, a + directions[0]);
                    //AddGizmoWall(a, a + directions[1]);

                    break;
                }
            }
        }

        Vector3 pt = Vector3.zero;

        for (int i = 0; i < directions.Count; i++)
        {
            if (ProcGenHelpers.RayInterceptsSegment(a, directions[i], perimeter, out pt))
            {
                int     wallsHit;
                Vector3 pt2;
                if (ProcGenHelpers.RayInterceptsSegment(a, directions[i], wallLines, out pt2, out wallsHit))
                {
                    if (!ProcGenHelpers.TooClose(pt, wallLines[wallsHit], shortestWall) && !ProcGenHelpers.IsKnownSegment(a, pt2, wallLines) && !ProcGenHelpers.IsKnownSegment(a, pt2, true, perimeter))
                    {
                        pt = pt2;
                        Debug.Log("Corner to inner wall");
                        room = true;
                        break;
                    }
                }
                else if (!ProcGenHelpers.TooClose(pt, perimeter, shortestWall) && !ProcGenHelpers.IsKnownSegment(a, pt, true, perimeter) && !ProcGenHelpers.IsKnownSegment(a, pt, wallLines))
                {
                    Debug.Log("Corner to outer wall");
                    room = true;
                    break;
                }
            }
        }

        if (room)
        {
            Debug.LogWarning(string.Format("Added simple wall {0} {1}", a, pt));
            nonConcave.Add(pt);
            wallLines.Add(new List <Vector3>()
            {
                a, pt
            });
            if (!nonConcave.Contains(pt))
            {
                nonConcave.Add(pt);
            }
        }

        return(room);
    }
    bool MapCornerToCornerWall()
    {
        bool    room  = false;
        int     indx  = Random.Range(0, convex.Count);
        Vector3 a1    = convex[indx];
        int     indx2 = (indx + Random.Range(1, convex.Count - 1)) % convex.Count;
        Vector3 a2    = convex[indx2];
        //Debug.Log(string.Format("Using indices {0} {1} ({2})", indx, indx2, convex.Count));
        List <List <Vector3> > testPaths = new List <List <Vector3> >();

        if (a1.x == a2.x || a1.z == a2.z)
        {
            testPaths.Add(new List <Vector3>()
            {
                a1, a2
            });
            //Debug.Log(string.Format("Test simple wall {0} {1}", a1, a2));
        }
        else
        {
            Vector3[] c = new Vector3[2] {
                new Vector3(a1.x, 0, a2.z), new Vector3(a2.x, 0, a1.z)
            };
            for (int i = 0; i < 2; i++)
            {
                testPaths.Add(new List <Vector3>()
                {
                    a1, c[i], a2
                });
            }
        }

        for (int i = 0, l = testPaths.Count; i < l; i++)
        {
            List <Vector3> newWall = testPaths[i];
            int            testIndex;
            int            pathIndex;

            bool isKnown = false;
            for (int idW = 0, wL = newWall.Count; idW < wL - 1; idW++)
            {
                if (ProcGenHelpers.IsKnownSegment(newWall[idW], newWall[idW + 1], true, perimeter) ||
                    ProcGenHelpers.IsKnownSegment(newWall[idW], newWall[idW + 1], wallLines))
                {
                    isKnown = true;
                    break;
                }
            }

            if (isKnown)
            {
                //Debug.Log("Inner wall collided with previously known wall");
            }
            else if (ProcGenHelpers.CollidesWith(newWall, perimeter, true, out testIndex, out pathIndex))
            {
                Debug.Log(string.Format("Inner wall {0} {1} collides at ({2} | {3})", newWall[testIndex], newWall[testIndex + 1], testIndex, pathIndex));
            }
            else
            {
                int pathsIndex;
                if (ProcGenHelpers.CollidesWith(newWall, wallLines, out testIndex, out pathIndex, out pathsIndex))
                {
                    Debug.Log("Collides with inner wall");
                }
                else
                {
                    //Debug.Log(string.Format("Added curved wall {0} {1} {2}", newWall.Count, newWall[0], newWall[newWall.Count -1]));
                    wallLines.Add(newWall);
                    room = true;
                    if (newWall.Count == 3)
                    {
                        convex.Add(newWall[1]);
                    }

                    break;
                }
            }
        }

        return(room);
    }
    bool MapWallToWall()
    {
        bool room = false;
        //Min length to divide
        float        longest = Mathf.Pow(shortestWall * 2, 2);
        List <float> lens    = new List <float>();

        for (int i = 0, l = perimeter.Count; i < l; i++)
        {
            int nextI = (i + 1) % l;
            lens.Add((perimeter[nextI] - perimeter[i]).sqrMagnitude);
        }
        int c = lens.Where(e => e > longest).Count();

        if (c > 0)
        {
            int v = Random.Range(0, c) + 1;

            //TODO: need to use also inner walls I thinks

            List <int> sums = new List <int>();
            lens.Aggregate(0, (sum, e) => { sum += e > longest ? 1 : 0; sums.Add(sum); return(sum); });
            int idLong = sums.IndexOf(v);

            longest = Mathf.Sqrt(lens[idLong]);
            float flexPos = longest - 2 * shortestWall;
            int   nextI   = (idLong + 1) % perimeter.Count;
            float t       = (Random.value * flexPos + shortestWall) / longest;
            //Debug.Log(t);
            Vector3 pt = Vector3.Lerp(perimeter[idLong], perimeter[nextI], t);

            Vector3 d = ProcGenHelpers.Get90CW(pt - perimeter[idLong]).normalized;
            AddGizmoWall(pt, pt + d);
            Vector3 ptB;
            //Debug.Log(string.Format("{0} - {1}, {2}, d {3}", perimeter[idLong], perimeter[nextI], pt, d));

            if (ProcGenHelpers.RayInterceptsSegment(pt, d, perimeter, out ptB))
            {
                bool    perim2Perim = true;
                Vector3 ptC;
                bool    allowWall = true;
                int     idLine;
                if (ProcGenHelpers.RayInterceptsSegment(pt, d, wallLines, out ptC, out idLine))
                {
                    if (ProcGenHelpers.TooClose(pt, wallLines[idLine], shortestWall) || ProcGenHelpers.IsKnownSegment(pt, ptC, wallLines) || ProcGenHelpers.IsKnownSegment(pt, ptC, true, perimeter))
                    {
                        allowWall = false;
                    }
                    else
                    {
                        //Debug.Log("Wall construction intercept inner wall");
                        nonConcave.Add(ptB);
                        if ((ptC - pt).sqrMagnitude < (ptB - pt).sqrMagnitude)
                        {
                            ptB         = ptC;
                            perim2Perim = false;
                        }
                    }
                }
                else if (ProcGenHelpers.IsKnownSegment(pt, ptB, true, perimeter))
                {
                    allowWall = false;
                }

                if (allowWall && (ptB - pt).magnitude > shortestWall && !ProcGenHelpers.TooClose(pt, perimeter, shortestWall))
                {
                    wallLines.Add(new List <Vector3>()
                    {
                        pt, ptB
                    });
                    if (!nonConcave.Contains(pt))
                    {
                        nonConcave.Add(pt);
                    }
                    if (!nonConcave.Contains(ptB))
                    {
                        nonConcave.Add(ptB);
                    }
                    room = true;
                    perimeter.Insert(idLong + 1, pt);

                    if (perim2Perim)
                    {
                        for (int i = 0, l = perimeter.Count; i < l; i++)
                        {
                            int j = (i + 1) % l;
                            if (ProcGenHelpers.PointOnSegmentXZ(perimeter[i], perimeter[j], ptB))
                            {
                                perimeter.Insert(i + 1, ptB);
                                Debug.Log("Inserted perim to perim");
                                break;
                            }
                        }
                    }

                    Debug.Log("Inserted free wall");
                }
            }
        }

        return(room);
    }