78 lines
No EOL
2 KiB
C
78 lines
No EOL
2 KiB
C
#include "cubes.h"
|
|
#include <math.h>
|
|
|
|
int default_seed = 69420;
|
|
|
|
double noise_interpolate(double a0, double a1, double w) {
|
|
return (a1 - a0) * (3.0 - w * 2.0) * w * w + a0;
|
|
}
|
|
|
|
int noise_hash(int a, int b) { return b + 0x9e3779b9 + (a << 6) + (a >> 2); }
|
|
|
|
struct v2f noise_perlin_grad(int x, int y, int seed) {
|
|
int x_hash = noise_hash(x, seed);
|
|
int y_hash = noise_hash(seed, y);
|
|
|
|
double random = noise_hash(x_hash, y_hash) * (M_PI / ~(~0u >> 1));
|
|
struct v2f out = {cos(random), sin(random)};
|
|
return out;
|
|
}
|
|
|
|
double noise_perlin_dot(double ix, double iy, double x, double y, int seed) {
|
|
struct v2f grad = noise_perlin_grad(ix, iy, seed);
|
|
|
|
double dx = x - (double)ix;
|
|
double dy = y - (double)iy;
|
|
return (dx * grad.pos[0] + dy * grad.pos[1]);
|
|
}
|
|
|
|
double noise_perlin(double x, double y, double s, int seed) {
|
|
x /= s;
|
|
y /= s;
|
|
|
|
int x0 = (int)floor(x);
|
|
int x1 = x0 + 1;
|
|
int y0 = (int)floor(y);
|
|
int y1 = y0 + 1;
|
|
|
|
float sx = x - (float)x0;
|
|
float sy = y - (float)y0;
|
|
|
|
float n0, n1, ix0, ix1, value;
|
|
|
|
n0 = noise_perlin_dot(x0, y0, x, y, seed);
|
|
n1 = noise_perlin_dot(x1, y0, x, y, seed);
|
|
ix0 = noise_interpolate(n0, n1, sx);
|
|
|
|
n0 = noise_perlin_dot(x0, y1, x, y, seed);
|
|
n1 = noise_perlin_dot(x1, y1, x, y, seed);
|
|
ix1 = noise_interpolate(n0, n1, sx);
|
|
|
|
value = noise_interpolate(ix0, ix1, sy);
|
|
|
|
return value;
|
|
}
|
|
|
|
struct chunk noise_chunk(struct chunk chunk, int x, int y, int z) {
|
|
int c = 0;
|
|
for (int x2 = 0; x2 < CHUNK_LENGTH; x2++) {
|
|
int x3 = x2 + x * CHUNK_LENGTH;
|
|
for (int z2 = 0; z2 < CHUNK_LENGTH; z2++) {
|
|
int z3 = z2 + z * CHUNK_LENGTH;
|
|
double hp = noise_perlin(x3, z3, 128.0, default_seed);
|
|
hp = ((hp > 0.0) ? -1.0 : 1.0) * (pow(fabs(hp), 0.7));
|
|
hp *= 128.0;
|
|
int h = hp + 64;
|
|
|
|
for (int y2 = 0; y2 < CHUNK_LENGTH; y2++) {
|
|
int y3 = y2 + y * CHUNK_LENGTH;
|
|
chunk.blocks[c] = 0;
|
|
if (y3 < h) chunk.blocks[c] = 4;
|
|
if (y3 < h - 1) chunk.blocks[c] = 5;
|
|
if (y3 < h - 2) chunk.blocks[c] = 6;
|
|
c++;
|
|
}
|
|
}
|
|
}
|
|
return chunk;
|
|
} |