Index: trunk/src/core/random.cc
===================================================================
--- trunk/src/core/random.cc	(revision 487)
+++ trunk/src/core/random.cc	(revision 503)
@@ -19,5 +19,11 @@
 #define NV_MT_TWIST(u, v)  ( (NV_MT_MIXBITS(u, v) >> 1) ^ ( (v) & 1UL ? mt_matrix_a : 0UL) )
 
-void random::mt_init( uint32 seed )
+nv::random& random::get()
+{
+	static random default_rng;
+	return default_rng;
+}
+
+void random_mersenne::mt_init( uint32 seed )
 {
 	m_state[0] = static_cast<uint32>( seed & mt_full_mask );
@@ -34,5 +40,5 @@
 
 
-void random::mt_update()
+void random_mersenne::mt_update()
 {
 	uint32 *p = m_state;
@@ -51,5 +57,5 @@
 
 
-uint32 random::mt_uint32()
+uint32 random_mersenne::mt_uint32()
 {
 	uint32 r;
@@ -70,36 +76,22 @@
 }
 
-random::random( random::seed_type seed /*= 0 */ )
+random_mersenne::random_mersenne( random_mersenne::seed_type seed /*= 0 */ )
 	: m_next( nullptr ), m_remaining( 0 ), m_seeded( 0 )
 {
-	mt_init( seed == 0 ? randomized_seed() : seed );
-}
-
-random::seed_type random::set_seed( random::seed_type seed /*= 0 */ )
-{
-	if ( seed == 0 ) seed = randomized_seed();
+	mt_init( seed );
+}
+
+random_mersenne::seed_type random_mersenne::set_seed( random_mersenne::seed_type seed /*= 0 */ )
+{
 	mt_init( seed );
 	return seed;
 }
 
-nv::random& random::get()
-{
-	static random default_rng;
-	return default_rng;
-}
-
-random::result_type random::rand()
+random_mersenne::result_type random_mersenne::rand()
 {
 	return mt_uint32();
 }
 
-uint32 random::urand( uint32 val )
-{
-	uint32 x, max = mt_full_mask - ( mt_full_mask % val );
-	while ( ( x = rand() ) >= max );
-	return x / ( max / val );
-}
-
-random::seed_type random::randomized_seed()
+random_base::seed_type random_base::randomized_seed()
 {
 	// TODO: this seems off, as it might often seed the same, use general time 
@@ -108,5 +100,5 @@
 }
 
-nv::vec2 nv::random::precise_unit_vec2()
+nv::vec2 nv::random_base::precise_unit_vec2()
 {
 	f32 angle = frand( math::pi<f32>() * 2.f );
@@ -114,5 +106,5 @@
 }
 
-nv::vec3 nv::random::precise_unit_vec3()
+nv::vec3 nv::random_base::precise_unit_vec3()
 {
 	f32 cos_theta = frange( -1.0f, 1.0f );
@@ -126,5 +118,5 @@
 }
 
-nv::vec2 nv::random::fast_disk_point()
+nv::vec2 nv::random_base::fast_disk_point()
 {
 	f32 r1 = frand();
@@ -135,5 +127,5 @@
 }
 
-nv::vec2 nv::random::precise_disk_point()
+nv::vec2 nv::random_base::precise_disk_point()
 {
 	f32 r = sqrt( frand() );
@@ -142,5 +134,5 @@
 }
 
-nv::vec3 nv::random::fast_sphere_point()
+nv::vec3 nv::random_base::fast_sphere_point()
 {
 	f32 rad     = frand();
@@ -156,5 +148,5 @@
 }
 
-nv::vec3 nv::random::precise_sphere_point()
+nv::vec3 nv::random_base::precise_sphere_point()
 {
 	f32 radius = pow( frand(), 1.f/3.f );
@@ -169,5 +161,5 @@
 }
 
-nv::vec2 nv::random::precise_ellipse_point( const vec2& radii )
+nv::vec2 nv::random_base::precise_ellipse_point( const vec2& radii )
 {
 	vec2 p = range( -radii, radii );
@@ -184,5 +176,5 @@
 }
 
-nv::vec3 nv::random::precise_ellipsoid_point( const vec3& radii )
+nv::vec3 nv::random_base::precise_ellipsoid_point( const vec3& radii )
 {
 	vec3 p = range( -radii, radii );
@@ -199,5 +191,5 @@
 }
 
-nv::vec2 nv::random::fast_hollow_disk_point( f32 iradius, f32 oradius )
+nv::vec2 nv::random_base::fast_hollow_disk_point( f32 iradius, f32 oradius )
 {
 	f32 idist2 = iradius * iradius;
@@ -207,10 +199,10 @@
 }
 
-nv::vec2 nv::random::precise_hollow_disk_point( f32 iradius, f32 oradius )
+nv::vec2 nv::random_base::precise_hollow_disk_point( f32 iradius, f32 oradius )
 {
 	return fast_hollow_disk_point( iradius, oradius );
 }
 
-nv::vec3 nv::random::fast_hollow_sphere_point( f32 iradius, f32 oradius )
+nv::vec3 nv::random_base::fast_hollow_sphere_point( f32 iradius, f32 oradius )
 {
 	f32 idist3 = iradius * iradius * iradius;
@@ -220,5 +212,5 @@
 }
 
-nv::vec3 nv::random::precise_hollow_sphere_point( f32 iradius, f32 oradius )
+nv::vec3 nv::random_base::precise_hollow_sphere_point( f32 iradius, f32 oradius )
 {
 	return fast_hollow_sphere_point( iradius, oradius );
@@ -226,5 +218,5 @@
 
 
-nv::vec2 nv::random::fast_hollow_ellipse_point( const vec2& iradii, const vec2& oradii )
+nv::vec2 nv::random_base::fast_hollow_ellipse_point( const vec2& iradii, const vec2& oradii )
 {
 	vec2 iradii2 = iradii * iradii;
@@ -241,10 +233,10 @@
 }
 
-nv::vec2 nv::random::precise_hollow_ellipse_point( const vec2& iradii, const vec2& oradii )
+nv::vec2 nv::random_base::precise_hollow_ellipse_point( const vec2& iradii, const vec2& oradii )
 {
 	return fast_hollow_ellipse_point( iradii, oradii );
 }
 
-nv::vec3 nv::random::fast_hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii )
+nv::vec3 nv::random_base::fast_hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii )
 {
 	vec3 iradii2 = iradii * iradii;
@@ -267,7 +259,32 @@
 }
 
-nv::vec3 nv::random::precise_hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii )
+nv::vec3 nv::random_base::precise_hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii )
 {
 	return fast_hollow_ellipsoid_point( iradii, oradii );
 }
 
+nv::random_xor128::random_xor128( seed_type seed /*= randomized_seed() */ )
+{
+	set_seed( seed );
+}
+
+nv::random_base::seed_type nv::random_xor128::set_seed( seed_type seed /*= 0 */ )
+{
+	uint32 s = 4294967296 - seed;
+	m_state[0] = 123456789 * s;
+	m_state[1] = 362436069 * s;
+	m_state[2] = 521288629 * s;
+	m_state[3] = 88675123 * s;
+	return seed;
+}
+
+nv::random_base::result_type nv::random_xor128::rand()
+{
+	uint32 t = m_state[0];
+	t ^= t << 11;
+	t ^= t >> 8;
+	m_state[0] = m_state[1]; m_state[1] = m_state[2]; m_state[2] = m_state[3];
+	m_state[3] ^= m_state[3] >> 19;
+	m_state[3] ^= t;
+	return m_state[3];
+}
