allow seperate random instances
authorhgn <hgodden00@gmail.com>
Sun, 10 Dec 2023 17:24:44 +0000 (17:24 +0000)
committerhgn <hgodden00@gmail.com>
Sun, 10 Dec 2023 17:24:44 +0000 (17:24 +0000)
vg.h
vg_m.h

diff --git a/vg.h b/vg.h
index 3ce5a462642ab62d75b89735d330df670239a9c9..04578f7c81a5c7c53bef107079a6642cb180cf36 100644 (file)
--- 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 91071ffb163d1b38617679c938bf68a7ba5bc590..68e2304a339c13013eae62c3dd3644a62ae6118e 100644 (file)
--- 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.index<MT_STATE_VECTOR_LENGTH; vg_rand.index++){
-      vg_rand.mt[vg_rand.index] = 
-         (6069 * vg_rand.mt[vg_rand.index-1]) & 0xffffffff;
+   rand->mt[0] = seed & 0xffffffff;
+   for( rand->index=1; rand->index<MT_STATE_VECTOR_LENGTH; rand->index++){
+      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<MT_STATE_VECTOR_LENGTH-MT_STATE_VECTOR_M; kk++ ){
-         y = (vg_rand.mt[kk] & MT_UPPER_MASK) | 
-             (vg_rand.mt[kk+1] & MT_LOWER_MASK);
-         vg_rand.mt[kk] = vg_rand.mt[kk+MT_STATE_VECTOR_M] ^ 
-                           (y >> 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( ; kk<MT_STATE_VECTOR_LENGTH-1; kk++ ){
-         y = (vg_rand.mt[kk] & MT_UPPER_MASK) | 
-             (vg_rand.mt[kk+1] & MT_LOWER_MASK);
-         vg_rand.mt[kk] = 
-            vg_rand.mt[ kk+(MT_STATE_VECTOR_M-MT_STATE_VECTOR_LENGTH)] ^ 
+         y = (rand->mt[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);