#include "noise.h" #include #include uint8_t perm[512]; static uint16_t currentSeed = 0xFFFF; inline static float fade(float t) { return t * t * t * (t * (t * 6 - 15) + 10); } inline static float noiseLerp(float a, float b, float t) { return a + t * (b - a); } inline static float grad(uint8_t hash, float x) { uint8_t h = hash & 15; float grad = 1.0f + (h & 7); // 1 to 8 if (h & 8) grad = -grad; return (grad * x) / 4.0f; // match JS scaling } static void generatePermutation(uint16_t seed, uint8_t* perm) { uint8_t p[256]; uint32_t s = seed; for (int i = 0; i < 256; i++) { s = (s * 1664525 + 1013904223) % 4294967296; p[i] = i; } for (int i = 255; i > 0; i--) { uint32_t j = s % (i + 1); std::swap(p[i], p[j]); s = (s * 1664525 + 1013904223) % 4294967296; } for (int i = 0; i < 512; i++) { perm[i] = p[i & 255]; } } float perlin1D_octave(uint16_t seed, float x, int octaves = 4, float persistence = 0.5f) { if (seed != currentSeed) { generatePermutation(seed, perm); currentSeed = seed; } float total = 0.0f; float amplitude = 1.0f; float frequency = 1.0f; float maxValue = 0.0f; for (int i = 0; i < octaves; i++) { total += perlin1D(seed, x * frequency) * amplitude; maxValue += amplitude; amplitude *= persistence; frequency *= 2.0f; } return total / maxValue; } float perlin1D(uint16_t seed, float x) { int xi = static_cast(floor(x)) & 255; float xf = x - floor(x); float u = fade(xf); uint8_t a = perm[xi]; uint8_t b = perm[xi + 1]; return noiseLerp(grad(a, xf), grad(b, xf - 1.0f), u); }