52 lines
1.6 KiB
C++
52 lines
1.6 KiB
C++
#include "HeightGenerator.h"
|
|
#include <random>
|
|
#include <iostream>
|
|
#include <math.h>
|
|
# define MY_PI 3.1415927
|
|
std::random_device rd; // obtain a random number from hardware
|
|
const int HeightGenerator::SEED = rd();
|
|
|
|
float HeightGenerator::generateHeight(int x, int z) {
|
|
float total = 0;
|
|
int p = 0.25f;
|
|
for (int i = 0; i < 5; i++) {
|
|
float freq = pow(2, i);
|
|
float amp = pow(p, i);
|
|
total += getInterpolatedNoise(x * freq, z * freq) * amp;
|
|
}
|
|
return total;
|
|
}
|
|
|
|
float HeightGenerator::getInterpolatedNoise(float x, float z) {
|
|
int intX = int(x);
|
|
int intZ = int(z);
|
|
float fracX = x - intX;
|
|
float fracZ = z - intZ;
|
|
|
|
float v1 = getSmoothNoise(intX, intZ);
|
|
float v2 = getSmoothNoise(intX + 1, intZ);
|
|
float v3 = getSmoothNoise(intX, intZ + 1);
|
|
float v4 = getSmoothNoise(intX + 1, intZ + 1);
|
|
float i1 = interpolate(v1, v2, fracX);
|
|
float i2 = interpolate(v3, v4, fracX);
|
|
return interpolate(i1, i2, fracZ);
|
|
}
|
|
|
|
float HeightGenerator::interpolate(float a, float b, float blend) {
|
|
double theta = blend * MY_PI;
|
|
float f = float(1.f - cos(theta)) * 0.5f;
|
|
return a * (1 - f) + b * f;
|
|
}
|
|
|
|
float HeightGenerator::getSmoothNoise(int x, int z) {
|
|
float corners = float(getNoise(x - 1, z - 1) + getNoise(x + 1, z - 1) + getNoise(x - 1, z + 1) + getNoise(x + 1, z + 1)) / 16;
|
|
float sides = float(getNoise(x - 1, z) + getNoise(x + 1, z) + getNoise(x, z - 1) + getNoise(x, z + 1)) / 8;
|
|
float center = float(getNoise(x, z)) / 4;
|
|
return corners + sides + center;
|
|
}
|
|
|
|
float HeightGenerator::getNoise(int x, int z) {
|
|
std::mt19937 gen(SEED + x * 49632 + z * 325176);
|
|
std::uniform_real_distribution<> distr(-3, 3);
|
|
return distr(gen);
|
|
} |