More work on cloudy brush, fix perlin noise.

This commit is contained in:
UnknownShadow200 2016-05-11 13:41:57 +10:00
parent ba62aae7af
commit 4bddbebead
2 changed files with 50 additions and 12 deletions

View File

@ -25,10 +25,14 @@ namespace MCGalaxy.Drawing.Brushes {
public sealed class CloudyBrush : FrequencyBrush {
readonly ExtBlock[] blocks;
readonly int[] counts;
readonly float[] thresholds;
readonly ImprovedNoise noise;
public CloudyBrush(ExtBlock[] blocks, NoiseArgs n) {
public CloudyBrush(ExtBlock[] blocks, int[] counts, NoiseArgs n) {
this.blocks = blocks;
this.counts = counts;
this.thresholds = thresholds;
Random r = n.Seed == int.MinValue ? new Random() : new Random(n.Seed);
noise = new ImprovedNoise(r);
@ -66,8 +70,7 @@ namespace MCGalaxy.Drawing.Brushes {
Filter, arg => Handler(arg, args.Player, ref n));
if (toAffect == null) return null;
ExtBlock[] blocks = Combine(toAffect, count);
return new CloudyBrush(blocks, n);
return new CloudyBrush(toAffect, count, n);
}
// We want to handle non block options.
@ -105,8 +108,43 @@ namespace MCGalaxy.Drawing.Brushes {
return false;
}
public override void Configure(DrawOp op, Player p) {
public unsafe override void Configure(DrawOp op, Player p) {
Player.Message(p, "Calculating noise distribution...");
// Initalise our 10000 element histogram
const int count = 10000;
int* values = stackalloc int[count];
for (int i = 0; i < count; i++)
values[i] = 0;
// Fill the histogram
for (int x = op.Min.X; x <= op.Max.X; x++)
for (int y = op.Min.Y; y <= op.Max.Y; y++)
for (int z = op.Min.Z; z <= op.Max.Z; z++)
{
float N = noise.NormalisedNoise(x, y, z);
N = (N + 1) * 0.5f; // rescale to [0, 1]
int index = (int)(N * count);
index = index < 0 ? 0 : index;
index = index >= count ? count - 1 : index;
values[index]++;
}
// Calculate the ratio of blocks
float* ratio = stackalloc float[counts.Length];
int total = 0;
for (int i = 0; i < counts.Length; i++)
total += counts[i];
float prev = 0;
for (int i = 0; i < ratio.Length; i++) {
ratio[i] = prev + (counts[i] / (float)total);
prev = ratio[i];
}
// Map noise distribution to block ratios TODO how?
int volume = (op.Max.X - op.Min.X + 1)
* (op.Max.Y - op.Min.Y + 1) * (op.Max.Z - op.Min.Z + 1);
Player.Message(p, "Finished calculating, now drawing.");
}

View File

@ -81,19 +81,19 @@ namespace MCGalaxy.Generator {
return Lerp(
Lerp(
Lerp(Grad(p[AA], X, Y, Z),
Grad(p[BA], X - 1, Y, Z),
Lerp(Grad(p[AA], x, y, z),
Grad(p[BA], x - 1, y, z),
u),
Lerp(Grad(p[AB], X, Y - 1, Z),
Grad(p[BB], X - 1, Y - 1, Z),
Lerp(Grad(p[AB], x, y - 1, z),
Grad(p[BB], x - 1, y - 1, z),
u),
v),
Lerp(
Lerp(Grad(p[AA + 1], X, Y, Z - 1),
Grad(p[BA + 1], X - 1, Y, Z - 1),
Lerp(Grad(p[AA + 1], x, y, z - 1),
Grad(p[BA + 1], x - 1, y, z - 1),
u),
Lerp(Grad(p[AB + 1], X, Y - 1, Z - 1),
Grad(p[BB + 1], X - 1, Y - 1, Z - 1),
Lerp(Grad(p[AB + 1], x, y - 1, z - 1),
Grad(p[BB + 1], x - 1, y - 1, z - 1),
u),
v),
w);