コード例 #1
0
    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);
    }
コード例 #2
0
    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);
    }