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