yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Ellie Hermaszewskaformatf65d756bf

master
3.2 KiB116 linesraw
1#ifndef SLANG_CORE_RANDOM_GENERATOR_H
2#define SLANG_CORE_RANDOM_GENERATOR_H
3
4#include "slang-smart-pointer.h"
5#include "slang.h"
6
7#include <stdlib.h>
8#include <string.h>
9
10namespace Slang
11{
12
13class RandomGenerator : public RefObject
14{
15public:
16    /// Make a copy of the generator in the same state
17    virtual RandomGenerator* clone() = 0;
18
19    /// Reset with a seed
20    virtual void reset(int32_t seed) = 0;
21    /// Next int32_t random number
22    virtual int32_t nextInt32() = 0;
23    /// Next int64_t random number
24    virtual int64_t nextInt64();
25
26    /// Get a 0-1 range floating point
27    virtual float nextUnitFloat32();
28
29    /// Get the next bool
30    virtual bool nextBool();
31
32    /// Get multiple int32s
33    virtual void nextInt32s(int32_t* dst, size_t count) = 0;
34
35    /// Next uint32_t
36    uint32_t nextUInt32() { return uint32_t(nextInt32()); }
37
38    /// Next Int32 which can only be positive
39    int32_t nextPositiveInt32() { return nextInt32() & 0x7fffffff; }
40    /// Next Int64 which can only be positive
41    int64_t nextPositiveInt64() { return nextInt64() & SLANG_INT64(0x7fffffffffffffff); }
42
43    /// Returns value up to BUT NOT INCLUDING maxValue.
44    int32_t nextInt32UpTo(int32_t maxValue)
45    {
46        assert(maxValue > 0);
47        return (maxValue <= 1) ? 0 : (nextPositiveInt32() % maxValue);
48    }
49
50    /// Returns value from min up to BUT NOT INCLUDING max.
51    int32_t nextInt32InRange(int32_t min, int32_t max);
52
53    /// Returns value from min up to BUT NOT INCLUDING max
54    uint32_t nextUInt32InRange(uint32_t min, uint32_t max);
55
56    /// Returns value up to BUT NOT INCLUDING maxValue
57    int64_t nextInt64UpTo(int64_t maxValue)
58    {
59        assert(maxValue > 0);
60        return (maxValue <= 1) ? 0 : (nextPositiveInt64() % maxValue);
61    }
62
63    /// Returns value from min up to BUT NOT INCLUDING max
64    int64_t nextInt64InRange(int64_t min, int64_t max);
65
66    /// Fill with random data.
67    /// NOTE! Output is only identical bytes if generator in same state *and* size_t(dst) & 3 is the
68    /// same on calls.
69    void nextData(void* dst, size_t size);
70
71    /// Create a RandomGenerator with specified seed using default generator type
72    static RandomGenerator* create(int32_t seed);
73};
74
75/* Mersenne Twister random number generator
76https://en.wikipedia.org/wiki/Mersenne_Twister
77*/
78class Mt19937RandomGenerator : public RandomGenerator
79{
80public:
81    typedef Mt19937RandomGenerator ThisType;
82
83    enum
84    {
85        kNumEntries = 624
86    };
87
88    Mt19937RandomGenerator* clone() SLANG_OVERRIDE { return new ThisType(*this); }
89    void reset(int32_t seed) SLANG_OVERRIDE;
90    int32_t nextInt32() SLANG_OVERRIDE;
91    void nextInt32s(int32_t* dst, size_t count) SLANG_OVERRIDE;
92
93    /// Ctor
94    Mt19937RandomGenerator();
95    Mt19937RandomGenerator(const ThisType& rhs);
96    explicit Mt19937RandomGenerator(int32_t seed);
97
98    /// Assignment
99    void operator=(const ThisType& rhs)
100    {
101        m_index = rhs.m_index;
102        ::memcpy(m_mt, rhs.m_mt, sizeof(m_mt));
103    }
104
105protected:
106    void _generate();
107
108    uint32_t m_mt[kNumEntries]; ///< The random state vector
109    int m_index;                ///< If set to >= kMaxEntries it means reset
110};
111
112typedef Mt19937RandomGenerator DefaultRandomGenerator;
113
114} // namespace Slang
115
116#endif // SLANG_RANDOM_GENERATOR_H