Fixed unity terrain generation bug.
This commit is contained in:
parent
8f9f935796
commit
68140b11a7
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,5 +1,7 @@
|
|||||||
## Ignore Visual Studio temporary files, build results, and
|
# Logs
|
||||||
## files generated by popular Visual Studio add-ons.
|
Game/Logs/
|
||||||
|
Game/[Oo]bj/
|
||||||
|
Game/[Tt]emp/
|
||||||
|
|
||||||
# User-specific files
|
# User-specific files
|
||||||
*.suo
|
*.suo
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<biome>
|
<biome>
|
||||||
<name>Grassland</name>
|
<name>Grassland</name>
|
||||||
<heightRange min="0" max="10" />
|
<height>100</height>
|
||||||
<moisture min=".1" max=".5"/>
|
<moisture min=".1" max=".5"/>
|
||||||
<vegetationDensity min=".2" max=".5" />
|
<vegetationDensity min=".2" max=".5" />
|
||||||
</biome>
|
</biome>
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<biome>
|
<biome>
|
||||||
<name>Mountain</name>
|
<name>Mountain</name>
|
||||||
<heightRange min="0" max="500" />
|
<height>500</height>
|
||||||
<moisture min=".1" max=".3"/>
|
<moisture min=".1" max=".3"/>
|
||||||
<vegetationDensity min=".5" max=".9" />
|
<vegetationDensity min=".5" max=".9" />
|
||||||
</biome>
|
</biome>
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<terrgenConfig>
|
<terrgenConfig>
|
||||||
<noiseOctaves>8</noiseOctaves>
|
<noiseOctaves>9</noiseOctaves>
|
||||||
<noiseNonLinearPower>2</noiseNonLinearPower>
|
<noiseNonLinearPower>2.4</noiseNonLinearPower>
|
||||||
<waterNonLinearPower>1.3</waterNonLinearPower>
|
<waterNonLinearPower>1.9</waterNonLinearPower>
|
||||||
<elevationScale>0.01</elevationScale>
|
<elevationScale>0.0005</elevationScale>
|
||||||
</terrgenConfig>
|
</terrgenConfig>
|
Binary file not shown.
@ -45,10 +45,14 @@ namespace TransportGame.Generator
|
|||||||
|
|
||||||
// Generate water level
|
// Generate water level
|
||||||
float waterAmount = random.NextSingle(map.Biome.Moisture.Minimum, map.Biome.Moisture.Maximum);
|
float waterAmount = random.NextSingle(map.Biome.Moisture.Minimum, map.Biome.Moisture.Maximum);
|
||||||
map.WaterLevel = Mathf.Pow(waterAmount, ConfigurationManager.TerrGenConfig.WaterNonLinearPower)
|
map.WaterLevel = Mathf.Pow(waterAmount, ConfigurationManager.TerrGenConfig.WaterNonLinearPower) * map.Biome.Height;
|
||||||
* (map.Biome.HeightRange.Maximum - map.Biome.HeightRange.Minimum) + map.Biome.HeightRange.Minimum;
|
|
||||||
|
DumpData(map, "1generated.map");
|
||||||
|
|
||||||
|
// Simulate water erosion
|
||||||
|
//Erode(map);
|
||||||
|
//DumpData(map, "2eroded.map");
|
||||||
|
|
||||||
DumpData(map);
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,14 +68,21 @@ namespace TransportGame.Generator
|
|||||||
{
|
{
|
||||||
for (int x = 0; x < map.Width; ++x)
|
for (int x = 0; x < map.Width; ++x)
|
||||||
for (int y = 0; y < map.Height; ++y)
|
for (int y = 0; y < map.Height; ++y)
|
||||||
map[x, y] = Noise.Generate(x, y, map.Biome.HeightRange.Minimum, map.Biome.HeightRange.Maximum);
|
map[x, y] = Noise.Generate(x, y, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DumpData(Map map)
|
//private void Erode(Map map)
|
||||||
|
//{
|
||||||
|
// float[,] water = new float[map.Width, map.Height];
|
||||||
|
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
private void DumpData(Map map, string filename)
|
||||||
{
|
{
|
||||||
XmlSerializer serializer = new XmlSerializer(typeof(Map));
|
XmlSerializer serializer = new XmlSerializer(typeof(Map));
|
||||||
|
|
||||||
using (StreamWriter writer = new StreamWriter(Path.Combine(Logger.LogsDirectory, "mapdump.map")))
|
using (StreamWriter writer = new StreamWriter(Path.Combine(Logger.LogsDirectory, filename)))
|
||||||
{
|
{
|
||||||
serializer.Serialize(writer, map);
|
serializer.Serialize(writer, map);
|
||||||
writer.Close();
|
writer.Close();
|
||||||
|
@ -1,44 +1,44 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
using TransportGame.Utils;
|
using TransportGame.Utils;
|
||||||
|
|
||||||
namespace TransportGame.Model
|
namespace TransportGame.Model
|
||||||
{
|
{
|
||||||
[XmlRoot("biome")]
|
[XmlRoot("biome")]
|
||||||
public class Biome
|
public class Biome
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the name of the biome
|
/// Gets or sets the name of the biome
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[XmlElement("name")]
|
[XmlElement("name")]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the height range of the biome.
|
/// Gets or sets the maximum height of the biome.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 1 unit = 100 meters.
|
/// 1 unit = 100 meters.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[XmlElement("heightRange")]
|
[XmlElement("height")]
|
||||||
public Range HeightRange { get; set; }
|
public float Height { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the moisture range.
|
/// Gets or sets the moisture range.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Moisture is the amount of water on a map.
|
/// Moisture is the amount of water on a map.
|
||||||
/// Value is a probability, should be between 0 and 1.
|
/// Value is a probability, should be between 0 and 1.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[XmlElement("moisture")]
|
[XmlElement("moisture")]
|
||||||
public Range Moisture { get; set; }
|
public Range Moisture { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the vegetation density of the biome
|
/// Gets or sets the vegetation density of the biome
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[XmlElement("vegetationDensity")]
|
[XmlElement("vegetationDensity")]
|
||||||
public Range VegetationDensity { get; set; }
|
public Range VegetationDensity { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ namespace TransportGame.Model
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool IsWater(int x, int y)
|
public bool IsWater(int x, int y)
|
||||||
{
|
{
|
||||||
return grid[x, y] <= WaterLevel;
|
return grid[x, y] * Biome.Height <= WaterLevel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,87 +1,87 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using TransportGame.Utils;
|
using TransportGame.Utils;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using TransportGame.Generator;
|
using TransportGame.Generator;
|
||||||
using TransportGame.Model;
|
using TransportGame.Model;
|
||||||
using TransportGame.Business;
|
using TransportGame.Business;
|
||||||
|
|
||||||
public class TerrainGeneratorScript : MonoBehaviour
|
public class TerrainGeneratorScript : MonoBehaviour
|
||||||
{
|
{
|
||||||
private Map map = null;
|
private Map map = null;
|
||||||
|
|
||||||
public int TerrainWidth = 256;
|
public int TerrainWidth = 256;
|
||||||
public int TerrainHeight = 256;
|
public int TerrainHeight = 256;
|
||||||
public GameObject WaterObject;
|
public GameObject WaterObject;
|
||||||
|
|
||||||
// Use this for initialization
|
// Use this for initialization
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
StartCoroutine(GenerateMap());
|
StartCoroutine(GenerateMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateMapThread()
|
private void GenerateMapThread()
|
||||||
{
|
{
|
||||||
TerrainGenerator generator = new TerrainGenerator();
|
TerrainGenerator generator = new TerrainGenerator();
|
||||||
map = generator.Generate(TerrainWidth, TerrainHeight);
|
map = generator.Generate(TerrainWidth, TerrainHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mesh GenerateWater()
|
private Mesh GenerateWater()
|
||||||
{
|
{
|
||||||
Mesh water = new Mesh();
|
Mesh water = new Mesh();
|
||||||
water.name = "water";
|
water.name = "water";
|
||||||
water.vertices = new[] {
|
water.vertices = new[] {
|
||||||
new Vector3(0, map.WaterLevel, 0),
|
new Vector3(0, map.WaterLevel, 0),
|
||||||
new Vector3(0, map.WaterLevel, map.Height),
|
new Vector3(0, map.WaterLevel, map.Height),
|
||||||
new Vector3(map.Width, map.WaterLevel, 0),
|
new Vector3(map.Width, map.WaterLevel, 0),
|
||||||
new Vector3(map.Width, map.WaterLevel, map.Height)
|
new Vector3(map.Width, map.WaterLevel, map.Height)
|
||||||
};
|
};
|
||||||
water.triangles = new[] { 0, 1, 2, 2, 1, 3 };
|
water.triangles = new[] { 0, 1, 2, 2, 1, 3 };
|
||||||
water.uv = new[] {
|
water.uv = new[] {
|
||||||
new Vector2(0, 0),
|
new Vector2(0, 0),
|
||||||
new Vector2(0, 1),
|
new Vector2(0, 1),
|
||||||
new Vector2(1, 0),
|
new Vector2(1, 0),
|
||||||
new Vector2(1, 1)
|
new Vector2(1, 1)
|
||||||
};
|
};
|
||||||
water.RecalculateNormals();
|
water.RecalculateNormals();
|
||||||
|
|
||||||
return water;
|
return water;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerator GenerateMap()
|
private IEnumerator GenerateMap()
|
||||||
{
|
{
|
||||||
// Wait for the map generation thread
|
// Wait for the map generation thread
|
||||||
foreach (var i in Task.RunAsync(GenerateMapThread))
|
foreach (var i in Task.RunAsync(GenerateMapThread))
|
||||||
yield return i;
|
yield return i;
|
||||||
|
|
||||||
// Generate terrain data
|
// Generate terrain data
|
||||||
TerrainData terrainData = new TerrainData();
|
TerrainData terrainData = new TerrainData();
|
||||||
terrainData.heightmapResolution = Mathf.Max(map.Height, map.Width);
|
terrainData.heightmapResolution = Mathf.Max(map.Height, map.Width) + 1;
|
||||||
terrainData.size = new Vector3(map.Width, map.Biome.HeightRange.Maximum, map.Height);
|
terrainData.size = new Vector3(map.Width, map.Biome.Height, map.Height);
|
||||||
terrainData.SetDetailResolution(1024, 8);
|
terrainData.SetDetailResolution(1024, 8);
|
||||||
terrainData.SetHeights(0, 0, map.Heights);
|
terrainData.SetHeights(0, 0, map.Heights);
|
||||||
terrainData.name = "Generated Terrain Data";
|
terrainData.name = "Generated Terrain Data";
|
||||||
yield return null;
|
yield return null;
|
||||||
|
|
||||||
// Create terrain object
|
// Create terrain object
|
||||||
GameObject terrain = Terrain.CreateTerrainGameObject(terrainData);
|
GameObject terrain = Terrain.CreateTerrainGameObject(terrainData);
|
||||||
terrain.name = "Generated Terrain";
|
terrain.name = "Generated Terrain";
|
||||||
yield return null;
|
yield return null;
|
||||||
|
|
||||||
Terrain terrainComp = terrain.GetComponent<Terrain>();
|
Terrain terrainComp = terrain.GetComponent<Terrain>();
|
||||||
terrainComp.heightmapPixelError = 1;
|
terrainComp.heightmapPixelError = 1;
|
||||||
yield return null;
|
yield return null;
|
||||||
|
|
||||||
// Set water
|
// Set water
|
||||||
if (WaterObject != null)
|
if (WaterObject != null)
|
||||||
{
|
{
|
||||||
MeshFilter waterMesh = WaterObject.GetComponent<MeshFilter>();
|
MeshFilter waterMesh = WaterObject.GetComponent<MeshFilter>();
|
||||||
waterMesh.mesh = GenerateWater();
|
waterMesh.mesh = GenerateWater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update is called once per frame
|
// Update is called once per frame
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ Global
|
|||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(MonoDevelopProperties) = preSolution
|
GlobalSection(MonoDevelopProperties) = preSolution
|
||||||
StartupItem = Assembly-CSharp.csproj
|
StartupItem = Assembly-CSharp.csproj
|
||||||
Policies = $0
|
Policies = $0
|
||||||
$0.TextStylePolicy = $1
|
$0.TextStylePolicy = $1
|
||||||
|
@ -29,7 +29,7 @@ Global
|
|||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(MonoDevelopProperties) = preSolution
|
GlobalSection(MonoDevelopProperties) = preSolution
|
||||||
StartupItem = Assembly-CSharp.csproj
|
StartupItem = Assembly-CSharp.csproj
|
||||||
Policies = $0
|
Policies = $0
|
||||||
$0.TextStylePolicy = $1
|
$0.TextStylePolicy = $1
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Game/Library/ShaderCache/0/04a06c16885597a27e5c44b37fc9d2e0.bin
Normal file
BIN
Game/Library/ShaderCache/0/04a06c16885597a27e5c44b37fc9d2e0.bin
Normal file
Binary file not shown.
BIN
Game/Library/ShaderCache/8/892a8fde3afd6f35fc5c197d07631abf.bin
Normal file
BIN
Game/Library/ShaderCache/8/892a8fde3afd6f35fc5c197d07631abf.bin
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,9 +1,3 @@
|
|||||||
Base path: E:/SDKs/Unity/Editor/Data
|
Base path: E:/SDKs/Unity/Editor/Data
|
||||||
Pipe name: \\.\pipe\UnityShaderCompiler-32bit-1-3856
|
Pipe name: \\.\pipe\UnityShaderCompiler-32bit-1-4308
|
||||||
Cmd: getPlatforms
|
Cmd: getPlatforms
|
||||||
Unhandled exception: Readfile from pipe failed. GLE=The pipe has been ended.
|
|
||||||
|
|
||||||
|
|
||||||
Quitting shader compiler process
|
|
||||||
|
|
||||||
Crashed!
|
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
Base path: E:/SDKs/Unity/Editor/Data
|
Base path: E:/SDKs/Unity/Editor/Data
|
||||||
Pipe name: \\.\pipe\UnityShaderCompiler-64bit-1-3856
|
Pipe name: \\.\pipe\UnityShaderCompiler-64bit-1-4308
|
||||||
Cmd: getPlatforms
|
Cmd: getPlatforms
|
||||||
|
Cmd: compileSnippet
|
||||||
|
api=4 type=0 insize=14871 outsize=3492 kw=DIRECTIONAL SHADOWS_OFF LIGHTMAP_OFF DIRLIGHTMAP_OFF DYNAMICLIGHTMAP_OFF ok=1
|
||||||
|
Cmd: compileSnippet
|
||||||
|
api=4 type=1 insize=14871 outsize=10090 kw=DIRECTIONAL SHADOWS_OFF LIGHTMAP_OFF DIRLIGHTMAP_OFF DYNAMICLIGHTMAP_OFF ok=1
|
||||||
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,13 +1,13 @@
|
|||||||
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\Assembly-CSharp.dll
|
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\Assembly-CSharp.dll
|
||||||
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\Assembly-CSharp.pdb
|
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\Assembly-CSharp.pdb
|
||||||
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\UnityEditor.dll
|
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\UnityEditor.dll
|
||||||
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\UnityEngine.dll
|
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\UnityEngine.dll
|
||||||
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\UnityEngine.UI.dll
|
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\UnityEngine.UI.dll
|
||||||
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\UnityEditor.xml
|
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\UnityEditor.xml
|
||||||
E:\Facultate\$ Licenta\Game\obj\Debug\UnityVS.Game.CSharp.csprojResolveAssemblyReference.cache
|
E:\Facultate\$ Licenta\Game\obj\Debug\UnityVS.Game.CSharp.csprojResolveAssemblyReference.cache
|
||||||
E:\Facultate\$ Licenta\Game\obj\Debug\Assembly-CSharp.dll
|
E:\Facultate\$ Licenta\Game\obj\Debug\Assembly-CSharp.dll
|
||||||
E:\Facultate\$ Licenta\Game\obj\Debug\Assembly-CSharp.pdb
|
E:\Facultate\$ Licenta\Game\obj\Debug\Assembly-CSharp.pdb
|
||||||
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\UnityEngine.xml
|
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\UnityEngine.xml
|
||||||
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\UnityEngine.UI.xml
|
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\UnityEngine.UI.xml
|
||||||
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\Assembly-CSharp-firstpass.pdb
|
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\Assembly-CSharp-firstpass.pdb
|
||||||
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\Assembly-UnityScript-firstpass.dll
|
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\Assembly-UnityScript-firstpass.dll
|
||||||
|
25
Tools/MapViewer/MapViewer/Business/BitmapExtensions.cs
Normal file
25
Tools/MapViewer/MapViewer/Business/BitmapExtensions.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using TransportGame.MapViewer.Model;
|
||||||
|
|
||||||
|
namespace TransportGame.MapViewer.Business
|
||||||
|
{
|
||||||
|
public static class BitmapExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a wpf bitmap source from a bitmap.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="this">The bitmap</param>
|
||||||
|
/// <returns>The bitmap source</returns>
|
||||||
|
public static BitmapSource ToBitmapSource(this Bitmap24 @this)
|
||||||
|
{
|
||||||
|
return BitmapSource.Create(@this.Width, @this.Height,
|
||||||
|
96, 96, PixelFormats.Rgb24, null, @this.Raw, @this.Width * 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using TransportGame.MapViewer.Model;
|
||||||
using TransportGame.Model;
|
using TransportGame.Model;
|
||||||
|
|
||||||
namespace TransportGame.MapViewer
|
namespace TransportGame.MapViewer
|
||||||
@ -23,8 +18,8 @@ namespace TransportGame.MapViewer
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the scale
|
/// Gets or sets the scale
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private int _scale;
|
private float _scale;
|
||||||
public int Scale
|
public float Scale
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -45,7 +40,7 @@ namespace TransportGame.MapViewer
|
|||||||
|
|
||||||
public MapRenderer()
|
public MapRenderer()
|
||||||
{
|
{
|
||||||
Scale = 4;
|
Scale = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
///<summary>
|
||||||
@ -54,72 +49,46 @@ namespace TransportGame.MapViewer
|
|||||||
///<param name="file"></param>
|
///<param name="file"></param>
|
||||||
///<param name="map"></param>
|
///<param name="map"></param>
|
||||||
///<param name="layers"></param>
|
///<param name="layers"></param>
|
||||||
public Color[,] Render(Map map, Layers layers = Layers.All)
|
public Bitmap24 Render(Map map, Layers layers = Layers.All)
|
||||||
{
|
{
|
||||||
lock (this)
|
lock (this)
|
||||||
{
|
{
|
||||||
// Create texture on which to draw
|
// Create texture on which to draw
|
||||||
Color[,] pixels = new Color[map.Width * Scale, map.Height * Scale];
|
Bitmap24 bitmap = new Bitmap24(Convert.ToInt32(map.Width * Scale), Convert.ToInt32(map.Height * Scale));
|
||||||
|
|
||||||
// First layer - cells
|
// First layer - cells
|
||||||
DrawCells(pixels, map, (layers & Layers.Elevation) > 0);
|
DrawCells(bitmap, map, (layers & Layers.Elevation) > 0);
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
return pixels;
|
return bitmap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawCells(Color[,] pixels, Map map, bool elevation)
|
private void DrawCells(Bitmap24 bitmap, Map map, bool elevation)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < pixels.GetLength(0); x++)
|
for (int x = 0; x < bitmap.Width; x++)
|
||||||
for (int y = 0; y < pixels.GetLength(1); y++)
|
for (int y = 0; y < bitmap.Height; y++)
|
||||||
{
|
{
|
||||||
int mapX = x / Scale;
|
int mapX = Convert.ToInt32(x / Scale);
|
||||||
int mapY = y / Scale;
|
int mapY = Convert.ToInt32(y / Scale);
|
||||||
|
|
||||||
// Draw water
|
// Draw water
|
||||||
if (map.IsWater(mapX, mapY))
|
if (map.IsWater(mapX, mapY))
|
||||||
pixels[x, y] = WaterColor;
|
bitmap[x, y] = WaterColor;
|
||||||
|
|
||||||
// Draw elevation
|
// Draw elevation
|
||||||
else if (elevation)
|
else if (elevation)
|
||||||
{
|
{
|
||||||
float alpha = (map[mapX, mapY] - map.Biome.HeightRange.Minimum) / (map.Biome.HeightRange.Maximum - map.Biome.HeightRange.Minimum);
|
float alpha = map[mapX, mapY]; // map height range is [0,1]
|
||||||
pixels[x, y] = Color.Multiply(ElevationTerrainColor, alpha);
|
bitmap[x, y] = Color.Multiply(ElevationTerrainColor, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw terrain
|
// Draw terrain
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pixels[x, y] = TerrainColor;
|
bitmap[x, y] = TerrainColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<BitmapSource> RenderToImageSource(Map map, Layers layers = Layers.All)
|
|
||||||
{
|
|
||||||
var colors = await Task.Run(() => Render(map, layers));
|
|
||||||
colors[0, 0] = Colors.Red;
|
|
||||||
colors[colors.GetLength(0) - 1, 0] = Colors.Red;
|
|
||||||
|
|
||||||
// Convert to raw pixels
|
|
||||||
byte[] raw = new byte[colors.GetLength(0) * colors.GetLength(1) * 3];
|
|
||||||
|
|
||||||
for (int x = 0; x < colors.GetLength(0); x++)
|
|
||||||
for (int y = 0; y < colors.GetLength(1); y++)
|
|
||||||
{
|
|
||||||
int pixelIndex = x + y * colors.GetLength(0);
|
|
||||||
|
|
||||||
raw[3 * pixelIndex] = colors[x, y].R;
|
|
||||||
raw[3 * pixelIndex + 1] = colors[x, y].G;
|
|
||||||
raw[3 * pixelIndex + 2] = colors[x, y].B;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create bitmap source
|
|
||||||
BitmapSource bmp = BitmapSource.Create(colors.GetLength(0), colors.GetLength(1),
|
|
||||||
96, 96, PixelFormats.Rgb24, null, raw, colors.GetLength(0) * 3);
|
|
||||||
|
|
||||||
return bmp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
<Button Name="buttonSave" ToolTip="Saves as image" Click="buttonSave_Click">
|
<Button Name="buttonSave" ToolTip="Saves as image" Click="buttonSave_Click">
|
||||||
<Image Source="pack://application:,,,/Resources/picture_save.png" />
|
<Image Source="pack://application:,,,/Resources/picture_save.png" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|
||||||
<Button Name="buttonZoomIn" ToolTip="Zoom in" Click="buttonZoomIn_Click">
|
<Button Name="buttonZoomIn" ToolTip="Zoom in" Click="buttonZoomIn_Click">
|
||||||
@ -31,7 +32,7 @@
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<TextBlock VerticalAlignment="Center">
|
<TextBlock VerticalAlignment="Center">
|
||||||
<Run Text="{Binding ZoomLevel}" /><Run>00%</Run>
|
<Run Text="{Binding ZoomLevel}" /><Run>%</Run>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
</ToolBar>
|
</ToolBar>
|
||||||
|
|
||||||
@ -114,8 +115,8 @@
|
|||||||
<TextBlock Grid.Row="0" Grid.Column="0" >Name:</TextBlock>
|
<TextBlock Grid.Row="0" Grid.Column="0" >Name:</TextBlock>
|
||||||
<TextBox Grid.Row="0" Grid.Column="1" IsReadOnly="True" Text="{Binding Map.Biome.Name,Mode=OneWay}" />
|
<TextBox Grid.Row="0" Grid.Column="1" IsReadOnly="True" Text="{Binding Map.Biome.Name,Mode=OneWay}" />
|
||||||
|
|
||||||
<TextBlock Grid.Row="1" Grid.Column="0" >Height range:</TextBlock>
|
<TextBlock Grid.Row="1" Grid.Column="0" >Height:</TextBlock>
|
||||||
<TextBox Grid.Row="1" Grid.Column="1" IsReadOnly="True" Text="{Binding Map.Biome.HeightRange,Mode=OneWay}" />
|
<TextBox Grid.Row="1" Grid.Column="1" IsReadOnly="True" Text="{Binding Map.Biome.Height,Mode=OneWay}" />
|
||||||
|
|
||||||
<TextBlock Grid.Row="2" Grid.Column="0" >Moisture:</TextBlock>
|
<TextBlock Grid.Row="2" Grid.Column="0" >Moisture:</TextBlock>
|
||||||
<TextBox Grid.Row="2" Grid.Column="1" IsReadOnly="True" Text="{Binding Map.Biome.Moisture,Mode=OneWay}" />
|
<TextBox Grid.Row="2" Grid.Column="1" IsReadOnly="True" Text="{Binding Map.Biome.Moisture,Mode=OneWay}" />
|
||||||
|
@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
|
using TransportGame.MapViewer.Business;
|
||||||
using TransportGame.MapViewer.Storage;
|
using TransportGame.MapViewer.Storage;
|
||||||
using TransportGame.Model;
|
using TransportGame.Model;
|
||||||
|
|
||||||
@ -152,15 +153,15 @@ namespace TransportGame.MapViewer
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the zoom level
|
/// Gets or sets the zoom level
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int ZoomLevel
|
public float ZoomLevel
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Renderer.Scale;
|
return Renderer.Scale * 100f;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Renderer.Scale = value;
|
Renderer.Scale = value / 100f;
|
||||||
if (PropertyChanged != null)
|
if (PropertyChanged != null)
|
||||||
PropertyChanged(this, new PropertyChangedEventArgs("ZoomLevel"));
|
PropertyChanged(this, new PropertyChangedEventArgs("ZoomLevel"));
|
||||||
}
|
}
|
||||||
@ -215,7 +216,8 @@ namespace TransportGame.MapViewer
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RenderedMap = await Renderer.RenderToImageSource(Map, _layers);
|
var renderResult = await Task.Run(() => Renderer.Render(Map, _layers));
|
||||||
|
RenderedMap = renderResult.ToBitmapSource();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -260,10 +262,10 @@ namespace TransportGame.MapViewer
|
|||||||
private async void buttonZoomIn_Click(object sender, RoutedEventArgs e)
|
private async void buttonZoomIn_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
// Zoom
|
// Zoom
|
||||||
ZoomLevel++;
|
ZoomLevel *= 2;
|
||||||
|
|
||||||
// Update IsEnabled
|
// Update IsEnabled
|
||||||
if (ZoomLevel >= 10)
|
if (ZoomLevel >= 400)
|
||||||
buttonZoomIn.IsEnabled = false;
|
buttonZoomIn.IsEnabled = false;
|
||||||
buttonZoomOut.IsEnabled = true;
|
buttonZoomOut.IsEnabled = true;
|
||||||
|
|
||||||
@ -275,10 +277,10 @@ namespace TransportGame.MapViewer
|
|||||||
private async void buttonZoomOut_Click(object sender, RoutedEventArgs e)
|
private async void buttonZoomOut_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
// Zoom
|
// Zoom
|
||||||
ZoomLevel--;
|
ZoomLevel /=2;
|
||||||
|
|
||||||
// Update IsEnabled
|
// Update IsEnabled
|
||||||
if (ZoomLevel <= 1)
|
if (ZoomLevel <= 10)
|
||||||
buttonZoomOut.IsEnabled = false;
|
buttonZoomOut.IsEnabled = false;
|
||||||
buttonZoomIn.IsEnabled = true;
|
buttonZoomIn.IsEnabled = true;
|
||||||
|
|
||||||
@ -332,8 +334,7 @@ namespace TransportGame.MapViewer
|
|||||||
filename = dialog.FileName;
|
filename = dialog.FileName;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,8 @@
|
|||||||
<Compile Include="..\..\..\Game\Assets\Scripts\Model\Map.cs">
|
<Compile Include="..\..\..\Game\Assets\Scripts\Model\Map.cs">
|
||||||
<Link>Model\Map.cs</Link>
|
<Link>Model\Map.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Business\BitmapExtensions.cs" />
|
||||||
|
<Compile Include="Model\Bitmap24.cs" />
|
||||||
<Compile Include="Storage\MapStorage.cs" />
|
<Compile Include="Storage\MapStorage.cs" />
|
||||||
<Page Include="MainWindow.xaml">
|
<Page Include="MainWindow.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
72
Tools/MapViewer/MapViewer/Model/Bitmap24.cs
Normal file
72
Tools/MapViewer/MapViewer/Model/Bitmap24.cs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace TransportGame.MapViewer.Model
|
||||||
|
{
|
||||||
|
public class Bitmap24
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the width of the bitmap
|
||||||
|
/// </summary>
|
||||||
|
public int Width { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the height of the bitmap
|
||||||
|
/// </summary>
|
||||||
|
public int Height { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the raw bytes of the bitmap
|
||||||
|
/// </summary>
|
||||||
|
public byte[] Raw { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a bitmap
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="w"></param>
|
||||||
|
/// <param name="h"></param>
|
||||||
|
public Bitmap24(int w, int h)
|
||||||
|
{
|
||||||
|
Width = w;
|
||||||
|
Height = h;
|
||||||
|
|
||||||
|
Raw = new byte[w * h * 3];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a pixel
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">x coordinate of pixel</param>
|
||||||
|
/// <param name="y">y coordinate of pixel</param>
|
||||||
|
public Color this[int x, int y]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int index = RawIndexOf(x, y);
|
||||||
|
return Color.FromRgb(Raw[index], Raw[index + 1], Raw[index + 2]);
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
int index = RawIndexOf(x, y);
|
||||||
|
Raw[index] = value.R;
|
||||||
|
Raw[index + 1] = value.G;
|
||||||
|
Raw[index + 2] = value.B;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int RawIndexOf(int x, int y)
|
||||||
|
{
|
||||||
|
if (x < 0 || x >= Width)
|
||||||
|
throw new ArgumentOutOfRangeException("x is out of range");
|
||||||
|
|
||||||
|
if (y < 0 || y >= Height)
|
||||||
|
throw new ArgumentOutOfRangeException("x is out of range");
|
||||||
|
|
||||||
|
return 3 * (x + y * Width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user