Fixed unity terrain generation bug.
This commit is contained in:
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);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user