+#define NOISE_FLAG_DEFAULTS 0x01
+#define NOISE_FLAG_EASED 0x02
+#define NOISE_FLAG_ABSVALUE 0x04
+
+//// TODO(hmmmm): implement these!
+#define NOISE_FLAG_POINTBUFFER 0x08
+#define NOISE_FLAG_SIMPLEX 0x10
+
+struct NoiseParams {
+ float offset = 0.0f;
+ float scale = 1.0f;
+ v3f spread = v3f(250, 250, 250);
+ s32 seed = 12345;
+ u16 octaves = 3;
+ float persist = 0.6f;
+ float lacunarity = 2.0f;
+ u32 flags = NOISE_FLAG_DEFAULTS;
+
+ NoiseParams() = default;
+
+ NoiseParams(float offset_, float scale_, const v3f &spread_, s32 seed_,
+ u16 octaves_, float persist_, float lacunarity_,
+ u32 flags_=NOISE_FLAG_DEFAULTS)
+ {
+ offset = offset_;
+ scale = scale_;
+ spread = spread_;
+ seed = seed_;
+ octaves = octaves_;
+ persist = persist_;
+ lacunarity = lacunarity_;
+ flags = flags_;
+ }
+};
+
+class Noise {
+public:
+ NoiseParams np;
+ s32 seed;
+ u32 sx;
+ u32 sy;
+ u32 sz;
+ float *noise_buf = nullptr;
+ float *gradient_buf = nullptr;
+ float *persist_buf = nullptr;
+ float *result = nullptr;
+
+ Noise(NoiseParams *np, s32 seed, u32 sx, u32 sy, u32 sz=1);
+ ~Noise();
+
+ void setSize(u32 sx, u32 sy, u32 sz=1);
+ void setSpreadFactor(v3f spread);
+ void setOctaves(int octaves);
+
+ void gradientMap2D(
+ float x, float y,
+ float step_x, float step_y,
+ s32 seed);
+ void gradientMap3D(
+ float x, float y, float z,
+ float step_x, float step_y, float step_z,
+ s32 seed);
+
+ float *perlinMap2D(float x, float y, float *persistence_map=NULL);
+ float *perlinMap3D(float x, float y, float z, float *persistence_map=NULL);
+
+ inline float *perlinMap2D_PO(float x, float xoff, float y, float yoff,
+ float *persistence_map=NULL)
+ {
+ return perlinMap2D(
+ x + xoff * np.spread.X,
+ y + yoff * np.spread.Y,
+ persistence_map);
+ }
+
+ inline float *perlinMap3D_PO(float x, float xoff, float y, float yoff,
+ float z, float zoff, float *persistence_map=NULL)
+ {
+ return perlinMap3D(
+ x + xoff * np.spread.X,
+ y + yoff * np.spread.Y,
+ z + zoff * np.spread.Z,
+ persistence_map);
+ }
+
+private:
+ void allocBuffers();
+ void resizeNoiseBuf(bool is3d);
+ void updateResults(float g, float *gmap, const float *persistence_map,
+ size_t bufsize);
+
+};
+
+float NoisePerlin2D(NoiseParams *np, float x, float y, s32 seed);
+float NoisePerlin3D(NoiseParams *np, float x, float y, float z, s32 seed);
+
+inline float NoisePerlin2D_PO(NoiseParams *np, float x, float xoff,
+ float y, float yoff, s32 seed)
+{
+ return NoisePerlin2D(np,
+ x + xoff * np->spread.X,
+ y + yoff * np->spread.Y,
+ seed);
+}
+
+inline float NoisePerlin3D_PO(NoiseParams *np, float x, float xoff,
+ float y, float yoff, float z, float zoff, s32 seed)
+{
+ return NoisePerlin3D(np,
+ x + xoff * np->spread.X,
+ y + yoff * np->spread.Y,
+ z + zoff * np->spread.Z,
+ seed);
+}
+
+// Return value: -1 ... 1
+float noise2d(int x, int y, s32 seed);
+float noise3d(int x, int y, int z, s32 seed);
+
+float noise2d_gradient(float x, float y, s32 seed, bool eased=true);
+float noise3d_gradient(float x, float y, float z, s32 seed, bool eased=false);
+
+float noise2d_perlin(float x, float y, s32 seed,
+ int octaves, float persistence, bool eased=true);
+
+float noise2d_perlin_abs(float x, float y, s32 seed,
+ int octaves, float persistence, bool eased=true);
+
+float noise3d_perlin(float x, float y, float z, s32 seed,
+ int octaves, float persistence, bool eased=false);
+
+float noise3d_perlin_abs(float x, float y, float z, s32 seed,
+ int octaves, float persistence, bool eased=false);
+
+inline float easeCurve(float t)
+{
+ return t * t * t * (t * (6.f * t - 15.f) + 10.f);
+}