Vector3 GetClampedPosition(ref Matrix4x4 mat, Terrain terrain) { var position = Matrix.GetTranslation(ref mat); position.y = LandscapeDataRasterizer.GetHeight(terrain, position.x, position.z); return(position); }
void UpdateHeights(GridDungeonModel model) { if (terrain == null || terrain.terrainData == null) { return; } var rasterizer = new LandscapeDataRasterizer(terrain, groundLevelHeight); rasterizer.LoadData(); var gridSize = model.Config.GridCellSize; // Raise the terrain foreach (var cell in model.Cells) { var locationGrid = cell.Bounds.Location; var location = locationGrid * gridSize; var size = cell.Bounds.Size * gridSize; var cellY = location.y + layoutLevelOffset; rasterizer.DrawCell(location.x, location.z, size.x, size.z, cellY); } // Smooth the terrain ApplySmoothing(model, rasterizer); rasterizer.SaveData(); }
protected virtual void ApplySmoothing(GridDungeonModel model, LandscapeDataRasterizer rasterizer) { var gridSize = model.Config.GridCellSize; foreach (var cell in model.Cells) { var locationGrid = cell.Bounds.Location; var location = locationGrid * gridSize; var size = cell.Bounds.Size * gridSize; var cellY = location.y + layoutLevelOffset; var curve = (cell.CellType == CellType.Room) ? roomElevationCurve : corridorElevationCurve; rasterizer.SmoothCell(location.x, location.z, size.x, size.z, cellY, smoothingDistance, curve); } }
void UpdateBaseTexture(GridDungeonModel model, float[, ,] map) { var gridSize = model.Config.GridCellSize; var layoutMap = new float[map.GetLength(0), map.GetLength(1)]; foreach (var cell in model.Cells) { var bounds = cell.Bounds; var locationGrid = bounds.Location; var location = locationGrid * gridSize; var size = bounds.Size * gridSize; int gx1, gy1, gx2, gy2; LandscapeDataRasterizer.WorldToTerrainTextureCoord(terrain, location.x, location.z, out gx1, out gy1); LandscapeDataRasterizer.WorldToTerrainTextureCoord(terrain, location.x + size.x, location.z + size.z, out gx2, out gy2); for (var gx = gx1; gx <= gx2; gx++) { for (var gy = gy1; gy <= gy2; gy++) { layoutMap[gy, gx] = 1; } } } // Blur the layout data var filter = new BlurFilter(roadBlurDistance); layoutMap = filter.ApplyFilter(layoutMap); var data = terrain.terrainData; // Fill up the inner region with corridor index for (var y = 0; y < data.alphamapHeight; y++) { for (var x = 0; x < data.alphamapWidth; x++) { bool corridor = (layoutMap[y, x] > corridorBlurThreshold); if (corridor) { for (int layer = 0; layer < data.alphamapLayers; layer++) { var weight = (layer == corridorTextureIndex) ? 1 : 0; map[y, x, layer] = weight; } } } } }
public override void GetTransform(PropSocket socket, DungeonModel model, Matrix4x4 propTransform, System.Random random, out Vector3 outPosition, out Quaternion outRotation, out Vector3 outScale) { base.GetTransform(socket, model, propTransform, random, out outPosition, out outRotation, out outScale); var terrain = Terrain.activeTerrain; if (terrain == null) { return; } var position = Matrix.GetTranslation(ref propTransform); var currentY = position.y; var targetY = LandscapeDataRasterizer.GetHeight(terrain, position.x, position.z); outPosition.y = targetY - currentY; }
void UpdateDetailTexture(GridDungeonModel model, int[,] map) { var gridSize = model.Config.GridCellSize; foreach (var cell in model.Cells) { var bounds = cell.Bounds; var locationGrid = bounds.Location; var location = locationGrid * gridSize; var size = bounds.Size * gridSize; int gx1, gy1, gx2, gy2; LandscapeDataRasterizer.WorldToTerrainDetailCoord(terrain, location.x, location.z, out gx1, out gy1); LandscapeDataRasterizer.WorldToTerrainDetailCoord(terrain, location.x + size.x, location.z + size.z, out gx2, out gy2); for (var gx = gx1; gx <= gx2; gx++) { for (var gy = gy1; gy <= gy2; gy++) { map[gy, gx] = 0; } } } }
void UpdateBaseTexture(SimpleCityDungeonModel model, float[,,] map) { if (terrain == null) { return; } int fillIndex = GetTextureIndex(SimpleCityLandscapeTextureType.Fill); if (fillIndex < 0) { return; } var data = terrain.terrainData; // Fill up the entire space with the fill texture for (var y = 0; y < data.alphamapHeight; y++) { for (var x = 0; x < data.alphamapWidth; x++) { for (int t = 0; t < textures.Length; t++) { var ratio = (t == fillIndex) ? 1 : 0; map[y, x, t] = ratio; } } } var activeTextureTypes = new SimpleCityLandscapeTextureType[] { SimpleCityLandscapeTextureType.Park, SimpleCityLandscapeTextureType.Road, SimpleCityLandscapeTextureType.CityWallPadding, }; var activeCellTypes = new SimpleCityCellType[] { SimpleCityCellType.Park, SimpleCityCellType.Road, SimpleCityCellType.CityWallPadding, }; var dataMaps = new List <float[, ]>(); for (int i = 0; i < activeTextureTypes.Length; i++) { dataMaps.Add(new float[map.GetLength(0), map.GetLength(1)]); } var gridSize2D = model.Config.CellSize; var gridSize = new Vector3(gridSize2D.x, 0, gridSize2D.y); var cells = new List <SimpleCityCell>(); foreach (var cell in model.Cells) { cells.Add(cell); } cells.AddRange(model.WallPaddingCells); foreach (var cell in cells) { var locationGrid = cell.Position; var location = locationGrid * gridSize - gridSize / 2.0f; var size = gridSize; int gx1, gy1, gx2, gy2; LandscapeDataRasterizer.WorldToTerrainTextureCoord(terrain, location.x, location.z, out gx1, out gy1); LandscapeDataRasterizer.WorldToTerrainTextureCoord(terrain, location.x + size.x, location.z + size.z, out gx2, out gy2); for (int i = 0; i < activeTextureTypes.Length; i++) { //SimpleCityLandscapeTextureType activeTexType = activeTextureTypes[i]; SimpleCityCellType activeCellType = activeCellTypes[i]; //int textureIndex = GetTextureIndex(activeTexType); var dataMap = dataMaps[i]; for (var gx = gx1; gx <= gx2; gx++) { for (var gy = gy1; gy <= gy2; gy++) { dataMap[gy, gx] = (cell.CellType == activeCellType) ? 1 : 0; } } } } // Blur the layout data var filter = new BlurFilter(roadBlurDistance); for (int i = 0; i < dataMaps.Count; i++) { dataMaps[i] = filter.ApplyFilter(dataMaps[i]); } for (int i = 0; i < dataMaps.Count; i++) { var dataMap = dataMaps[i]; int textureIndex = GetTextureIndex(activeTextureTypes[i]); if (textureIndex < 0) { continue; } for (var y = 0; y < data.alphamapHeight; y++) { for (var x = 0; x < data.alphamapWidth; x++) { map[y, x, textureIndex] = dataMap[y, x]; if (textureIndex != fillIndex) { map[y, x, fillIndex] -= dataMap[y, x]; map[y, x, fillIndex] = Mathf.Clamp01(map[y, x, fillIndex]); } } } } // Normalize for (var y = 0; y < data.alphamapHeight; y++) { for (var x = 0; x < data.alphamapWidth; x++) { // Apply the curves for (int t = 0; t < textures.Length; t++) { var curve = textures[t].curve; if (curve != null && curve.keys.Length > 0) { map[y, x, t] = curve.Evaluate(map[y, x, t]); } } float sum = 0; for (int t = 0; t < textures.Length; t++) { sum += map[y, x, t]; } for (int t = 0; t < textures.Length; t++) { map[y, x, t] /= sum; } } } for (int layer = 0; layer < data.detailPrototypes.Length; layer++) { var foliageMap = data.GetDetailLayer(0, 0, data.detailWidth, data.detailHeight, layer); for (int x = 0; x < data.detailWidth; x++) { float nx = x / (float)(data.detailWidth - 1); int sampleX = Mathf.RoundToInt(nx * (data.alphamapWidth - 1)); for (int y = 0; y < data.detailHeight; y++) { float ny = y / (float)(data.detailHeight - 1); int sampleY = Mathf.RoundToInt(ny * (data.alphamapHeight - 1)); float influence = 0; foreach (var foliageTheme in foliage) { var textureIndex = GetTextureIndex(foliageTheme.textureType); if (textureIndex < 0) { continue; } foreach (var entry in foliageTheme.foliageEntries) { if (entry.grassIndex == layer) { float mapData = map[sampleY, sampleX, textureIndex]; if (foliageTheme.curve != null && foliageTheme.curve.length > 0) { mapData = foliageTheme.curve.Evaluate(mapData); } float alpha = mapData * entry.density * foliageTheme.density; influence += alpha; } } } int value = Mathf.FloorToInt(influence); float frac = influence - value; if (Random.value < frac) { value++; } foliageMap[y, x] = value; } } data.SetDetailLayer(0, 0, layer, foliageMap); } /* * // Update foliage * foreach (var foliageTheme in foliage) * { * var textureIndex = GetTextureIndex(foliageTheme.textureType); * if (textureIndex < 0) continue; * foreach (var entry in foliageTheme.foliageEntries) * { * int layer = entry.grassIndex; * var foliageMap = data.GetDetailLayer(0, 0, data.detailWidth, data.detailHeight, layer); * for (int x = 0; x < data.detailWidth; x++) * { * float nx = x / (float)(data.detailWidth - 1); * int sampleX = Mathf.RoundToInt(nx * (data.alphamapWidth - 1)); * for (int y = 0; y < data.detailHeight; y++) * { * float ny = y / (float)(data.detailHeight - 1); * int sampleY = Mathf.RoundToInt(ny * (data.alphamapHeight - 1)); * * float alpha = map[sampleY, sampleX, textureIndex] * entry.density * foliageTheme.density; * int value = Mathf.FloorToInt(alpha); * float frac = alpha - value; * if (Random.value < frac) value++; * foliageMap[y, x] = value; * } * } * * data.SetDetailLayer(0, 0, layer, foliageMap); * } * } */ }
void UpdateBaseTexture(GridDungeonModel model, float[,,] map) { if (terrain == null) { return; } int fillIndex = GetTextureIndex(LandscapeTextureType.Fill); if (fillIndex < 0) { return; } var data = terrain.terrainData; // Fill up the entire space with the fill texture for (var y = 0; y < data.alphamapHeight; y++) { for (var x = 0; x < data.alphamapWidth; x++) { for (int t = 0; t < textures.Length; t++) { var ratio = (t == fillIndex) ? 1 : 0; map[y, x, t] = ratio; } } } int corridorIndex = GetTextureIndex(LandscapeTextureType.Corridor); int roomIndex = GetTextureIndex(LandscapeTextureType.Room); if (roomIndex < 0 && corridorIndex < 0) { // Both corridor and room textures were not provided. Fill them up with the fill index roomIndex = fillIndex; corridorIndex = fillIndex; } else if (roomIndex < 0) { // Use the same texture for the room used by the corridor roomIndex = corridorIndex; } else if (corridorIndex < 0) { // Use the same texture for the corridor used by the room corridorIndex = roomIndex; } // Apply the room/corridor texture { var gridSize = model.Config.GridCellSize; var roomMap = new float[map.GetLength(0), map.GetLength(1)]; var corridorMap = new float[map.GetLength(0), map.GetLength(1)]; foreach (var cell in model.Cells) { var bounds = cell.Bounds; var locationGrid = bounds.Location; var location = locationGrid * gridSize; var size = bounds.Size * gridSize; int gx1, gy1, gx2, gy2; LandscapeDataRasterizer.WorldToTerrainTextureCoord(terrain, location.x, location.z, out gx1, out gy1); LandscapeDataRasterizer.WorldToTerrainTextureCoord(terrain, location.x + size.x, location.z + size.z, out gx2, out gy2); for (var gx = gx1; gx <= gx2; gx++) { for (var gy = gy1; gy <= gy2; gy++) { if (cell.CellType == CellType.Unknown) { continue; } if (cell.CellType == CellType.Room) { roomMap[gy, gx] = 1; } else { corridorMap[gy, gx] = 1; } } } } // Blur the layout data var filter = new BlurFilter(roadBlurDistance); roomMap = filter.ApplyFilter(roomMap); corridorMap = filter.ApplyFilter(corridorMap); // Fill up the inner region with corridor index for (var y = 0; y < data.alphamapHeight; y++) { for (var x = 0; x < data.alphamapWidth; x++) { bool corridor = (corridorMap[y, x] > corridorBlurThreshold); if (corridor) { map[y, x, fillIndex] = 0; map[y, x, roomIndex] = 0; map[y, x, corridorIndex] = 1; } bool room = (roomMap[y, x] > roomBlurThreshold); if (room) { map[y, x, fillIndex] = 0; map[y, x, corridorIndex] = 0; map[y, x, roomIndex] = 1; } } } } }