1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! Random Number Generator

use hexf::*;

// pbrt
use crate::core::pbrt::Float;

// see rng.h

//#ifndef PBRT_HAVE_HEX_FP_CONSTANTS
//pub const FLOAT_ONE_MINUS_EPSILON: Float = 0.99999994;
//#else
pub const FLOAT_ONE_MINUS_EPSILON: Float = hexf32!("0x1.fffffep-1");
//#endif
pub const PCG32_DEFAULT_STATE: u64 = 0x853c_49e6_748f_ea9b;
pub const PCG32_DEFAULT_STREAM: u64 = 0xda3e_39cb_94b9_5bdb;
pub const PCG32_MULT: u64 = 0x5851_f42d_4c95_7f2d;

/// Random number generator
#[derive(Debug, Default, Copy, Clone)]
pub struct Rng {
    state: u64,
    inc: u64,
}

impl Rng {
    pub fn new() -> Self {
        Rng {
            state: PCG32_DEFAULT_STATE,
            inc: PCG32_DEFAULT_STREAM,
        }
    }
    pub fn set_sequence(&mut self, initseq: u64) {
        self.state = 0_u64;
        let (shl, _overflow) = initseq.overflowing_shl(1);
        self.inc = shl | 1;
        self.uniform_uint32();
        let (add, _overflow) = self.state.overflowing_add(PCG32_DEFAULT_STATE);
        self.state = add;
        self.uniform_uint32();
    }
    pub fn uniform_uint32(&mut self) -> u32 {
        let oldstate: u64 = self.state;
        // C++: state = oldstate * PCG32_MULT + inc;
        let (mul, _overflow) = oldstate.overflowing_mul(PCG32_MULT);
        let (add, _overflow) = mul.overflowing_add(self.inc);
        self.state = add;
        // C++: uint32_t xorshifted = (uint32_t)(((oldstate >> 18u) ^ oldstate) >> 27u);
        let (shr, _overflow) = oldstate.overflowing_shr(18);
        let combine = shr ^ oldstate;
        let (shr, _overflow) = combine.overflowing_shr(27);
        let xorshifted: u32 = shr as u32;
        // C++: uint32_t rot = (uint32_t)(oldstate >> 59u);
        let (shr, _overflow) = oldstate.overflowing_shr(59);
        let rot: u32 = shr as u32;
        // C++: return (xorshifted >> rot) | (xorshifted << ((~rot + 1u) & 31));
        let (shr, _overflow) = xorshifted.overflowing_shr(rot);
        // bitwise not in Rust is ! (not the ~ operator like in C)
        let neg = !rot;
        let (add, _overflow) = neg.overflowing_add(1_u32);
        let (shl, _overflow) = xorshifted.overflowing_shl(add & 31);
        shr | shl
    }
    pub fn uniform_uint32_bounded(&mut self, b: u32) -> u32 {
        // bitwise not in Rust is ! (not the ~ operator like in C)
        let threshold = (!b + 1) & b;
        loop {
            let r = self.uniform_uint32();
            if r >= threshold {
                return r % b;
            }
        }
    }
    pub fn uniform_float(&mut self) -> Float {
        //#ifndef PBRT_HAVE_HEX_FP_CONSTANTS
        // (self.uniform_uint32() as Float * 2.3283064365386963e-10 as Float)
        //     .min(FLOAT_ONE_MINUS_EPSILON)
        //#else
        (self.uniform_uint32() as Float * hexf32!("0x1.0p-32") as Float)
            .min(FLOAT_ONE_MINUS_EPSILON)
        //#endif
    }
}