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 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); }