vkmEngine 1.0.0
A C++ game engine · vkmengine.com
Loading...
Searching...
No Matches
random.h
1#pragma once
2
3#include <cstdint>
4
5namespace Vkm::Engine::Math {
6
12class Rng {
13 public:
14 Rng() = default;
15
21 explicit Rng(uint64_t seed, uint64_t stream = DEFAULT_STREAM) {
22 this->seed(seed, stream);
23 }
24
25 ~Rng() = default;
26
27 Rng(const Rng& other) = default;
28 Rng& operator=(const Rng& other) = default;
29
30 Rng(Rng && other) noexcept = default;
31 Rng& operator=(Rng && other) noexcept = default;
32
33 public:
39 void seed(uint64_t seed, uint64_t stream = DEFAULT_STREAM) {
40 m_state = 0u;
41 m_inc = (stream << 1u) | 1u; // inc must be odd
42 nextU32();
43 m_state += seed;
44 nextU32();
45 }
46
54 uint32_t nextU32() {
55 const uint64_t old = m_state;
56 m_state = old * 6364136223846793005ULL + m_inc;
57 const uint32_t xorshifted = static_cast<uint32_t>(((old >> 18u) ^ old) >> 27u);
58 const uint32_t rot = static_cast<uint32_t>(old >> 59u);
59 return (xorshifted >> rot) | (xorshifted << ((0u - rot) & 31u));
60 }
61
62 float nextFloat() { return (nextU32() >> 8) * (1.0f / 16777216.0f); }
63 float nextFloat(float min, float max) { return min + (max - min) * nextFloat(); }
64 int nextInt(int min, int max) {
65 return min + static_cast<int>(boundedU32(static_cast<uint32_t>(max - min) + 1u));
66 }
67 bool nextBool() { return (nextU32() >> 31u) != 0u; }
68
69 private:
71 static constexpr uint64_t DEFAULT_STREAM = 0xda3e39cb94b95bdbULL;
72
73 private:
82 uint32_t boundedU32(uint32_t range) {
83 uint32_t x = nextU32();
84 uint64_t m = static_cast<uint64_t>(x) * static_cast<uint64_t>(range);
85 uint32_t low = static_cast<uint32_t>(m);
86 if (low < range) {
87 const uint32_t threshold = (0u - range) % range;
88 while (low < threshold) {
89 x = nextU32();
90 m = static_cast<uint64_t>(x) * static_cast<uint64_t>(range);
91 low = static_cast<uint32_t>(m);
92 }
93 }
94 return static_cast<uint32_t>(m >> 32u);
95 }
96
97 private:
98 uint64_t m_state = 0x853c49e6748fea9bULL;
99 uint64_t m_inc = DEFAULT_STREAM;
100};
101
108namespace Random {
109
120
126inline float value() { return rng().nextFloat(); }
127
135inline float range(float min, float max) { return rng().nextFloat(min, max); }
136
144inline int range(int min, int max) { return rng().nextInt(min, max); }
145
151inline bool boolean() { return rng().nextBool(); }
152
153} // namespace Random
154
155} // namespace Vkm::Engine::Math
PCG32 pseudo-random generator (O'Neill, 2014).
Definition random.h:12
void seed(uint64_t seed, uint64_t stream=DEFAULT_STREAM)
Re-seed in place, discarding the current sequence position.
Definition random.h:39
uint32_t nextU32()
Advance the state and return the next raw 32-bit value.
Definition random.h:54
Rng(uint64_t seed, uint64_t stream=DEFAULT_STREAM)
Seed with an explicit state and (optionally) stream selector.
Definition random.h:21
The casual draws: a float, a range, a coin, off a per-thread generator.
Definition random.h:108
float range(float min, float max)
Uniform float in [min, max), from the per-thread generator.
Definition random.h:135
bool boolean()
Fair coin flip, from the per-thread generator.
Definition random.h:151
float value()
Uniform float in [0, 1), from the per-thread generator.
Definition random.h:126
Rng & rng()
Per-thread default generator.