|
|
531f67 |
#ifndef GENERATOR_H
|
|
|
531f67 |
#define GENERATOR_H
|
|
|
531f67 |
|
|
|
531f67 |
|
|
|
531f67 |
#include <climits></climits>
|
|
|
531f67 |
#include <map></map>
|
|
|
531f67 |
|
|
|
531f67 |
#include "surface.h"
|
|
|
531f67 |
#include "vector.h"
|
|
|
531f67 |
|
|
|
531f67 |
|
|
|
531f67 |
class Generator: public Shared {
|
|
|
531f67 |
public:
|
|
|
5f2fc2 |
enum {
|
|
|
5f2fc2 |
gray0 = 1ull << 28,
|
|
|
5f2fc2 |
one = 1ull << 32,
|
|
|
5f2fc2 |
gray1 = 1ull << 36,
|
|
|
5f2fc2 |
big = 1ull << 60,
|
|
|
5f2fc2 |
max_side = 1ull << 16,
|
|
|
5f2fc2 |
max_area = 1ull << 32,
|
|
|
5f2fc2 |
};
|
|
|
5f2fc2 |
|
|
|
531f67 |
struct CacheEntry;
|
|
|
531f67 |
typedef std::map<ulongintvector2, cacheentry=""> Cache;</ulongintvector2,>
|
|
|
531f67 |
|
|
|
531f67 |
struct CacheEntry {
|
|
|
531f67 |
Cache::iterator next, previous;
|
|
|
531f67 |
bool in_use;
|
|
|
531f67 |
Vector4 value;
|
|
|
531f67 |
};
|
|
|
531f67 |
|
|
|
5f2fc2 |
class GenSurface {
|
|
|
5f2fc2 |
private:
|
|
|
5f2fc2 |
Vector4 *data;
|
|
|
5f2fc2 |
ULongInt w, h;
|
|
|
5f2fc2 |
ULongIntVector2 m_offset;
|
|
|
5f2fc2 |
ULongInt m_step;
|
|
|
5f2fc2 |
|
|
|
5f2fc2 |
public:
|
|
|
5f2fc2 |
inline GenSurface():
|
|
|
5f2fc2 |
data(), w(), h(), m_step() { }
|
|
|
5f2fc2 |
inline GenSurface(const ULongIntPair2 &bounds, ULongInt step):
|
|
|
5f2fc2 |
GenSurface() { create(bounds, step); }
|
|
|
5f2fc2 |
inline GenSurface(const GenSurface &other):
|
|
|
5f2fc2 |
GenSurface() { *this = other; }
|
|
|
5f2fc2 |
inline GenSurface(GenSurface &&other):
|
|
|
5f2fc2 |
data(other.data), w(other.w), h(other.h), m_offset(other.m_offset), m_step(other.m_step)
|
|
|
5f2fc2 |
{ if (&other != this) other.data = nullptr; }
|
|
|
5f2fc2 |
inline ~GenSurface()
|
|
|
5f2fc2 |
{ reset(); }
|
|
|
5f2fc2 |
|
|
|
5f2fc2 |
void create(const ULongIntPair2 &bounds, ULongInt step);
|
|
|
5f2fc2 |
void reset();
|
|
|
5f2fc2 |
GenSurface& operator= (const GenSurface &other);
|
|
|
5f2fc2 |
|
|
|
5f2fc2 |
inline bool is_valid() const {
|
|
|
5f2fc2 |
return data
|
|
|
5f2fc2 |
&& w < max_side
|
|
|
5f2fc2 |
&& h < max_side
|
|
|
5f2fc2 |
&& w*h < max_area
|
|
|
5f2fc2 |
&& w%2 && h%2
|
|
|
5f2fc2 |
&& !(m_step & (m_step - 1))
|
|
|
5f2fc2 |
&& !(m_offset.x & (m_step - 1))
|
|
|
5f2fc2 |
&& !(m_offset.y & (m_step - 1))
|
|
|
5f2fc2 |
&& m_offset.x & m_step
|
|
|
5f2fc2 |
&& m_offset.y & m_step;
|
|
|
5f2fc2 |
}
|
|
|
5f2fc2 |
|
|
|
5f2fc2 |
inline ULongInt width() const { return w; }
|
|
|
5f2fc2 |
inline ULongInt height() const { return h; }
|
|
|
5f2fc2 |
inline const ULongIntVector2& offset() const { return m_offset; }
|
|
|
5f2fc2 |
inline ULongInt step() const { return m_step; }
|
|
|
5f2fc2 |
|
|
|
5f2fc2 |
inline Vector4* operator[] (ULongInt row) { return data + row*w; }
|
|
|
5f2fc2 |
inline const Vector4* operator[] (ULongInt row) const { return data + row*w; }
|
|
|
5f2fc2 |
|
|
|
5f2fc2 |
inline ULongIntVector2 p0() const { return m_offset; }
|
|
|
5f2fc2 |
inline ULongIntVector2 p1() const { return m_offset + ULongIntVector2(w-1, h-1)*m_step; }
|
|
|
5f2fc2 |
};
|
|
|
5f2fc2 |
|
|
|
5f2fc2 |
|
|
|
5f2fc2 |
static inline ULongInt random(ULongInt x)
|
|
|
5f2fc2 |
{ return x*2862933555777941757ull + 3037000493ull; }
|
|
|
a9c87c |
|
|
|
531f67 |
static inline Real random_to_real(ULongInt x)
|
|
|
531f67 |
{ return Real(x)/Real(ULLONG_MAX); }
|
|
|
a9c87c |
static inline Real random_to_normal(ULongInt x, ULongInt y)
|
|
|
a9c87c |
{ return sqrt(-2*log(random_to_real(x))) * sin(2*M_PI*random_to_real(y)); }
|
|
|
a9c87c |
|
|
|
531f67 |
private:
|
|
|
531f67 |
const int max_cache_count;
|
|
|
531f67 |
|
|
|
531f67 |
mutable Cache m_cache;
|
|
|
531f67 |
mutable Cache::iterator m_cache_top;
|
|
|
531f67 |
mutable int m_cache_count;
|
|
|
531f67 |
|
|
|
531f67 |
ULongInt m_seeds[2][4];
|
|
|
5f2fc2 |
|
|
|
531f67 |
public:
|
|
|
531f67 |
Generator();
|
|
|
531f67 |
explicit Generator(ULongInt seed);
|
|
|
531f67 |
|
|
|
531f67 |
inline const ULongInt* seeds_x() const { return m_seeds[0]; }
|
|
|
531f67 |
inline const ULongInt* seeds_y() const { return m_seeds[1]; }
|
|
|
531f67 |
inline ULongInt seed() const { return seeds_x()[0]; }
|
|
|
531f67 |
void set_seed(ULongInt x);
|
|
|
531f67 |
|
|
|
531f67 |
Real random(const ULongIntVector2 &coord, int index) const;
|
|
|
5f2fc2 |
inline Vector4 random(const ULongIntVector2 &coord) const
|
|
|
5f2fc2 |
{ return Vector4(random(coord, 0), random(coord, 1), random(coord, 2), random(coord, 3)); }
|
|
|
5f2fc2 |
|
|
|
531f67 |
Vector4 generate(const ULongIntVector2 &coord, bool shrink_cache = true) const;
|
|
|
531f67 |
Vector4 generate(const Vector2 &coord, const Vector2 &precision) const;
|
|
|
4dc49c |
void generate(Surface &target, const Pair2 &bounds) const;
|
|
|
5f2fc2 |
|
|
|
5f2fc2 |
void generate(GenSurface &target) const;
|
|
|
5f2fc2 |
void generate(GenSurface &target, const GenSurface &source) const;
|
|
|
531f67 |
};
|
|
|
531f67 |
|
|
|
531f67 |
|
|
|
531f67 |
#endif
|