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