use rand_state for rng
This commit is contained in:
parent
48999f5ab4
commit
b9530f6c7a
@ -22,7 +22,6 @@
|
||||
#include "math.h"
|
||||
#include "renderer.h"
|
||||
#include "phys.h"
|
||||
#include "rng.h"
|
||||
#include "sock.h"
|
||||
#include "host.h"
|
||||
#include "bitbuff.h"
|
||||
|
||||
60
src/rand.c
Normal file
60
src/rand.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include "rand.h"
|
||||
#include "sys.h"
|
||||
#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;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Stateful prng
|
||||
* ========================== */
|
||||
|
||||
u64 rand_u64_from_state(struct rand_state *state)
|
||||
{
|
||||
u64 res = state->seed;
|
||||
while (res == 0) {
|
||||
sys_true_rand(STRING_FROM_STRUCT(&res));
|
||||
}
|
||||
res = mix64(res);
|
||||
state->seed = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Seeded prng
|
||||
* ========================== */
|
||||
|
||||
u64 rand_u64_from_seed(u64 seed)
|
||||
{
|
||||
return mix64(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);
|
||||
}
|
||||
15
src/rand.h
Normal file
15
src/rand.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef RAND_H
|
||||
#define RAND_H
|
||||
|
||||
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 rand_u64_from_state(struct rand_state *state);
|
||||
f64 rand_f64_from_state(struct rand_state *state, f64 range_start, f64 range_end);
|
||||
|
||||
u64 rand_u64_from_seed(u64 seed);
|
||||
f64 rand_f64_from_seed(u64 seed, f64 range_start, f64 range_end);
|
||||
|
||||
#endif
|
||||
26
src/rng.c
26
src/rng.c
@ -1,26 +0,0 @@
|
||||
#include "rng.h"
|
||||
#include "sys.h"
|
||||
|
||||
u32 rng_true_u32(void)
|
||||
{
|
||||
u32 v = 0;
|
||||
sys_true_rand(STRING_FROM_STRUCT(&v));
|
||||
return v;
|
||||
}
|
||||
|
||||
u64 rng_true_u64(void)
|
||||
{
|
||||
u64 v = 0;
|
||||
sys_true_rand(STRING_FROM_STRUCT(&v));
|
||||
return v;
|
||||
}
|
||||
|
||||
f32 rng_true_f32(f32 range_start, f32 range_end)
|
||||
{
|
||||
return ((f32)rng_true_u32() / (f32)U32_MAX) * (range_end - range_start) + range_start;
|
||||
}
|
||||
|
||||
f64 rng_true_f64(f64 range_start, f64 range_end)
|
||||
{
|
||||
return ((f64)rng_true_u64() / (f64)U64_MAX) * (range_end - range_start) + range_start;
|
||||
}
|
||||
10
src/rng.h
10
src/rng.h
@ -1,10 +0,0 @@
|
||||
#ifndef RNG_H
|
||||
#define RNG_H
|
||||
|
||||
/* Rand */
|
||||
u32 rng_true_u32(void);
|
||||
u64 rng_true_u64(void);
|
||||
f32 rng_true_f32(f32 range_start, f32 range_end);
|
||||
f64 rng_true_f64(f64 range_start, f64 range_end);
|
||||
|
||||
#endif
|
||||
@ -269,7 +269,7 @@ struct sim_ent *sim_ent_from_id(struct sim_snapshot *ss, struct sim_ent_id id)
|
||||
struct sim_ent_id sim_ent_random_id(void)
|
||||
{
|
||||
struct sim_ent_id res = ZI;
|
||||
res.uid = uid_rand();
|
||||
res.uid = uid_true_rand();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
#include "log.h"
|
||||
#include "phys.h"
|
||||
#include "collider.h"
|
||||
#include "rng.h"
|
||||
#include "rand.h"
|
||||
#include "space.h"
|
||||
#include "bitbuff.h"
|
||||
#include "host.h"
|
||||
@ -74,7 +74,7 @@ INTERNAL void spawn_test_entities(struct sim_step_ctx *ctx, struct v2 offset)
|
||||
e->layer = SIM_LAYER_SHOULDERS;
|
||||
|
||||
sim_ent_enable_prop(e, SIM_ENT_PROP_PHYSICAL_DYNAMIC);
|
||||
e->mass_unscaled = 1;
|
||||
e->mass_unscaled = 10;
|
||||
e->inertia_unscaled = 10;
|
||||
e->linear_ground_friction = 250;
|
||||
e->angular_ground_friction = 200;
|
||||
@ -299,7 +299,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, st
|
||||
/* Create test blood */
|
||||
/* TODO: Remove this */
|
||||
{
|
||||
struct xform xf = XFORM_TRS(.t = point, .r = rng_true_f32(0, TAU));
|
||||
struct xform xf = XFORM_TRS(.t = point, .r = rand_f64_from_state(&step_ctx->rand, 0, TAU));
|
||||
struct sim_ent *decal = sim_ent_alloc_sync_src(root);
|
||||
decal->sprite = sprite_tag_from_path(LIT("res/graphics/blood.ase"));
|
||||
decal->sprite_tint = RGBA_32_F(1, 1, 1, 0.25f);
|
||||
@ -308,10 +308,10 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, st
|
||||
|
||||
f32 perp_range = 0.5;
|
||||
struct v2 linear_velocity = v2_mul(normal, 0.5);
|
||||
linear_velocity = v2_add(linear_velocity, v2_mul(v2_perp(normal), rng_true_f32(-perp_range, perp_range)));
|
||||
linear_velocity = v2_add(linear_velocity, v2_mul(v2_perp(normal), rand_f64_from_state(&step_ctx->rand, -perp_range, perp_range)));
|
||||
|
||||
f32 angular_velocity_range = 5;
|
||||
f32 angular_velocity = rng_true_f32(-angular_velocity_range, angular_velocity_range);
|
||||
f32 angular_velocity = rand_f64_from_seed(&step_ctx->rand, -angular_velocity_range, angular_velocity_range);
|
||||
|
||||
sim_ent_enable_prop(decal, SIM_ENT_PROP_PHYSICAL_KINEMATIC);
|
||||
sim_ent_set_linear_velocity(decal, linear_velocity);
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
#ifndef SIM_STEP_H
|
||||
#define SIM_STEP_H
|
||||
|
||||
#include "rand.h"
|
||||
|
||||
struct space;
|
||||
struct sim_snapshot;
|
||||
struct sim_snapshot_list;
|
||||
@ -27,6 +29,7 @@ void sim_accel_reset(struct sim_snapshot *ss, struct sim_accel *accel);
|
||||
struct sim_step_ctx {
|
||||
b32 is_master;
|
||||
struct sim_accel *accel;
|
||||
struct rand_state rand; /* TODO: Replace with per-sim rand for deterministic rng */
|
||||
|
||||
struct sim_snapshot *world; /* The world to simulate */
|
||||
i64 sim_dt_ns; /* How much sim time should progress */
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
#include "uid.h"
|
||||
#include "rand.h"
|
||||
#include "sys.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Returns a uid generated from the system's random number generator */
|
||||
struct uid uid_rand(void)
|
||||
struct uid uid_true_rand(void)
|
||||
{
|
||||
struct uid res = ZI;
|
||||
sys_true_rand(STRING_FROM_STRUCT(&res));
|
||||
@ -14,8 +14,7 @@ struct uid uid_rand(void)
|
||||
struct uid uid_combine(struct uid a, struct uid b)
|
||||
{
|
||||
struct uid res;
|
||||
/* Add bits of a+b to an arbitrary random constant (to prevent (a=0 + b=0) from returning a uid=0) */
|
||||
res.hi = 0x958d53b0e2fd8e3f + a.hi + b.hi;
|
||||
res.lo = 0x7038ffd46e0868c7 + a.lo + b.lo;
|
||||
res.hi = rand_u64_from_seed(a.hi + b.hi);
|
||||
res.lo = rand_u64_from_seed(a.lo + b.lo);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#ifndef UID_H
|
||||
#define UID_H
|
||||
|
||||
struct uid uid_rand(void);
|
||||
struct uid uid_true_rand(void);
|
||||
struct uid uid_combine(struct uid a, struct uid b);
|
||||
|
||||
#endif
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
#include "mixer.h"
|
||||
#include "atomic.h"
|
||||
#include "collider.h"
|
||||
#include "rng.h"
|
||||
#include "rand.h"
|
||||
#include "log.h"
|
||||
#include "sock.h"
|
||||
#include "host.h"
|
||||
@ -752,8 +752,8 @@ INTERNAL void user_update(void)
|
||||
if (shake > 0) {
|
||||
u64 angle_seed0 = ent->id.uid.lo + (u64)(G.ss_blended->sim_time_ns / frequency_ns);
|
||||
u64 angle_seed1 = angle_seed0 + 1;
|
||||
f32 angle0 = ((f32)mix64(angle_seed0) / (f32)U64_MAX) * TAU;
|
||||
f32 angle1 = ((f32)mix64(angle_seed1) / (f32)U64_MAX) * TAU;
|
||||
f32 angle0 = rand_f64_from_seed(angle_seed0, 0, TAU);
|
||||
f32 angle1 = rand_f64_from_seed(angle_seed1, 0, TAU);
|
||||
|
||||
struct v2 vec0 = v2_with_len(v2_from_angle(angle0), shake);
|
||||
/* NOTE: vec1 not completely accurate since shake can change between frames, just a prediction */
|
||||
|
||||
17
src/util.h
17
src/util.h
@ -30,23 +30,6 @@ INLINE u64 hash_fnv64(u64 seed, struct string s)
|
||||
return hash;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Bit mixing
|
||||
* ========================== */
|
||||
|
||||
/* Based on Jon Maiga's "mx3"
|
||||
* (https://jonkagstrom.com/mx3/mx3_rev2.html)
|
||||
*/
|
||||
|
||||
INLINE 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;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Merge sort
|
||||
* ========================== */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user