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
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
# Logs
|
||||
Game/Logs/
|
||||
Game/[Oo]bj/
|
||||
Game/[Tt]emp/
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<biome>
|
||||
<name>Grassland</name>
|
||||
<heightRange min="0" max="10" />
|
||||
<moisture min=".1" max=".5"/>
|
||||
<vegetationDensity min=".2" max=".5" />
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<biome>
|
||||
<name>Grassland</name>
|
||||
<height>100</height>
|
||||
<moisture min=".1" max=".5"/>
|
||||
<vegetationDensity min=".2" max=".5" />
|
||||
</biome>
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<biome>
|
||||
<name>Mountain</name>
|
||||
<heightRange min="0" max="500" />
|
||||
<moisture min=".1" max=".3"/>
|
||||
<vegetationDensity min=".5" max=".9" />
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<biome>
|
||||
<name>Mountain</name>
|
||||
<height>500</height>
|
||||
<moisture min=".1" max=".3"/>
|
||||
<vegetationDensity min=".5" max=".9" />
|
||||
</biome>
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<terrgenConfig>
|
||||
<noiseOctaves>8</noiseOctaves>
|
||||
<noiseNonLinearPower>2</noiseNonLinearPower>
|
||||
<waterNonLinearPower>1.3</waterNonLinearPower>
|
||||
<elevationScale>0.01</elevationScale>
|
||||
<noiseOctaves>9</noiseOctaves>
|
||||
<noiseNonLinearPower>2.4</noiseNonLinearPower>
|
||||
<waterNonLinearPower>1.9</waterNonLinearPower>
|
||||
<elevationScale>0.0005</elevationScale>
|
||||
</terrgenConfig>
|
Binary file not shown.
@ -45,10 +45,14 @@ namespace TransportGame.Generator
|
||||
|
||||
// Generate water level
|
||||
float waterAmount = random.NextSingle(map.Biome.Moisture.Minimum, map.Biome.Moisture.Maximum);
|
||||
map.WaterLevel = Mathf.Pow(waterAmount, ConfigurationManager.TerrGenConfig.WaterNonLinearPower)
|
||||
* (map.Biome.HeightRange.Maximum - map.Biome.HeightRange.Minimum) + map.Biome.HeightRange.Minimum;
|
||||
map.WaterLevel = Mathf.Pow(waterAmount, ConfigurationManager.TerrGenConfig.WaterNonLinearPower) * map.Biome.Height;
|
||||
|
||||
DumpData(map, "1generated.map");
|
||||
|
||||
// Simulate water erosion
|
||||
//Erode(map);
|
||||
//DumpData(map, "2eroded.map");
|
||||
|
||||
DumpData(map);
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -64,14 +68,21 @@ namespace TransportGame.Generator
|
||||
{
|
||||
for (int x = 0; x < map.Width; ++x)
|
||||
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));
|
||||
|
||||
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);
|
||||
writer.Close();
|
||||
|
@ -1,44 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using TransportGame.Utils;
|
||||
|
||||
namespace TransportGame.Model
|
||||
{
|
||||
[XmlRoot("biome")]
|
||||
public class Biome
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the biome
|
||||
/// </summary>
|
||||
[XmlElement("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the height range of the biome.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 1 unit = 100 meters.
|
||||
/// </remarks>
|
||||
[XmlElement("heightRange")]
|
||||
public Range HeightRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the moisture range.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Moisture is the amount of water on a map.
|
||||
/// Value is a probability, should be between 0 and 1.
|
||||
/// </remarks>
|
||||
[XmlElement("moisture")]
|
||||
public Range Moisture { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the vegetation density of the biome
|
||||
/// </summary>
|
||||
[XmlElement("vegetationDensity")]
|
||||
public Range VegetationDensity { get; set; }
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using TransportGame.Utils;
|
||||
|
||||
namespace TransportGame.Model
|
||||
{
|
||||
[XmlRoot("biome")]
|
||||
public class Biome
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the biome
|
||||
/// </summary>
|
||||
[XmlElement("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum height of the biome.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 1 unit = 100 meters.
|
||||
/// </remarks>
|
||||
[XmlElement("height")]
|
||||
public float Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the moisture range.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Moisture is the amount of water on a map.
|
||||
/// Value is a probability, should be between 0 and 1.
|
||||
/// </remarks>
|
||||
[XmlElement("moisture")]
|
||||
public Range Moisture { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the vegetation density of the biome
|
||||
/// </summary>
|
||||
[XmlElement("vegetationDensity")]
|
||||
public Range VegetationDensity { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ namespace TransportGame.Model
|
||||
/// <returns></returns>
|
||||
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 System.Collections;
|
||||
using TransportGame.Utils;
|
||||
using System.Threading;
|
||||
using TransportGame.Generator;
|
||||
using TransportGame.Model;
|
||||
using TransportGame.Business;
|
||||
|
||||
public class TerrainGeneratorScript : MonoBehaviour
|
||||
{
|
||||
private Map map = null;
|
||||
|
||||
public int TerrainWidth = 256;
|
||||
public int TerrainHeight = 256;
|
||||
public GameObject WaterObject;
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
StartCoroutine(GenerateMap());
|
||||
}
|
||||
|
||||
private void GenerateMapThread()
|
||||
{
|
||||
TerrainGenerator generator = new TerrainGenerator();
|
||||
map = generator.Generate(TerrainWidth, TerrainHeight);
|
||||
}
|
||||
|
||||
private Mesh GenerateWater()
|
||||
{
|
||||
Mesh water = new Mesh();
|
||||
water.name = "water";
|
||||
water.vertices = new[] {
|
||||
new Vector3(0, map.WaterLevel, 0),
|
||||
new Vector3(0, map.WaterLevel, map.Height),
|
||||
new Vector3(map.Width, map.WaterLevel, 0),
|
||||
new Vector3(map.Width, map.WaterLevel, map.Height)
|
||||
};
|
||||
water.triangles = new[] { 0, 1, 2, 2, 1, 3 };
|
||||
water.uv = new[] {
|
||||
new Vector2(0, 0),
|
||||
new Vector2(0, 1),
|
||||
new Vector2(1, 0),
|
||||
new Vector2(1, 1)
|
||||
};
|
||||
water.RecalculateNormals();
|
||||
|
||||
return water;
|
||||
}
|
||||
|
||||
private IEnumerator GenerateMap()
|
||||
{
|
||||
// Wait for the map generation thread
|
||||
foreach (var i in Task.RunAsync(GenerateMapThread))
|
||||
yield return i;
|
||||
|
||||
// Generate terrain data
|
||||
TerrainData terrainData = new TerrainData();
|
||||
terrainData.heightmapResolution = Mathf.Max(map.Height, map.Width);
|
||||
terrainData.size = new Vector3(map.Width, map.Biome.HeightRange.Maximum, map.Height);
|
||||
terrainData.SetDetailResolution(1024, 8);
|
||||
terrainData.SetHeights(0, 0, map.Heights);
|
||||
terrainData.name = "Generated Terrain Data";
|
||||
yield return null;
|
||||
|
||||
// Create terrain object
|
||||
GameObject terrain = Terrain.CreateTerrainGameObject(terrainData);
|
||||
terrain.name = "Generated Terrain";
|
||||
yield return null;
|
||||
|
||||
Terrain terrainComp = terrain.GetComponent<Terrain>();
|
||||
terrainComp.heightmapPixelError = 1;
|
||||
yield return null;
|
||||
|
||||
// Set water
|
||||
if (WaterObject != null)
|
||||
{
|
||||
MeshFilter waterMesh = WaterObject.GetComponent<MeshFilter>();
|
||||
waterMesh.mesh = GenerateWater();
|
||||
}
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
}
|
||||
}
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using TransportGame.Utils;
|
||||
using System.Threading;
|
||||
using TransportGame.Generator;
|
||||
using TransportGame.Model;
|
||||
using TransportGame.Business;
|
||||
|
||||
public class TerrainGeneratorScript : MonoBehaviour
|
||||
{
|
||||
private Map map = null;
|
||||
|
||||
public int TerrainWidth = 256;
|
||||
public int TerrainHeight = 256;
|
||||
public GameObject WaterObject;
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
StartCoroutine(GenerateMap());
|
||||
}
|
||||
|
||||
private void GenerateMapThread()
|
||||
{
|
||||
TerrainGenerator generator = new TerrainGenerator();
|
||||
map = generator.Generate(TerrainWidth, TerrainHeight);
|
||||
}
|
||||
|
||||
private Mesh GenerateWater()
|
||||
{
|
||||
Mesh water = new Mesh();
|
||||
water.name = "water";
|
||||
water.vertices = new[] {
|
||||
new Vector3(0, map.WaterLevel, 0),
|
||||
new Vector3(0, map.WaterLevel, map.Height),
|
||||
new Vector3(map.Width, map.WaterLevel, 0),
|
||||
new Vector3(map.Width, map.WaterLevel, map.Height)
|
||||
};
|
||||
water.triangles = new[] { 0, 1, 2, 2, 1, 3 };
|
||||
water.uv = new[] {
|
||||
new Vector2(0, 0),
|
||||
new Vector2(0, 1),
|
||||
new Vector2(1, 0),
|
||||
new Vector2(1, 1)
|
||||
};
|
||||
water.RecalculateNormals();
|
||||
|
||||
return water;
|
||||
}
|
||||
|
||||
private IEnumerator GenerateMap()
|
||||
{
|
||||
// Wait for the map generation thread
|
||||
foreach (var i in Task.RunAsync(GenerateMapThread))
|
||||
yield return i;
|
||||
|
||||
// Generate terrain data
|
||||
TerrainData terrainData = new TerrainData();
|
||||
terrainData.heightmapResolution = Mathf.Max(map.Height, map.Width) + 1;
|
||||
terrainData.size = new Vector3(map.Width, map.Biome.Height, map.Height);
|
||||
terrainData.SetDetailResolution(1024, 8);
|
||||
terrainData.SetHeights(0, 0, map.Heights);
|
||||
terrainData.name = "Generated Terrain Data";
|
||||
yield return null;
|
||||
|
||||
// Create terrain object
|
||||
GameObject terrain = Terrain.CreateTerrainGameObject(terrainData);
|
||||
terrain.name = "Generated Terrain";
|
||||
yield return null;
|
||||
|
||||
Terrain terrainComp = terrain.GetComponent<Terrain>();
|
||||
terrainComp.heightmapPixelError = 1;
|
||||
yield return null;
|
||||
|
||||
// Set water
|
||||
if (WaterObject != null)
|
||||
{
|
||||
MeshFilter waterMesh = WaterObject.GetComponent<MeshFilter>();
|
||||
waterMesh.mesh = GenerateWater();
|
||||
}
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
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
|
||||
Pipe name: \\.\pipe\UnityShaderCompiler-32bit-1-3856
|
||||
Cmd: getPlatforms
|
||||
Unhandled exception: Readfile from pipe failed. GLE=The pipe has been ended.
|
||||
|
||||
|
||||
Quitting shader compiler process
|
||||
|
||||
Crashed!
|
||||
Base path: E:/SDKs/Unity/Editor/Data
|
||||
Pipe name: \\.\pipe\UnityShaderCompiler-32bit-1-4308
|
||||
Cmd: getPlatforms
|
||||
|
@ -1,3 +1,7 @@
|
||||
Base path: E:/SDKs/Unity/Editor/Data
|
||||
Pipe name: \\.\pipe\UnityShaderCompiler-64bit-1-3856
|
||||
Pipe name: \\.\pipe\UnityShaderCompiler-64bit-1-4308
|
||||
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.pdb
|
||||
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.UI.dll
|
||||
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\Assembly-CSharp.dll
|
||||
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.UI.xml
|
||||
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-CSharp.dll
|
||||
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\UnityEngine.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\obj\Debug\UnityVS.Game.CSharp.csprojResolveAssemblyReference.cache
|
||||
E:\Facultate\$ Licenta\Game\obj\Debug\Assembly-CSharp.dll
|
||||
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.UI.xml
|
||||
E:\Facultate\$ Licenta\Game\Temp\UnityVS_bin\Debug\Assembly-CSharp-firstpass.pdb
|
||||
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.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using TransportGame.MapViewer.Model;
|
||||
using TransportGame.Model;
|
||||
|
||||
namespace TransportGame.MapViewer
|
||||
@ -23,8 +18,8 @@ namespace TransportGame.MapViewer
|
||||
/// <summary>
|
||||
/// Gets or sets the scale
|
||||
/// </summary>
|
||||
private int _scale;
|
||||
public int Scale
|
||||
private float _scale;
|
||||
public float Scale
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -45,7 +40,7 @@ namespace TransportGame.MapViewer
|
||||
|
||||
public MapRenderer()
|
||||
{
|
||||
Scale = 4;
|
||||
Scale = 1;
|
||||
}
|
||||
|
||||
///<summary>
|
||||
@ -54,72 +49,46 @@ namespace TransportGame.MapViewer
|
||||
///<param name="file"></param>
|
||||
///<param name="map"></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)
|
||||
{
|
||||
// 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
|
||||
DrawCells(pixels, map, (layers & Layers.Elevation) > 0);
|
||||
DrawCells(bitmap, map, (layers & Layers.Elevation) > 0);
|
||||
|
||||
// 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 y = 0; y < pixels.GetLength(1); y++)
|
||||
for (int x = 0; x < bitmap.Width; x++)
|
||||
for (int y = 0; y < bitmap.Height; y++)
|
||||
{
|
||||
int mapX = x / Scale;
|
||||
int mapY = y / Scale;
|
||||
int mapX = Convert.ToInt32(x / Scale);
|
||||
int mapY = Convert.ToInt32(y / Scale);
|
||||
|
||||
// Draw water
|
||||
if (map.IsWater(mapX, mapY))
|
||||
pixels[x, y] = WaterColor;
|
||||
bitmap[x, y] = WaterColor;
|
||||
|
||||
// Draw elevation
|
||||
else if (elevation)
|
||||
{
|
||||
float alpha = (map[mapX, mapY] - map.Biome.HeightRange.Minimum) / (map.Biome.HeightRange.Maximum - map.Biome.HeightRange.Minimum);
|
||||
pixels[x, y] = Color.Multiply(ElevationTerrainColor, alpha);
|
||||
float alpha = map[mapX, mapY]; // map height range is [0,1]
|
||||
bitmap[x, y] = Color.Multiply(ElevationTerrainColor, alpha);
|
||||
}
|
||||
|
||||
// Draw terrain
|
||||
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">
|
||||
<Image Source="pack://application:,,,/Resources/picture_save.png" />
|
||||
</Button>
|
||||
|
||||
<Separator />
|
||||
|
||||
<Button Name="buttonZoomIn" ToolTip="Zoom in" Click="buttonZoomIn_Click">
|
||||
@ -31,7 +32,7 @@
|
||||
</Button>
|
||||
|
||||
<TextBlock VerticalAlignment="Center">
|
||||
<Run Text="{Binding ZoomLevel}" /><Run>00%</Run>
|
||||
<Run Text="{Binding ZoomLevel}" /><Run>%</Run>
|
||||
</TextBlock>
|
||||
</ToolBar>
|
||||
|
||||
@ -114,8 +115,8 @@
|
||||
<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}" />
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" >Height range:</TextBlock>
|
||||
<TextBox Grid.Row="1" Grid.Column="1" IsReadOnly="True" Text="{Binding Map.Biome.HeightRange,Mode=OneWay}" />
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" >Height:</TextBlock>
|
||||
<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>
|
||||
<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.Media.Imaging;
|
||||
using Microsoft.Win32;
|
||||
using TransportGame.MapViewer.Business;
|
||||
using TransportGame.MapViewer.Storage;
|
||||
using TransportGame.Model;
|
||||
|
||||
@ -152,15 +153,15 @@ namespace TransportGame.MapViewer
|
||||
/// <summary>
|
||||
/// Gets or sets the zoom level
|
||||
/// </summary>
|
||||
public int ZoomLevel
|
||||
public float ZoomLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
return Renderer.Scale;
|
||||
return Renderer.Scale * 100f;
|
||||
}
|
||||
set
|
||||
{
|
||||
Renderer.Scale = value;
|
||||
Renderer.Scale = value / 100f;
|
||||
if (PropertyChanged != null)
|
||||
PropertyChanged(this, new PropertyChangedEventArgs("ZoomLevel"));
|
||||
}
|
||||
@ -215,7 +216,8 @@ namespace TransportGame.MapViewer
|
||||
|
||||
try
|
||||
{
|
||||
RenderedMap = await Renderer.RenderToImageSource(Map, _layers);
|
||||
var renderResult = await Task.Run(() => Renderer.Render(Map, _layers));
|
||||
RenderedMap = renderResult.ToBitmapSource();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -260,10 +262,10 @@ namespace TransportGame.MapViewer
|
||||
private async void buttonZoomIn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Zoom
|
||||
ZoomLevel++;
|
||||
ZoomLevel *= 2;
|
||||
|
||||
// Update IsEnabled
|
||||
if (ZoomLevel >= 10)
|
||||
if (ZoomLevel >= 400)
|
||||
buttonZoomIn.IsEnabled = false;
|
||||
buttonZoomOut.IsEnabled = true;
|
||||
|
||||
@ -275,10 +277,10 @@ namespace TransportGame.MapViewer
|
||||
private async void buttonZoomOut_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Zoom
|
||||
ZoomLevel--;
|
||||
ZoomLevel /=2;
|
||||
|
||||
// Update IsEnabled
|
||||
if (ZoomLevel <= 1)
|
||||
if (ZoomLevel <= 10)
|
||||
buttonZoomOut.IsEnabled = false;
|
||||
buttonZoomIn.IsEnabled = true;
|
||||
|
||||
@ -332,8 +334,7 @@ namespace TransportGame.MapViewer
|
||||
filename = dialog.FileName;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,8 @@
|
||||
<Compile Include="..\..\..\Game\Assets\Scripts\Model\Map.cs">
|
||||
<Link>Model\Map.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Business\BitmapExtensions.cs" />
|
||||
<Compile Include="Model\Bitmap24.cs" />
|
||||
<Compile Include="Storage\MapStorage.cs" />
|
||||
<Page Include="MainWindow.xaml">
|
||||
<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