diff --git a/src/rand.c b/src/rand.c index 5c6e9374..510d2418 100644 --- a/src/rand.c +++ b/src/rand.c @@ -3,17 +3,8 @@ #include "memory.h" #include "thread_local.h" -/* Based on Jon Maiga's "mx3" - * (https://jonkagstrom.com/mx3/mx3_rev2.html) - */ -INTERNAL u64 mix64(u64 x) -{ - x = (x ^ (x >> 32)) * 0xbea225f9eb34556d; - x = (x ^ (x >> 29)) * 0xbea225f9eb34556d; - x = (x ^ (x >> 32)) * 0xbea225f9eb34556d; - x = (x ^ (x >> 29)); - return x; -} +/* TODO: Use a value that gives good precision when dividing into range 0 -> 1 */ +#define F64_RAND_MAX U64_MAX /* ========================== * * Stateful prng @@ -21,40 +12,36 @@ INTERNAL u64 mix64(u64 x) u64 rand_u64_from_state(struct rand_state *state) { - u64 res = state->seed; - while (res == 0) { - sys_true_rand(STRING_FROM_STRUCT(&res)); + u64 seed = state->seed; + if (seed == 0) { + sys_true_rand(STRING_FROM_STRUCT(&seed)); + state->seed = seed; } - res = mix64(res); - state->seed = res; - return res; + return seed ^ rand_u64_from_seed(++state->counter); } f64 rand_f64_from_state(struct rand_state *state, f64 range_start, f64 range_end) { - if (range_start > range_end) { - f64 swp = range_start; - range_start = range_end; - range_end = swp; - } - return range_start + ((f64)rand_u64_from_state(state) / (f64)U64_MAX) * (range_end - range_start); + return range_start + (range_end - range_start) * ((f64)(rand_u64_from_state(state) % F64_RAND_MAX) / (f64)F64_RAND_MAX); } /* ========================== * * Seeded prng * ========================== */ + /* Based on Jon Maiga's "mx3" + * https://jonkagstrom.com/mx3/mx3_rev2.html + */ u64 rand_u64_from_seed(u64 seed) { - return mix64(seed); + seed = (seed ^ (seed >> 32)) * 0xbea225f9eb34556d; + seed = (seed ^ (seed >> 29)) * 0xbea225f9eb34556d; + seed = (seed ^ (seed >> 32)) * 0xbea225f9eb34556d; + seed = (seed ^ (seed >> 29)); + return seed; } f64 rand_f64_from_seed(u64 seed, f64 range_start, f64 range_end) { - if (range_start > range_end) { - f64 swp = range_start; - range_start = range_end; - range_end = swp; - } - return range_start + ((f64)rand_u64_from_seed(seed) / (f64)U64_MAX) * (range_end - range_start); + return range_start + (range_end - range_start) * ((f64)(rand_u64_from_seed(seed) % F64_RAND_MAX) / (f64)F64_RAND_MAX); } diff --git a/src/rand.h b/src/rand.h index bdb97c1c..eae7d642 100644 --- a/src/rand.h +++ b/src/rand.h @@ -4,6 +4,7 @@ struct rand_state { /* If a state's seed = 0 upon a to a related function, it will be initialized using platform's true rng source */ u64 seed; + u64 counter; }; u64 rand_u64_from_state(struct rand_state *state); diff --git a/src/sim_ent.c b/src/sim_ent.c index 58183a34..1bea9734 100644 --- a/src/sim_ent.c +++ b/src/sim_ent.c @@ -584,24 +584,11 @@ void sim_ent_sync(struct sim_ent *local, struct sim_ent *remote) struct sim_ent old = *local; MEMCPY_STRUCT(local, remote); - - - - if (!MEMEQ_STRUCT(&old._xform, &remote->_xform)) { - DEBUGBREAKABLE; - } - - - - - - - - /* Why would 2 ents w/ different uids ever be synced? */ ASSERT(sim_ent_id_eq(local->id, old.id)); local->ss = old.ss; + local->id = old.id; /* Keep local tree */ local->parent = old.parent;