SimpleCityCell CreateCell(int x, int z, SimpleCityCellType cellType) { var cell = new SimpleCityCell(); cell.Position = new IntVector(x, 0, z); cell.CellType = cellType; cell.Rotation = Quaternion.identity; return(cell); }
void RemoveRoadEdge(int x, int z) { if (!IsStraightRoad(x, z)) { // Nothing to remove return; } var RoadsToRemove = new HashSet <IntVector>(); RoadsToRemove.Add(new IntVector(x, 0, z)); int index = x - 1; while (IsStraightRoad(index, z)) { RoadsToRemove.Add(new IntVector(index, 0, z)); index--; } index = x + 1; while (IsStraightRoad(index, z)) { RoadsToRemove.Add(new IntVector(index, 0, z)); index++; } index = z - 1; while (IsStraightRoad(x, index)) { RoadsToRemove.Add(new IntVector(x, 0, index)); index--; } index = z + 1; while (IsStraightRoad(x, index)) { RoadsToRemove.Add(new IntVector(x, 0, index)); index++; } foreach (IntVector Position in RoadsToRemove) { SimpleCityCell Cell = demoModel.Cells[Position.x, Position.z]; Cell.CellType = SimpleCityCellType.House; } }
void FaceHouseTowardsRoad(SimpleCityCell cell) { int x = cell.Position.x; int z = cell.Position.z; bool roadLeft = GetCellType(x - 1, z) == SimpleCityCellType.Road; bool roadRight = GetCellType(x + 1, z) == SimpleCityCellType.Road; bool roadTop = GetCellType(x, z - 1) == SimpleCityCellType.Road; bool roadBottom = GetCellType(x, z + 1) == SimpleCityCellType.Road; if (!roadLeft && !roadRight && !roadTop && !roadBottom) { // No roads nearby. promote to park cell.CellType = SimpleCityCellType.Park; cell.Rotation = Quaternion.Euler(0, 90 * (random.Next() % 4), 0); return; } float angle = 0; if (roadLeft) { angle = 0; } else if (roadRight) { angle = 180; } else if (roadTop) { angle = 270; } else if (roadBottom) { angle = 90; } cell.Rotation = Quaternion.Euler(0, angle, 0); }
void FaceHouseTowardsRoad(SimpleCityCell cell) { int x = cell.Position.x; int z = cell.Position.z; bool roadLeft = GetCellType(x - 1, z) == SimpleCityCellType.Road; bool roadRight = GetCellType(x + 1, z) == SimpleCityCellType.Road; bool roadTop = GetCellType(x, z - 1) == SimpleCityCellType.Road; bool roadBottom = GetCellType(x, z + 1) == SimpleCityCellType.Road; if (!roadLeft && !roadRight && !roadTop && !roadBottom) { cell.CellType = SimpleCityCellType.Park; // interior return; } float angle = 0; if (roadLeft) { angle = 0; } else if (roadRight) { angle = 180; } else if (roadTop) { angle = 270; } else if (roadBottom) { angle = 90; } cell.Rotation = Quaternion.Euler(0, angle, 0); }
/// <summary> /// Generate a layout and save it in the model /// </summary> void GenerateCityLayout() { var width = random.Range(demoConfig.minSize, demoConfig.maxSize); var length = random.Range(demoConfig.minSize, demoConfig.maxSize); demoModel.CityWidth = width; demoModel.CityHeight = length; demoModel.Cells = new SimpleCityCell[width, length]; for (int x = 0; x < width; x++) { for (int z = 0; z < length; z++) { var cell = new SimpleCityCell(); cell.Position = new IntVector(x, 0, z); cell.CellType = SimpleCityCellType.House; cell.Rotation = GetRandomRotation(); demoModel.Cells[x, z] = cell; } } // Build a road network by removing some houses // First build roads along the edge of the map for (int x = 0; x < width; x++) { MakeRoad(x, 0); MakeRoad(x, length - 1); } for (int z = 0; z < length; z++) { MakeRoad(0, z); MakeRoad(width - 1, z); } // Create roads in-between for (int x = GetRandomBlockSize() + 1; x < width; x += GetRandomBlockSize() + 1) { if (width - x <= 2) { continue; } for (int z = 0; z < length; z++) { MakeRoad(x, z); } } for (int z = GetRandomBlockSize() + 1; z < length; z += GetRandomBlockSize() + 1) { if (length - z <= 2) { continue; } for (int x = 0; x < width; x++) { MakeRoad(x, z); } } // Insert 2x houses (bigger houses) for (int x = 0; x < width; x++) { for (int z = 0; z < length; z++) { if (CanContainBiggerHouse(x, z)) { if (random.NextFloat() < demoConfig.biggerHouseProbability) { InsertBiggerHouse(x, z); } } } } for (int x = 0; x < width; x++) { for (int z = 0; z < length; z++) { var cell = demoModel.Cells[x, z]; if (cell.CellType == SimpleCityCellType.House) { FaceHouseTowardsRoad(cell); } } } // Create padding cells var padding = demoConfig.cityWallPadding; var paddedCells = new List <SimpleCityCell>(); for (int p = 1; p <= padding; p++) { var currentPadding = p; var sx = -currentPadding; var sz = -currentPadding; var ex = width + currentPadding - 1; var ez = length + currentPadding - 1; // Fill it with city wall padding marker for (int x = sx; x < ex; x++) { SimpleCityCellType cellType = SimpleCityCellType.CityWallPadding; paddedCells.Add(CreateCell(x, sz, cellType)); paddedCells.Add(CreateCell(x, ez, cellType)); } for (int z = sz; z < ez; z++) { SimpleCityCellType cellType = SimpleCityCellType.CityWallPadding; paddedCells.Add(CreateCell(sx, z, cellType)); paddedCells.Add(CreateCell(ex, z, cellType)); } } demoModel.WallPaddingCells = paddedCells.ToArray(); }
/// <summary> /// Generate a layout and save it in the model /// </summary> void GenerateCityLayout() { var width = random.Range(demoConfig.minSize, demoConfig.maxSize); var length = random.Range(demoConfig.minSize, demoConfig.maxSize); demoModel.CityWidth = width; demoModel.CityHeight = length; demoModel.Cells = new SimpleCityCell[width, length]; for (int x = 0; x < width; x++) { for (int z = 0; z < length; z++) { var cell = new SimpleCityCell(); cell.Position = new IntVector(x, 0, z); cell.CellType = SimpleCityCellType.House; cell.Rotation = GetRandomRotation(); demoModel.Cells[x, z] = cell; } } // Build a road network by removing some houses // First build roads along the edge of the map for (int x = 0; x < width; x++) { MakeRoad(x, 0); MakeRoad(x, length - 1); } for (int z = 0; z < length; z++) { MakeRoad(0, z); MakeRoad(width - 1, z); } // Create roads in-between for (int x = GetRandomBlockSize() + 1; x < width; x += GetRandomBlockSize() + 1) { if (width - x <= 2) { continue; } for (int z = 0; z < length; z++) { MakeRoad(x, z); } } for (int z = GetRandomBlockSize() + 1; z < length; z += GetRandomBlockSize() + 1) { if (length - z <= 2) { continue; } for (int x = 0; x < width; x++) { MakeRoad(x, z); } } RemoveRoadEdges(); // Insert bigger houses for (int x = 0; x < width; x++) { for (int z = 0; z < length; z++) { foreach (var blockDimension in demoConfig.customBlockDimensions) { bool bProcess = random.NextFloat() < blockDimension.probability; if (!bProcess) { continue; } int BlockWidth = blockDimension.sizeX; int BlockHeight = blockDimension.sizeZ; InsertHouseDelegate InsertHouse = delegate() { if (CanContainBiggerHouse(x, z, BlockWidth, BlockHeight)) { if (random.NextFloat() < demoConfig.biggerHouseProbability) { InsertBiggerHouse(x, z, BlockWidth, BlockHeight, 0, blockDimension.markerName); } } }; InsertHouseDelegate InsertHouse90 = delegate() { // Try the 90 degrees rotated version if (CanContainBiggerHouse(x, z, BlockHeight, BlockWidth)) { if (random.NextFloat() < demoConfig.biggerHouseProbability) { InsertBiggerHouse(x, z, BlockHeight, BlockWidth, 90, blockDimension.markerName); } } }; if (random.NextFloat() < 0.5f) { InsertHouse(); InsertHouse90(); } else { InsertHouse90(); InsertHouse(); } } } } for (int x = 0; x < width; x++) { for (int z = 0; z < length; z++) { var cell = demoModel.Cells[x, z]; if (cell.CellType == SimpleCityCellType.House) { FaceHouseTowardsRoad(cell); } } } // Create padding cells var padding = demoConfig.cityWallPadding; var paddedCells = new List <SimpleCityCell>(); for (int p = 1; p <= padding; p++) { var currentPadding = p; var sx = -currentPadding; var sz = -currentPadding; var ex = width + currentPadding - 1; var ez = length + currentPadding - 1; // Fill it with city wall padding marker for (int x = sx; x < ex; x++) { SimpleCityCellType cellType = SimpleCityCellType.CityWallPadding; paddedCells.Add(CreateCell(x, sz, cellType)); paddedCells.Add(CreateCell(x, ez, cellType)); } for (int z = sz; z < ez; z++) { SimpleCityCellType cellType = SimpleCityCellType.CityWallPadding; paddedCells.Add(CreateCell(sx, z, cellType)); paddedCells.Add(CreateCell(ex, z, cellType)); } } demoModel.WallPaddingCells = paddedCells.ToArray(); }