#ifndef GENERATOR_H
#define GENERATOR_H
#include <climits>
#include <map>
#include "surface.h"
#include "vector.h"
class Generator: public Shared {
public:
struct CacheEntry;
typedef std::map<ULongIntVector2, CacheEntry> Cache;
struct CacheEntry {
Cache::iterator next, previous;
bool in_use;
Vector4 value;
};
static inline ULongInt random(ULongInt x) {
++x;
x ^= x >> 2;
x ^= x << 3;
x ^= x >> 5;
x ^= x << 7;
x ^= x >> 11;
x ^= x << 13;
x ^= x >> 17;
x ^= x << 19;
x ^= x >> 23;
x ^= x << 29;
x ^= x >> 31;
x ^= x << 37;
x ^= x >> 41;
x ^= x << 43;
x ^= x >> 47;
x ^= x << 53;
x ^= x >> 59;
x ^= x << 61;
++x;
return x;
}
static inline Real random_to_real(ULongInt x)
{ return Real(x)/Real(ULLONG_MAX); }
static inline Real random_to_normal(ULongInt x, ULongInt y)
{ return sqrt(-2*log(random_to_real(x))) * sin(2*M_PI*random_to_real(y)); }
static inline Real mirror_repeat(Real x) {
x *= 0.5;
x -= floor(x);
x *= 2;
return x > 1 ? 2 - x : x;
}
private:
const ULongInt one;
const int max_cache_count;
mutable Cache m_cache;
mutable Cache::iterator m_cache_top;
mutable int m_cache_count;
ULongInt m_seeds[2][4];
public:
Generator();
explicit Generator(ULongInt seed);
inline const ULongInt* seeds_x() const { return m_seeds[0]; }
inline const ULongInt* seeds_y() const { return m_seeds[1]; }
inline ULongInt seed() const { return seeds_x()[0]; }
void set_seed(ULongInt x);
Real random(const ULongIntVector2 &coord, int index) const;
Vector4 generate(const ULongIntVector2 &coord, bool shrink_cache = true) const;
Vector4 generate(const Vector2 &coord, const Vector2 &precision) const;
void generate(Surface &target, const Pair2 &bounds) const;
};
#endif