/*
 * PBrtJ -- Port of pbrt v3 to Java.
 * Copyright (c) 2017 Rick Weyrauch.
 *
 * pbrt source code is Copyright(c) 1998-2016
 * Matt Pharr, Greg Humphreys, and Wenzel Jakob.
 *
 */

package org.pbrt.core;

public class RNG {
    // RNG Private Data
    private long state, inc;

    public static final double DoubleOneMinusEpsilon = 0x1.fffffffffffffp-1;
    public static final float FloatOneMinusEpsilon = 0x1.fffffep-1f;

    private static final long PCG32_DEFAULT_STATE = 0x853c49e6748fea9bL;
    private static final long PCG32_DEFAULT_STREAM = 0xda3e39cb94b95bdbL;
    private static final long PCG32_MULT = 0x5851f42d4c957f2dL;

    // RNG Public Methods
    public RNG() {
        this.state = PCG32_DEFAULT_STATE;
        this.inc = PCG32_DEFAULT_STREAM;
    }
    public RNG(long sequenceIndex) {
        SetSequence(sequenceIndex);
    }
    public void SetSequence(long sequenceIndex) {
        state = 0;
        inc = (sequenceIndex << 1) | 1;
        UniformInt32();
        state += PCG32_DEFAULT_STATE;
        UniformInt32();
    }
    public int UniformInt32() {
        long oldstate = state;
        state = oldstate * PCG32_MULT + inc;
        long xorshifted = ((oldstate >> 18) ^ oldstate) >> 27;
        int rot = (int)(oldstate >> 59);
        return (int)(xorshifted >> rot) | (int)(xorshifted << ((~rot + 1) & 31));
    }
    public int UniformInt32(int b) {
        int threshold = (~b + 1) % b;
        while (true) {
            int r = UniformInt32();
            if (r >= threshold) return r % b;
        }
    }
    public float UniformFloat() {
        return Math.min(Pbrt.OneMinusEpsilon, ((float)UniformInt32() * 0x1p-32f));
    }

    public void Advance(long idelta) {
        long cur_mult = PCG32_MULT, cur_plus = inc, acc_mult = 1,
                acc_plus = 0, delta = idelta;
        while (delta > 0) {
            if ((delta & 1) != 0) {
                acc_mult *= cur_mult;
                acc_plus = acc_plus * cur_mult + cur_plus;
            }
            cur_plus = (cur_mult + 1) * cur_plus;
            cur_mult *= cur_mult;
            delta /= 2;
        }
        state = acc_mult * state + acc_plus;
    }

    public long subtract(RNG other) {
        assert (inc == other.inc);
        long cur_mult = PCG32_MULT, cur_plus = inc, cur_state = other.state,
                the_bit = 1, distance = 0;
        while (state != cur_state) {
            if ((state & the_bit) != (cur_state & the_bit)) {
                cur_state = cur_state * cur_mult + cur_plus;
                distance |= the_bit;
            }
            assert ((state & the_bit) == (cur_state & the_bit));
            the_bit <<= 1;
            cur_plus = (cur_mult + 1) * cur_plus;
            cur_mult *= cur_mult;
        }
        return distance;
    }

}
@@ -204,78 +204,79 @@
 e;%0A%0A
-public class RNG %7B%0A    // RNG Private Data%0A    private long state, inc
+import java.util.Random;%0A%0Apublic class RNG %7B%0A%0A    private Random random
 ;%0A%0A 
@@ -498,273 +498,107 @@
 bL;%0A
-    private static final long PCG32_DEFAULT_STREAM = 0xda3e39cb94b95bdbL;%0A    private static final long PCG32_MULT = 0x5851f42d4c957f2dL;%0A%0A    // RNG Public Methods%0A    public RNG() %7B%0A        this.state = PCG32_DEFAULT_STATE;%0A        this.inc = PCG32_DEFAULT_STREAM
+%0A    // RNG Public Methods%0A    public RNG() %7B%0A        this.random = new Random(PCG32_DEFAULT_STATE)
 ;%0A  
@@ -646,27 +646,40 @@
         
-SetSequence
+this.random = new Random
 (sequenc
@@ -755,1886 +755,297 @@
     
-state = 0;%0A        inc = (sequenceIndex %3C%3C 1) %7C 1;%0A        UniformInt32();%0A        state += PCG32_DEFAULT_STATE;%0A        UniformInt32();%0A    %7D%0A    public int UniformInt32() %7B%0A        long oldstate = state;%0A        state = oldstate * PCG32_MULT + inc;%0A        long xorshifted = ((oldstate %3E%3E 18) %5E oldstate) %3E%3E 27;%0A        int rot = (int)(oldstate %3E%3E 59);%0A        return (int)(xorshifted %3E%3E rot) %7C (int)(xorshifted %3C%3C ((~rot + 1) & 31));%0A    %7D%0A    public int UniformInt32(int b) %7B%0A        int threshold = (~b + 1) %25 b;%0A        while (true) %7B%0A            int r = UniformInt32();%0A            if (r %3E= threshold) return r %25 b;%0A        %7D%0A    %7D%0A    public float UniformFloat() %7B%0A        return Math.min(Pbrt.OneMinusEpsilon, ((float)UniformInt32() * 0x1p-32f));%0A    %7D%0A%0A    public void Advance(long idelta) %7B%0A        long cur_mult = PCG32_MULT, cur_plus = inc, acc_mult = 1,%0A                acc_plus = 0, delta = idelta;%0A        while (delta %3E 0) %7B%0A            if ((delta & 1) != 0) %7B%0A                acc_mult *= cur_mult;%0A                acc_plus = acc_plus * cur_mult + cur_plus;%0A            %7D%0A            cur_plus = (cur_mult + 1) * cur_plus;%0A            cur_mult *= cur_mult;%0A            delta /= 2;%0A        %7D%0A        state = acc_mult * state + acc_plus;%0A    %7D%0A%0A    public long subtract(RNG other) %7B%0A        assert (inc == other.inc);%0A        long cur_mult = PCG32_MULT, cur_plus = inc, cur_state = other.state,%0A                the_bit = 1, distance = 0;%0A        while (state != cur_state) %7B%0A            if ((state & the_bit) != (cur_state & the_bit)) %7B%0A                cur_state = cur_state * cur_mult + cur_plus;%0A                distance %7C= the_bit;%0A            %7D%0A            assert ((state & the_bit) == (cur_state & the_bit));%0A            the_bit %3C%3C= 1;%0A            cur_plus = (cur_mult + 1) * cur_plus;%0A            cur_mult *= cur_mult;%0A        %7D%0A        return distance;%0A    %7D%0A
+random.setSeed(sequenceIndex);%0A    %7D%0A    public int UniformInt32() %7B%0A        return random.nextInt();%0A    %7D%0A    public int UniformInt32(int b) %7B%0A        return random.nextInt(b);%0A    %7D%0A    public float UniformFloat() %7B%0A        return Math.min(Pbrt.OneMinusEpsilon, random.nextFloat());%0A    %7D
 %0A%7D

Use Java Random implementation for RNG for now.