PerlinNoise map generator
This commit is contained in:
parent
8c976c4beb
commit
70be7e0151
@ -87,6 +87,7 @@
|
|||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Sources\Crops\CropType.cs" />
|
<Compile Include="Sources\Crops\CropType.cs" />
|
||||||
<Compile Include="Sources\Crops\CropTypesHolder.cs" />
|
<Compile Include="Sources\Crops\CropTypesHolder.cs" />
|
||||||
|
<Compile Include="Sources\Crops\PerlinNoise.cs" />
|
||||||
<Compile Include="Sources\Crops\SoilProperties.cs" />
|
<Compile Include="Sources\Crops\SoilProperties.cs" />
|
||||||
<Compile Include="Sources\ML\Engine.cs" />
|
<Compile Include="Sources\ML\Engine.cs" />
|
||||||
<Compile Include="Sources\Objects\DayNightCycle.cs" />
|
<Compile Include="Sources\Objects\DayNightCycle.cs" />
|
||||||
@ -159,6 +160,9 @@
|
|||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="LibNoise">
|
||||||
|
<Version>0.2.0</Version>
|
||||||
|
</PackageReference>
|
||||||
<PackageReference Include="LightGBM">
|
<PackageReference Include="LightGBM">
|
||||||
<Version>2.3.1</Version>
|
<Version>2.3.1</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
@ -183,6 +187,9 @@
|
|||||||
<PackageReference Include="System.Collections.Immutable">
|
<PackageReference Include="System.Collections.Immutable">
|
||||||
<Version>1.7.0</Version>
|
<Version>1.7.0</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.Drawing.Common">
|
||||||
|
<Version>4.7.0</Version>
|
||||||
|
</PackageReference>
|
||||||
<PackageReference Include="System.Memory">
|
<PackageReference Include="System.Memory">
|
||||||
<Version>4.5.4</Version>
|
<Version>4.5.4</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
@ -13,11 +13,16 @@ class Farm
|
|||||||
private CropTypesHolder PresetCrops = new CropTypesHolder();
|
private CropTypesHolder PresetCrops = new CropTypesHolder();
|
||||||
private int Update;
|
private int Update;
|
||||||
private Astar astar = new Astar();
|
private Astar astar = new Astar();
|
||||||
|
private PerlinNoise perlin = new PerlinNoise();
|
||||||
|
private float[][] whiteNoise;
|
||||||
|
private float[][] perlinNoise;
|
||||||
|
|
||||||
|
|
||||||
//initializes the crops
|
//initializes the crops
|
||||||
public void init(Vector2 Size, Vector2 housepos)
|
public void init(Vector2 Size, Vector2 housepos)
|
||||||
{
|
{
|
||||||
|
whiteNoise = PerlinNoise.GenerateWhiteNoise(100, 100);
|
||||||
|
perlinNoise = PerlinNoise.GeneratePerlinNoise(whiteNoise, 1);
|
||||||
PresetCrops.init();
|
PresetCrops.init();
|
||||||
r = new Random();
|
r = new Random();
|
||||||
crops = new Crops[100, 100];
|
crops = new Crops[100, 100];
|
||||||
@ -26,6 +31,8 @@ class Farm
|
|||||||
{
|
{
|
||||||
for (int j = 0; j < 99; j++)
|
for (int j = 0; j < 99; j++)
|
||||||
{
|
{
|
||||||
|
int x = 0;
|
||||||
|
/*
|
||||||
int x = r.Next(0, 3);
|
int x = r.Next(0, 3);
|
||||||
if (x == 0)
|
if (x == 0)
|
||||||
{
|
{
|
||||||
@ -35,6 +42,13 @@ class Farm
|
|||||||
{
|
{
|
||||||
x = r.Next(1, 3);
|
x = r.Next(1, 3);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
if (perlinNoise[i][j] > 0 && perlinNoise[i][j] < 0.2f)
|
||||||
|
x = 0;
|
||||||
|
else if (perlinNoise[i][j] >= 0.2f && perlinNoise[i][j] < 0.7f)
|
||||||
|
x = 1;
|
||||||
|
else if (perlinNoise[i][j] >= 0.7f)
|
||||||
|
x = 2;
|
||||||
crops[i, j] = new Crops();
|
crops[i, j] = new Crops();
|
||||||
crops[i, j].setStatus(x);
|
crops[i, j].setStatus(x);
|
||||||
crops[i, j].setOriginalStatus();
|
crops[i, j].setOriginalStatus();
|
||||||
|
333
Game1/Sources/Crops/PerlinNoise.cs
Normal file
333
Game1/Sources/Crops/PerlinNoise.cs
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
|
||||||
|
class PerlinNoise
|
||||||
|
{
|
||||||
|
#region Feilds
|
||||||
|
static Random random = new Random();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Reusable Functions
|
||||||
|
|
||||||
|
public static float[][] GenerateWhiteNoise(int width, int height)
|
||||||
|
{
|
||||||
|
float[][] noise = GetEmptyArray<float>(width, height);
|
||||||
|
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < height; j++)
|
||||||
|
{
|
||||||
|
noise[i][j] = (float)random.NextDouble() % 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return noise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Interpolate(float x0, float x1, float alpha)
|
||||||
|
{
|
||||||
|
return x0 * (1 - alpha) + alpha * x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color Interpolate(Color col0, Color col1, float alpha)
|
||||||
|
{
|
||||||
|
float beta = 1 - alpha;
|
||||||
|
return Color.FromArgb(
|
||||||
|
255,
|
||||||
|
(int)(col0.R * alpha + col1.R * beta),
|
||||||
|
(int)(col0.G * alpha + col1.G * beta),
|
||||||
|
(int)(col0.B * alpha + col1.B * beta));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color GetColor(Color gradientStart, Color gradientEnd, float t)
|
||||||
|
{
|
||||||
|
float u = 1 - t;
|
||||||
|
|
||||||
|
Color color = Color.FromArgb(
|
||||||
|
255,
|
||||||
|
(int)(gradientStart.R * u + gradientEnd.R * t),
|
||||||
|
(int)(gradientStart.G * u + gradientEnd.G * t),
|
||||||
|
(int)(gradientStart.B * u + gradientEnd.B * t));
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color[][] MapGradient(Color gradientStart, Color gradientEnd, float[][] perlinNoise)
|
||||||
|
{
|
||||||
|
int width = perlinNoise.Length;
|
||||||
|
int height = perlinNoise[0].Length;
|
||||||
|
|
||||||
|
Color[][] image = GetEmptyArray<Color>(width, height); //an array of colours
|
||||||
|
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < height; j++)
|
||||||
|
{
|
||||||
|
image[i][j] = GetColor(gradientStart, gradientEnd, perlinNoise[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T[][] GetEmptyArray<T>(int width, int height)
|
||||||
|
{
|
||||||
|
T[][] image = new T[width][];
|
||||||
|
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
image[i] = new T[height];
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float[][] GenerateSmoothNoise(float[][] baseNoise, int octave)
|
||||||
|
{
|
||||||
|
int width = baseNoise.Length;
|
||||||
|
int height = baseNoise[0].Length;
|
||||||
|
|
||||||
|
float[][] smoothNoise = GetEmptyArray<float>(width, height);
|
||||||
|
|
||||||
|
int samplePeriod = 1 << octave; // calculates 2 ^ k
|
||||||
|
float sampleFrequency = 1.0f / samplePeriod;
|
||||||
|
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
//calculate the horizontal sampling indices
|
||||||
|
int sample_i0 = (i / samplePeriod) * samplePeriod;
|
||||||
|
int sample_i1 = (sample_i0 + samplePeriod) % width; //wrap around
|
||||||
|
float horizontal_blend = (i - sample_i0) * sampleFrequency;
|
||||||
|
|
||||||
|
for (int j = 0; j < height; j++)
|
||||||
|
{
|
||||||
|
//calculate the vertical sampling indices
|
||||||
|
int sample_j0 = (j / samplePeriod) * samplePeriod;
|
||||||
|
int sample_j1 = (sample_j0 + samplePeriod) % height; //wrap around
|
||||||
|
float vertical_blend = (j - sample_j0) * sampleFrequency;
|
||||||
|
|
||||||
|
//blend the top two corners
|
||||||
|
float top = Interpolate(baseNoise[sample_i0][sample_j0],
|
||||||
|
baseNoise[sample_i1][sample_j0], horizontal_blend);
|
||||||
|
|
||||||
|
//blend the bottom two corners
|
||||||
|
float bottom = Interpolate(baseNoise[sample_i0][sample_j1],
|
||||||
|
baseNoise[sample_i1][sample_j1], horizontal_blend);
|
||||||
|
|
||||||
|
//final blend
|
||||||
|
smoothNoise[i][j] = Interpolate(top, bottom, vertical_blend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return smoothNoise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float[][] GeneratePerlinNoise(float[][] baseNoise, int octaveCount)
|
||||||
|
{
|
||||||
|
int width = baseNoise.Length;
|
||||||
|
int height = baseNoise[0].Length;
|
||||||
|
|
||||||
|
float[][][] smoothNoise = new float[octaveCount][][]; //an array of 2D arrays containing
|
||||||
|
|
||||||
|
float persistance = 0.7f;
|
||||||
|
|
||||||
|
//generate smooth noise
|
||||||
|
for (int i = 0; i < octaveCount; i++)
|
||||||
|
{
|
||||||
|
smoothNoise[i] = GenerateSmoothNoise(baseNoise, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
float[][] perlinNoise = GetEmptyArray<float>(width, height); //an array of floats initialised to 0
|
||||||
|
|
||||||
|
float amplitude = 1.0f;
|
||||||
|
float totalAmplitude = 0.0f;
|
||||||
|
|
||||||
|
//blend noise together
|
||||||
|
for (int octave = octaveCount - 1; octave >= 0; octave--)
|
||||||
|
{
|
||||||
|
amplitude *= persistance;
|
||||||
|
totalAmplitude += amplitude;
|
||||||
|
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < height; j++)
|
||||||
|
{
|
||||||
|
perlinNoise[i][j] += smoothNoise[octave][i][j] * amplitude;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//normalisation
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < height; j++)
|
||||||
|
{
|
||||||
|
perlinNoise[i][j] /= totalAmplitude;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return perlinNoise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float[][] GeneratePerlinNoise(int width, int height, int octaveCount)
|
||||||
|
{
|
||||||
|
float[][] baseNoise = GenerateWhiteNoise(width, height);
|
||||||
|
|
||||||
|
return GeneratePerlinNoise(baseNoise, octaveCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color[][] MapToGrey(float[][] greyValues)
|
||||||
|
{
|
||||||
|
int width = greyValues.Length;
|
||||||
|
int height = greyValues[0].Length;
|
||||||
|
|
||||||
|
Color[][] image = GetEmptyArray<Color>(width, height);
|
||||||
|
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < height; j++)
|
||||||
|
{
|
||||||
|
int grey = (int)(255 * greyValues[i][j]);
|
||||||
|
Color color = Color.FromArgb(255, grey, grey, grey);
|
||||||
|
|
||||||
|
image[i][j] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SaveImage(Color[][] image, string fileName)
|
||||||
|
{
|
||||||
|
int width = image.Length;
|
||||||
|
int height = image[0].Length;
|
||||||
|
|
||||||
|
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
|
||||||
|
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < height; j++)
|
||||||
|
{
|
||||||
|
bitmap.SetPixel(i, j, image[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap.Save(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color[][] LoadImage(string fileName)
|
||||||
|
{
|
||||||
|
Bitmap bitmap = new Bitmap(fileName);
|
||||||
|
|
||||||
|
int width = bitmap.Width;
|
||||||
|
int height = bitmap.Height;
|
||||||
|
|
||||||
|
Color[][] image = GetEmptyArray<Color>(width, height);
|
||||||
|
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < height; j++)
|
||||||
|
{
|
||||||
|
image[i][j] = bitmap.GetPixel(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color[][] BlendImages(Color[][] image1, Color[][] image2, float[][] perlinNoise)
|
||||||
|
{
|
||||||
|
int width = image1.Length;
|
||||||
|
int height = image1[0].Length;
|
||||||
|
|
||||||
|
Color[][] image = GetEmptyArray<Color>(width, height); //an array of colours for the new image
|
||||||
|
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < height; j++)
|
||||||
|
{
|
||||||
|
image[i][j] = Interpolate(image1[i][j], image2[i][j], perlinNoise[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DemoGradientMap()
|
||||||
|
{
|
||||||
|
int width = 256;
|
||||||
|
int height = 256;
|
||||||
|
int octaveCount = 8;
|
||||||
|
|
||||||
|
Color gradientStart = Color.FromArgb(255, 0, 0);
|
||||||
|
Color gradientEnd = Color.FromArgb(255, 0, 255);
|
||||||
|
|
||||||
|
float[][] perlinNoise = GeneratePerlinNoise(width, height, octaveCount);
|
||||||
|
Color[][] perlinImage = MapGradient(gradientStart, gradientEnd, perlinNoise);
|
||||||
|
SaveImage(perlinImage, "perlin_noise.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float[][] AdjustLevels(float[][] image, float low, float high)
|
||||||
|
{
|
||||||
|
int width = image.Length;
|
||||||
|
int height = image[0].Length;
|
||||||
|
|
||||||
|
float[][] newImage = GetEmptyArray<float>(width, height);
|
||||||
|
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < height; j++)
|
||||||
|
{
|
||||||
|
float col = image[i][j];
|
||||||
|
|
||||||
|
if (col <= low)
|
||||||
|
{
|
||||||
|
newImage[i][j] = 0;
|
||||||
|
}
|
||||||
|
else if (col >= high)
|
||||||
|
{
|
||||||
|
newImage[i][j] = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newImage[i][j] = (col - low) / (high - low);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Color[][][] AnimateTransition(Color[][] image1, Color[][] image2, int frameCount)
|
||||||
|
{
|
||||||
|
Color[][][] animation = new Color[frameCount][][];
|
||||||
|
|
||||||
|
float low = 0;
|
||||||
|
float increment = 1.0f / frameCount;
|
||||||
|
float high = increment;
|
||||||
|
|
||||||
|
float[][] perlinNoise = AdjustLevels(
|
||||||
|
GeneratePerlinNoise(image1.Length, image1[0].Length, 9),
|
||||||
|
0.2f, 0.8f);
|
||||||
|
|
||||||
|
for (int i = 0; i < frameCount; i++)
|
||||||
|
{
|
||||||
|
AdjustLevels(perlinNoise, low, high);
|
||||||
|
float[][] blendMask = AdjustLevels(perlinNoise, low, high);
|
||||||
|
animation[i] = BlendImages(image1, image2, blendMask);
|
||||||
|
//SaveImage(animation[i], "blend_animation" + i + ".png");
|
||||||
|
SaveImage(MapToGrey(blendMask), "blend_mask" + i + ".png");
|
||||||
|
low = high;
|
||||||
|
high += increment;
|
||||||
|
}
|
||||||
|
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user