From b6b2dce32e5be8a89943a9f22f62722d097456c1 Mon Sep 17 00:00:00 2001 From: Tiberiu Chibici Date: Fri, 22 May 2015 11:26:29 +0300 Subject: [PATCH] Implemented population center generator --- Game/Assembly-CSharp-vs.csproj | 4 +- Game/Assembly-CSharp.csproj | 4 +- Game/Assets/Scripts/Business/BiomeManager.cs | 6 +- .../Scripts/Business/ConfigurationManager.cs | 2 +- .../Assets/Scripts/Generator/CityGenerator.cs | 43 ++++++++++ .../Scripts/Generator/CityGenerator.cs.meta | 12 +++ .../Generator/PopulationCentersGenerator.cs | 36 ++++++++ .../PopulationCentersGenerator.cs.meta | 12 +++ .../Scripts/Generator/TerrainGenerator.cs | 13 --- Game/Assets/Scripts/Model/Map.cs | 77 ++++++++---------- Game/Assets/Scripts/Model/Point.cs | 23 ++++++ Game/Assets/Scripts/Model/Point.cs.meta | 12 +++ .../Scripts/Unity/TerrainGeneratorScript.cs | 2 +- Game/Assets/Scripts/Utils/Logger.cs | 7 ++ .../Scripts/Utils/SerializationHelper.cs | 26 +++++- Game/Game-csharp.sln | 2 +- Game/Game.sln | 2 +- Game/ProjectSettings/QualitySettings.asset | Bin 4664 -> 4664 bytes Game/UnityVS.Game.CSharp.csproj | 3 + .../MapViewer/Business/MapRenderer.cs | 44 +++++++--- Tools/MapViewer/MapViewer/MainWindow.xaml | 4 +- Tools/MapViewer/MapViewer/MainWindow.xaml.cs | 29 ++++++- .../MapViewer/MapViewer/Storage/MapStorage.cs | 12 +-- 23 files changed, 277 insertions(+), 98 deletions(-) create mode 100644 Game/Assets/Scripts/Generator/CityGenerator.cs create mode 100644 Game/Assets/Scripts/Generator/CityGenerator.cs.meta create mode 100644 Game/Assets/Scripts/Generator/PopulationCentersGenerator.cs create mode 100644 Game/Assets/Scripts/Generator/PopulationCentersGenerator.cs.meta create mode 100644 Game/Assets/Scripts/Model/Point.cs create mode 100644 Game/Assets/Scripts/Model/Point.cs.meta diff --git a/Game/Assembly-CSharp-vs.csproj b/Game/Assembly-CSharp-vs.csproj index 94fcce8..48d0c2e 100644 --- a/Game/Assembly-CSharp-vs.csproj +++ b/Game/Assembly-CSharp-vs.csproj @@ -48,11 +48,14 @@ + + + @@ -71,7 +74,6 @@ - diff --git a/Game/Assembly-CSharp.csproj b/Game/Assembly-CSharp.csproj index eded667..a05e351 100644 --- a/Game/Assembly-CSharp.csproj +++ b/Game/Assembly-CSharp.csproj @@ -48,11 +48,14 @@ + + + @@ -71,7 +74,6 @@ - diff --git a/Game/Assets/Scripts/Business/BiomeManager.cs b/Game/Assets/Scripts/Business/BiomeManager.cs index 15ce7b2..81d07fd 100644 --- a/Game/Assets/Scripts/Business/BiomeManager.cs +++ b/Game/Assets/Scripts/Business/BiomeManager.cs @@ -33,12 +33,8 @@ namespace TransportGame.Business { try { - // Open file - var stream = File.OpenRead(file); - // Try to deserialize biome - XmlSerializer serializer = new XmlSerializer(typeof(Biome)); - var biome = (Biome)serializer.Deserialize(stream); + var biome = SerializationHelper.DeserializeXml(file); biome.FileName = file; // Add it to biome list diff --git a/Game/Assets/Scripts/Business/ConfigurationManager.cs b/Game/Assets/Scripts/Business/ConfigurationManager.cs index f4ef0d4..81a3f9d 100644 --- a/Game/Assets/Scripts/Business/ConfigurationManager.cs +++ b/Game/Assets/Scripts/Business/ConfigurationManager.cs @@ -21,7 +21,7 @@ namespace TransportGame.Business public static void LoadConfiguration() { // Load terrgen config - TerrGenConfig = SerializationHelper.Deserialize(Path.Combine(ConfigurationDirectory, TerrGenConfigFile)); + TerrGenConfig = SerializationHelper.DeserializeXml(Path.Combine(ConfigurationDirectory, TerrGenConfigFile)); } } } diff --git a/Game/Assets/Scripts/Generator/CityGenerator.cs b/Game/Assets/Scripts/Generator/CityGenerator.cs new file mode 100644 index 0000000..7144195 --- /dev/null +++ b/Game/Assets/Scripts/Generator/CityGenerator.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using TransportGame.Generator; +using TransportGame.Model; +using TransportGame.Utils; + +namespace TransportGame.Generator +{ + /// + /// Complete city generator. Generates everything, from terrain to buildings + /// + public class CityGenerator + { + /// + /// Generates a city + /// + /// Width + /// Height + /// City + public Map Generate(int width, int height) + { + Map map; + + // Generate terrain + TerrainGenerator terrainGen = new TerrainGenerator(); + map = terrainGen.Generate(width, height); + + // Generate population map + PopulationCentersGenerator populationGen = new PopulationCentersGenerator(); + populationGen.Generate(map); + + // Generate roads + // TODO: Generate roads + + Logger.DumpMap(map, "withpop.map"); + + // Done + return map; + } + } +} diff --git a/Game/Assets/Scripts/Generator/CityGenerator.cs.meta b/Game/Assets/Scripts/Generator/CityGenerator.cs.meta new file mode 100644 index 0000000..7cc4aa7 --- /dev/null +++ b/Game/Assets/Scripts/Generator/CityGenerator.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 723d5ad7f5932f649971961655fff523 +timeCreated: 1432200350 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Game/Assets/Scripts/Generator/PopulationCentersGenerator.cs b/Game/Assets/Scripts/Generator/PopulationCentersGenerator.cs new file mode 100644 index 0000000..215c3c2 --- /dev/null +++ b/Game/Assets/Scripts/Generator/PopulationCentersGenerator.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using TransportGame.Model; +using TransportGame.Noise; +using UnityEngine; + +namespace TransportGame.Generator +{ + public class PopulationCentersGenerator + { + System.Random random = new System.Random(); + + public void Generate(Map map) + { + // Generate a number of points + int maxPoints = map.Width * map.Height / (1024 * 512); + int points = random.Next(maxPoints / 4, maxPoints); + + for (int i = 0; i < points; ++i) + { + int px, py; + + do + { + px = random.Next(map.Width); + py = random.Next(map.Height); + } + while (map.IsWater(px, py)); + + map.PopulationCenters.Add(new Point(px, py)); + } + } + } +} diff --git a/Game/Assets/Scripts/Generator/PopulationCentersGenerator.cs.meta b/Game/Assets/Scripts/Generator/PopulationCentersGenerator.cs.meta new file mode 100644 index 0000000..c4210ee --- /dev/null +++ b/Game/Assets/Scripts/Generator/PopulationCentersGenerator.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 186756c7c690a3d4c8e633e3007523e0 +timeCreated: 1432200350 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Game/Assets/Scripts/Generator/TerrainGenerator.cs b/Game/Assets/Scripts/Generator/TerrainGenerator.cs index c13632c..9ca0286 100644 --- a/Game/Assets/Scripts/Generator/TerrainGenerator.cs +++ b/Game/Assets/Scripts/Generator/TerrainGenerator.cs @@ -50,8 +50,6 @@ namespace TransportGame.Generator float waterAmount = random.NextSingle(map.Biome.Moisture.Minimum, map.Biome.Moisture.Maximum); map.WaterLevel = Mathf.Pow(waterAmount, ConfigurationManager.TerrGenConfig.WaterNonLinearPower) * map.Biome.Height; - DumpData(map, "dump.map"); - return map; } @@ -69,16 +67,5 @@ namespace TransportGame.Generator for (int y = 0; y < map.Height; ++y) map.Heightmap[x, y] = Noise.Generate(x, y, 0, 1); } - - private void DumpData(Map map, string filename) - { - XmlSerializer serializer = new XmlSerializer(typeof(Map)); - - using (StreamWriter writer = new StreamWriter(Path.Combine(Logger.LogsDirectory, filename))) - { - serializer.Serialize(writer, map); - writer.Close(); - } - } } } diff --git a/Game/Assets/Scripts/Model/Map.cs b/Game/Assets/Scripts/Model/Map.cs index 0ba9477..53e7407 100644 --- a/Game/Assets/Scripts/Model/Map.cs +++ b/Game/Assets/Scripts/Model/Map.cs @@ -5,6 +5,7 @@ using System.Text; using System.Xml.Serialization; using TransportGame.Model.Road; using TransportGame.Utils; +using UnityEngine; namespace TransportGame.Model { @@ -12,7 +13,6 @@ namespace TransportGame.Model public class Map { private float[,] heightmap; - private float[,] population; #region Properties @@ -69,48 +69,11 @@ namespace TransportGame.Model public int Height { get { return (heightmap == null) ? 0 : heightmap.GetLength(1); } } /// - /// Gets the population map + /// Gets or sets the population map /// - [XmlIgnore()] - public float[,] Population - { - get - { - return population; - } - set - { - population = value; - } - } - - /// - /// Gets or sets the population as raw bytes - /// - [XmlElement("population")] - public byte[] PopulationRaw - { - get - { - return population.ToByteArray(); - } - set - { - population = value.GetFloatMatrix(); - } - } - - /// - /// Gets width of population map - /// - [XmlIgnore] - public int PopulationWidth { get { return (population == null) ? 0 : population.GetLength(0); } } - - /// - /// Gets height of population map - /// - [XmlIgnore] - public int PopulationHeight { get { return (population == null) ? 0 : population.GetLength(1); } } + [XmlArray("populationCenters")] + [XmlArrayItem("center")] + public List PopulationCenters { get; set; } /// /// Gets or sets the articulation road network @@ -130,6 +93,7 @@ namespace TransportGame.Model /// public Map() { + PopulationCenters = new List(); } /// @@ -140,6 +104,7 @@ namespace TransportGame.Model public Map(int width, int height) { heightmap = new float[width, height]; + PopulationCenters = new List(); } #endregion @@ -204,5 +169,33 @@ namespace TransportGame.Model return dx * dx + dy * dy; } + + /// + /// Gets population using terrain coordinates + /// + /// X + /// Y + /// Population + public float GetPopulation(int x, int y) + { + const int maxDistance = 400; + float value = 0; + + foreach (var point in PopulationCenters) + { + int x1 = x - point.X; + int y1 = y - point.Y; + + int dist = x1 * x1 + y1 * y1; + if (dist < maxDistance * maxDistance) + { + float influence = 1 - (float)dist / (float)(maxDistance * maxDistance); + influence = Mathf.Pow(influence, 3); // Ease + value = Mathf.Clamp01(value + influence); + } + } + + return value; + } } } diff --git a/Game/Assets/Scripts/Model/Point.cs b/Game/Assets/Scripts/Model/Point.cs new file mode 100644 index 0000000..082326f --- /dev/null +++ b/Game/Assets/Scripts/Model/Point.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace TransportGame.Model +{ + public class Point + { + public int X { get; set; } + public int Y { get; set; } + + public Point() + { + } + + public Point(int x, int y) + { + X = x; + Y = y; + } + } +} diff --git a/Game/Assets/Scripts/Model/Point.cs.meta b/Game/Assets/Scripts/Model/Point.cs.meta new file mode 100644 index 0000000..050e95e --- /dev/null +++ b/Game/Assets/Scripts/Model/Point.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 94117dad82214b44382141a14825994e +timeCreated: 1432281052 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Game/Assets/Scripts/Unity/TerrainGeneratorScript.cs b/Game/Assets/Scripts/Unity/TerrainGeneratorScript.cs index 3a6b8f9..72baf19 100644 --- a/Game/Assets/Scripts/Unity/TerrainGeneratorScript.cs +++ b/Game/Assets/Scripts/Unity/TerrainGeneratorScript.cs @@ -23,7 +23,7 @@ public class TerrainGeneratorScript : MonoBehaviour private void GenerateTerrainThread() { - TerrainGenerator generator = new TerrainGenerator(); + CityGenerator generator = new CityGenerator(); map = generator.Generate(TerrainWidth, TerrainHeight); } diff --git a/Game/Assets/Scripts/Utils/Logger.cs b/Game/Assets/Scripts/Utils/Logger.cs index bedf597..eb94805 100644 --- a/Game/Assets/Scripts/Utils/Logger.cs +++ b/Game/Assets/Scripts/Utils/Logger.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Xml.Serialization; using TransportGame.Business; +using TransportGame.Model; namespace TransportGame.Utils { @@ -84,5 +86,10 @@ namespace TransportGame.Utils { Log(Level.Critical, "{0}: {1}\nStack trace:{2}", ex.GetType().ToString(), ex.Message, ex.StackTrace); } + + public static void DumpMap(Map map, string filename) + { + map.SerializeXml(Path.Combine(LogsDirectory, filename)); + } } } diff --git a/Game/Assets/Scripts/Utils/SerializationHelper.cs b/Game/Assets/Scripts/Utils/SerializationHelper.cs index b95a950..9907a15 100644 --- a/Game/Assets/Scripts/Utils/SerializationHelper.cs +++ b/Game/Assets/Scripts/Utils/SerializationHelper.cs @@ -86,11 +86,31 @@ namespace TransportGame.Utils /// Type to deserialize /// File name /// Deserialized object - public static T Deserialize(string filename) + public static T DeserializeXml(string filename) { XmlSerializer serializer = new XmlSerializer(typeof(T)); - var stream = new StreamReader(filename); - return (T)serializer.Deserialize(stream); + using (var stream = new StreamReader(filename)) + { + T data = (T)serializer.Deserialize(stream); + stream.Close(); + return data; + } + } + + /// + /// Serializes an object to a file + /// + /// + /// + public static void SerializeXml(this T data, string filename) + { + XmlSerializer serializer = new XmlSerializer(typeof(T)); + + using (StreamWriter writer = new StreamWriter(filename)) + { + serializer.Serialize(writer, data); + writer.Close(); + } } } } diff --git a/Game/Game-csharp.sln b/Game/Game-csharp.sln index 89caa8b..dd92830 100644 --- a/Game/Game-csharp.sln +++ b/Game/Game-csharp.sln @@ -23,7 +23,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution + GlobalSection(MonoDevelopProperties) = preSolution StartupItem = Assembly-CSharp.csproj Policies = $0 $0.TextStylePolicy = $1 diff --git a/Game/Game.sln b/Game/Game.sln index 71a9804..bd3a86c 100644 --- a/Game/Game.sln +++ b/Game/Game.sln @@ -29,7 +29,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution + GlobalSection(MonoDevelopProperties) = preSolution StartupItem = Assembly-CSharp.csproj Policies = $0 $0.TextStylePolicy = $1 diff --git a/Game/ProjectSettings/QualitySettings.asset b/Game/ProjectSettings/QualitySettings.asset index 4baf357eec7a92d1dc1ef3822eecce2fe03eda87..2d0076e954aeefb6855c17c4ccbbd30335712a59 100644 GIT binary patch delta 36 qcmdm?vO`6hfr0HD1A~wS0|Ns;1A_pNVqh@UGte_kGu$XGD+B;<90ipC delta 36 qcmdm?vO`6hfr0HT1A~wS0|Nse1A_pNVqh@UGte_gGubFDD+B;;^aYgw diff --git a/Game/UnityVS.Game.CSharp.csproj b/Game/UnityVS.Game.CSharp.csproj index d6d29a1..e2863ea 100644 --- a/Game/UnityVS.Game.CSharp.csproj +++ b/Game/UnityVS.Game.CSharp.csproj @@ -72,11 +72,14 @@ + + + diff --git a/Tools/MapViewer/MapViewer/Business/MapRenderer.cs b/Tools/MapViewer/MapViewer/Business/MapRenderer.cs index bf693ee..8723d2b 100644 --- a/Tools/MapViewer/MapViewer/Business/MapRenderer.cs +++ b/Tools/MapViewer/MapViewer/Business/MapRenderer.cs @@ -12,7 +12,8 @@ namespace TransportGame.MapViewer { None = 0, Elevation = 1, - All = Elevation + Population = 2, + All = Elevation | Population }; /// @@ -36,7 +37,7 @@ namespace TransportGame.MapViewer private readonly Color WaterColor = Colors.Navy; private readonly Color ElevationTerrainColor = Colors.White; - private readonly Color TerrainColor = Colors.Gray; + private readonly Color TerrainColor = Colors.Silver; public MapRenderer() { @@ -57,14 +58,24 @@ namespace TransportGame.MapViewer Bitmap24 bitmap = new Bitmap24(Convert.ToInt32(map.Width * Scale), Convert.ToInt32(map.Height * Scale)); // First layer - cells - DrawCells(bitmap, map, (layers & Layers.Elevation) > 0); + DrawPixels(bitmap, map, (layers & Layers.Elevation) > 0, (layers & Layers.Population) > 0); // Done return bitmap; } } - private void DrawCells(Bitmap24 bitmap, Map map, bool elevation) + private Color AlphaBlend(Color top, Color dst) + { + float A = top.ScA + dst.ScA * (1 - top.ScA); + float R = (top.ScR * top.ScA + dst.ScR * (1 - top.ScA)) / A; + float G = (top.ScG * top.ScA + dst.ScG * (1 - top.ScA)) / A; + float B = (top.ScB * top.ScA + dst.ScB * (1 - top.ScA)) / A; + + return Color.FromScRgb(A, R, G, B); + } + + private void DrawPixels(Bitmap24 bitmap, Map map, bool elevation, bool population) { for (int x = 0; x < bitmap.Width; x++) for (int y = 0; y < bitmap.Height; y++) @@ -76,17 +87,24 @@ namespace TransportGame.MapViewer if (map.IsWater(mapX, mapY)) bitmap[x, y] = WaterColor; - // Draw elevation - else if (elevation) - { - float alpha = map.Heightmap[mapX, mapY]; // map.Heights range is [0,1] - bitmap[x, y] = Color.Multiply(ElevationTerrainColor, alpha); - } - - // Draw terrain else { - bitmap[x, y] = TerrainColor; + // Draw elevation + if (elevation) + { + float alpha = map.Heightmap[mapX, mapY]; // map.Heights range is [0,1] + bitmap[x, y] = Color.Multiply(ElevationTerrainColor, alpha); + } + + // No elevation, just put a terrain color + else bitmap[x, y] = TerrainColor; + + // Population + if (population) + { + Color popColor = Color.FromScRgb(map.GetPopulation(mapX, mapY) * 0.7f, 1, 0, 1); + bitmap[x, y] = AlphaBlend(popColor, bitmap[x, y]); + } } } } diff --git a/Tools/MapViewer/MapViewer/MainWindow.xaml b/Tools/MapViewer/MapViewer/MainWindow.xaml index 66015c9..82f29c9 100644 --- a/Tools/MapViewer/MapViewer/MainWindow.xaml +++ b/Tools/MapViewer/MapViewer/MainWindow.xaml @@ -61,9 +61,7 @@ (All) Elevation - Roads - Buildings - Vegetation + Population