#include "cubes.h" #include 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 *= 32.0; int h = hp + 32; for (int y2 = 0; y2 < CHUNK_LENGTH; y2++) { int y3 = y2 + y * CHUNK_LENGTH; chunk.blocks[c] = (y3 < h) ? (((int)((hp + 64.0) * 2.98) % 3) + 1) : 0; c++; } } } return chunk; }