From: hgn Date: Sun, 10 Dec 2023 17:24:44 +0000 (+0000) Subject: allow seperate random instances X-Git-Url: https://harrygodden.com/git/?p=vg.git;a=commitdiff_plain;h=7a1b2ba3172f9f296df110997e5b8cca5f10ab68 allow seperate random instances --- diff --git a/vg.h b/vg.h index 3ce5a46..04578f7 100644 --- a/vg.h +++ b/vg.h @@ -175,6 +175,8 @@ struct vg{ float loader_ring; GLuint tex_missing; + + vg_rand rand; } static vg = { .time_rate = 1.0 }; const char *vg_get_basepath(void){ @@ -842,9 +844,8 @@ static void _vg_terminate(void) exit(0); } -static void vg_enter( int argc, char *argv[], const char *window_name ) -{ - vg_rand_seed( 461 ); +static void vg_enter( int argc, char *argv[], const char *window_name ){ + vg_rand_seed( &vg.rand, 461 ); _vg_process_launch_opts_internal( argc, argv ); /* Systems init */ diff --git a/vg_m.h b/vg_m.h index 91071ff..68e2304 100644 --- a/vg_m.h +++ b/vg_m.h @@ -132,6 +132,16 @@ static f32 vg_dequantf( u32 q, u32 bits, f32 min, f32 max ){ return min + (f32)q * ((max-min) / (f32)mask); } +/* https://iquilezles.org/articles/functions/ + * + * Use k to control the stretching of the function. Its maximum, which is 1, + * happens at exactly x = 1/k. + */ +static f32 vg_exp_impulse( f32 x, f32 k ){ + f32 h = k*x; + return h*expf(1.0f-h); +} + /* * ----------------------------------------------------------------------------- * Section 2.a 2D Vectors @@ -2267,57 +2277,55 @@ static float vg_sphere_volume( float radius ){ /* changes to STATE_VECTOR_LENGTH also require changes to this */ #define MT_STATE_VECTOR_M 397 -struct { +typedef struct vg_rand vg_rand; +struct vg_rand { u32 mt[MT_STATE_VECTOR_LENGTH]; i32 index; -} -static vg_rand; +}; -static void vg_rand_seed( unsigned long seed ) { +static void vg_rand_seed( vg_rand *rand, unsigned long seed ) { /* set initial seeds to mt[STATE_VECTOR_LENGTH] using the generator * from Line 25 of Table 1 in: Donald Knuth, "The Art of Computer * Programming," Vol. 2 (2nd Ed.) pp.102. */ - vg_rand.mt[0] = seed & 0xffffffff; - for( vg_rand.index=1; vg_rand.indexmt[0] = seed & 0xffffffff; + for( rand->index=1; rand->indexindex++){ + rand->mt[rand->index] = (6069 * rand->mt[rand->index-1]) & 0xffffffff; } } /* * Generates a pseudo-randomly generated long. */ -static u32 vg_randu32(void) { +static u32 vg_randu32( vg_rand *rand ) { u32 y; /* mag[x] = x * 0x9908b0df for x = 0,1 */ static u32 mag[2] = {0x0, 0x9908b0df}; - if( vg_rand.index >= MT_STATE_VECTOR_LENGTH || vg_rand.index < 0 ){ + if( rand->index >= MT_STATE_VECTOR_LENGTH || rand->index < 0 ){ /* generate STATE_VECTOR_LENGTH words at a time */ int kk; - if( vg_rand.index >= MT_STATE_VECTOR_LENGTH+1 || vg_rand.index < 0 ){ - vg_rand_seed( 4357 ); + if( rand->index >= MT_STATE_VECTOR_LENGTH+1 || rand->index < 0 ){ + vg_rand_seed( rand, 4357 ); } for( kk=0; kk> 1) ^ mag[y & 0x1]; + y = (rand->mt[kk] & MT_UPPER_MASK) | + (rand->mt[kk+1] & MT_LOWER_MASK); + rand->mt[kk] = rand->mt[kk+MT_STATE_VECTOR_M] ^ (y>>1) ^ mag[y & 0x1]; } for( ; kkmt[kk] & MT_UPPER_MASK) | + (rand->mt[kk+1] & MT_LOWER_MASK); + rand->mt[kk] = + rand->mt[ kk+(MT_STATE_VECTOR_M-MT_STATE_VECTOR_LENGTH)] ^ (y >> 1) ^ mag[y & 0x1]; } - y = (vg_rand.mt[MT_STATE_VECTOR_LENGTH-1] & MT_UPPER_MASK) | - (vg_rand.mt[0] & MT_LOWER_MASK); - vg_rand.mt[MT_STATE_VECTOR_LENGTH-1] = - vg_rand.mt[MT_STATE_VECTOR_M-1] ^ (y >> 1) ^ mag[y & 0x1]; - vg_rand.index = 0; + y = (rand->mt[MT_STATE_VECTOR_LENGTH-1] & MT_UPPER_MASK) | + (rand->mt[0] & MT_LOWER_MASK); + rand->mt[MT_STATE_VECTOR_LENGTH-1] = + rand->mt[MT_STATE_VECTOR_M-1] ^ (y >> 1) ^ mag[y & 0x1]; + rand->index = 0; } - y = vg_rand.mt[vg_rand.index++]; + y = rand->mt[rand->index++]; y ^= (y >> 11); y ^= (y << 7) & MT_TEMPERING_MASK_B; y ^= (y << 15) & MT_TEMPERING_MASK_C; @@ -2328,18 +2336,18 @@ static u32 vg_randu32(void) { /* * Generates a pseudo-randomly generated f64 in the range [0..1]. */ -static inline f64 vg_randf64(void){ - return (f64)vg_randu32()/(f64)0xffffffff; +static inline f64 vg_randf64( vg_rand *rand ){ + return (f64)vg_randu32(rand)/(f64)0xffffffff; } -static inline f64 vg_randf64_range( f64 min, f64 max ){ - return vg_lerp( min, max, (f64)vg_randf64() ); +static inline f64 vg_randf64_range( vg_rand *rand, f64 min, f64 max ){ + return vg_lerp( min, max, (f64)vg_randf64(rand) ); } -static inline void vg_rand_dir( v3f dir ){ - dir[0] = vg_randf64(); - dir[1] = vg_randf64(); - dir[2] = vg_randf64(); +static inline void vg_rand_dir( vg_rand *rand, v3f dir ){ + dir[0] = vg_randf64(rand); + dir[1] = vg_randf64(rand); + dir[2] = vg_randf64(rand); /* warning: *could* be 0 length. * very unlikely.. 1 in (2^32)^3. but its mathematically wrong. */ @@ -2350,21 +2358,21 @@ static inline void vg_rand_dir( v3f dir ){ v3_normalize( dir ); } -static inline void vg_rand_sphere( v3f co ){ - vg_rand_dir(co); - v3_muls( co, cbrtf( vg_randf64() ), co ); +static inline void vg_rand_sphere( vg_rand *rand, v3f co ){ + vg_rand_dir(rand,co); + v3_muls( co, cbrtf( vg_randf64(rand) ), co ); } -static void vg_rand_disc( v2f co ){ - f32 a = vg_randf64() * VG_TAUf; +static void vg_rand_disc( vg_rand *rand, v2f co ){ + f32 a = vg_randf64(rand) * VG_TAUf; co[0] = sinf(a); co[1] = cosf(a); - v2_muls( co, sqrtf( vg_randf64() ), co ); + v2_muls( co, sqrtf( vg_randf64(rand) ), co ); } -static void vg_rand_cone( v3f out_dir, f32 angle ){ - f32 r = sqrtf(vg_randf64()) * angle * 0.5f, - a = vg_randf64() * VG_TAUf; +static void vg_rand_cone( vg_rand *rand, v3f out_dir, f32 angle ){ + f32 r = sqrtf(vg_randf64(rand)) * angle * 0.5f, + a = vg_randf64(rand) * VG_TAUf; out_dir[0] = sinf(a) * sinf(r); out_dir[1] = cosf(a) * sinf(r);