diff --git a/src/phys.c b/src/phys.c index ecea8596..ce96c8b8 100644 --- a/src/phys.c +++ b/src/phys.c @@ -4,6 +4,7 @@ #include "math.h" #include "scratch.h" #include "space.h" +#include "uid.h" GLOBAL struct { /* Constants */ @@ -46,10 +47,6 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a res.a = arena_dry_push(arena, struct phys_collision_data); struct sim_snapshot *ss = ctx->sim_step_ctx->world; struct space *space = ctx->sim_step_ctx->accel->space; - struct sim_lookup *contact_lookup = &ctx->sim_step_ctx->accel->contact_lookup; -#if COLLIDER_DEBUG - struct sim_lookup *debug_lookup = ctx->collision_debug_lookup; -#endif struct sim_ent *root = sim_ent_from_handle(ss, SIM_ENT_ROOT_HANDLE); u64 tick = ss->tick; @@ -96,23 +93,15 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a e1_collider = check0_collider; } - struct sim_lookup_key key = sim_lookup_key_from_two_handles(e0->handle, e1->handle); - struct sim_lookup_entry *constraint_entry = sim_lookup_get(contact_lookup, key); + struct uid constraint_uid = uid_combine(uid_combine(SIM_ENT_BASIS_UID_CONTACT, e0->uid), e1->uid); + struct sim_ent *constraint_ent = sim_ent_from_uid(ss, constraint_uid); - struct sim_ent *constraint_ent = sim_ent_nil(); - if (constraint_entry) { - constraint_ent = sim_ent_from_handle(ss, constraint_entry->ent); - if (sim_ent_is_valid_and_active(constraint_ent)) { - if (constraint_ent->contact_constraint_data.last_phys_iteration >= phys_iteration) { - /* Already processed constraint this iteration */ - continue; - } else { - constraint_ent->contact_constraint_data.last_phys_iteration = phys_iteration; - } + if (constraint_ent->valid) { + if (constraint_ent->contact_constraint_data.last_phys_iteration >= phys_iteration) { + /* Already processed constraint this iteration */ + continue; } else { - /* Constraint ent no longer valid, delete constraint_entry*/ - sim_lookup_remove(contact_lookup, constraint_entry); - constraint_entry= NULL; + constraint_ent->contact_constraint_data.last_phys_iteration = phys_iteration; } } @@ -125,10 +114,10 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a struct phys_contact_constraint *constraint = NULL; if (collider_res.num_points > 0) { - if (!sim_ent_is_valid_and_active(constraint_ent)) { + if (!constraint_ent->valid) { /* Create constraint */ { - constraint_ent = sim_ent_alloc_local(root); + constraint_ent = sim_ent_alloc_local_with_uid(root, constraint_uid); constraint_ent->contact_constraint_data.e1 = e1->handle; constraint_ent->contact_constraint_data.e0 = e0->handle; constraint_ent->contact_constraint_data.skip_solve = sim_ent_has_prop(e0, SIM_ENT_PROP_SENSOR) || sim_ent_has_prop(e1, SIM_ENT_PROP_SENSOR) @@ -138,8 +127,6 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a /* TODO: Should we recalculate normal as more contact points are added? */ sim_ent_enable_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT); sim_ent_activate(constraint_ent, tick); - ASSERT(!constraint_entry); /* Existing entry should never be present here */ - sim_lookup_set(contact_lookup, key, constraint_ent->handle); } /* Push collision data */ @@ -284,7 +271,6 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration) { __prof; struct sim_snapshot *ss = ctx->sim_step_ctx->world; - struct sim_lookup *contact_lookup = &ctx->sim_step_ctx->accel->contact_lookup; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { struct sim_ent *constraint_ent = &ss->ents[sim_ent_index]; @@ -364,14 +350,6 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration) constraint_ent->contact_constraint_data.num_points = 0; sim_ent_disable_prop(constraint_ent, SIM_ENT_PROP_ACTIVE); sim_ent_enable_prop(constraint_ent, SIM_ENT_PROP_RELEASE); - /* Remove from lookup */ - struct sim_lookup_key key = sim_lookup_key_from_two_handles(constraint->e0, constraint->e1); - struct sim_lookup_entry *entry = sim_lookup_get(contact_lookup, key); - if (entry) { - sim_lookup_remove(contact_lookup, entry); - } else { - ASSERT(false); /* This should always exist */ - } } } diff --git a/src/rng.c b/src/rng.c index e9f52ed5..0fcce607 100644 --- a/src/rng.c +++ b/src/rng.c @@ -78,13 +78,6 @@ u128 rng_rand_u128(void) return v; } -struct uid rng_rand_uid(void) -{ - u128 v = 0; - sys_rand(STRING_FROM_STRUCT(&v)); - return (struct uid) { .v = v }; -} - f32 rng_rand_f32(f32 range_start, f32 range_end) { return ((f32)rng_rand_u32() / (f32)U32_MAX) * (range_end - range_start) + range_start; diff --git a/src/rng.h b/src/rng.h index 20d2922b..6bfc84f0 100644 --- a/src/rng.h +++ b/src/rng.h @@ -11,7 +11,6 @@ struct rng_startup_receipt rng_startup(struct resource_startup_receipt *resource u32 rng_rand_u32(void); u64 rng_rand_u64(void); u128 rng_rand_u128(void); -struct uid rng_rand_uid(void); f32 rng_rand_f32(f32 range_start, f32 range_end); f64 rng_rand_f64(f64 range_start, f64 range_end); diff --git a/src/sim.h b/src/sim.h index 858cb1f7..d808b35f 100644 --- a/src/sim.h +++ b/src/sim.h @@ -3,6 +3,9 @@ #define SIM_CLIENT_NIL_HANDLE ((struct sim_client_handle) { .gen = 0, .idx = 0 }) +/* UID magic number bases (to be used in conjunction with random UIDs in deterministic UID combinations) */ +#define SIM_ENT_BASIS_UID_CONTACT (UID(0x6a2a5d2dbecf534f, 0x0a8ca7c372a015af)) + /* Absolute layers */ #define SIM_LAYER_FLOOR_DECALS (-300) #define SIM_LAYER_BULLETS (-200) diff --git a/src/sim_ent.c b/src/sim_ent.c index d5700e7c..9f798b23 100644 --- a/src/sim_ent.c +++ b/src/sim_ent.c @@ -2,7 +2,7 @@ #include "sim.h" #include "math.h" #include "bitbuff.h" -#include "rng.h" +#include "uid.h" /* ========================== * * Ent allocation @@ -40,7 +40,19 @@ struct sim_ent *sim_ent_alloc_local(struct sim_ent *parent) struct sim_ent *e = sim_ent_alloc_raw(ss); sim_ent_link_parent(e, parent); - sim_ent_set_uid(e, rng_rand_uid()); + sim_ent_set_uid(e, uid_rand()); + + return e; +} + +struct sim_ent *sim_ent_alloc_local_with_uid(struct sim_ent *parent, struct uid uid) +{ + ASSERT(parent->valid); + struct sim_snapshot *ss = parent->ss; + struct sim_ent *e = sim_ent_alloc_raw(ss); + sim_ent_link_parent(e, parent); + + sim_ent_set_uid(e, uid); return e; } @@ -52,7 +64,7 @@ struct sim_ent *sim_ent_alloc_sync_src(struct sim_ent *parent) struct sim_ent *e = sim_ent_alloc_raw(ss); sim_ent_link_parent(e, parent); - sim_ent_set_uid(e, rng_rand_uid()); + sim_ent_set_uid(e, uid_rand()); sim_ent_enable_prop(e, SIM_ENT_PROP_SYNC_SRC); e->sync_src_client = ss->client->handle; @@ -105,6 +117,17 @@ void sim_ent_release(struct sim_ent *ent) sim_ent_release_raw(ent); } +/* ========================== * + * Activate + * ========================== */ + +void sim_ent_activate(struct sim_ent *ent, u64 current_tick) +{ + sim_ent_enable_prop(ent, SIM_ENT_PROP_ACTIVE); + ent->activation_tick = current_tick; + ++ent->continuity_gen; +} + /* ========================== * * Uid * ========================== */ @@ -115,18 +138,13 @@ INLINE u64 hash_from_uid(struct uid uid) return uid.lo; } -struct uid sim_ent_get_uid(struct sim_ent *ent) -{ - return ent->_uid; -} - void sim_ent_set_uid(struct sim_ent *ent, struct uid uid) { struct sim_snapshot *ss = ent->ss; struct sim_ent_bucket *buckets = ss->uid_buckets; u64 num_uid_buckets = ss->num_uid_buckets; - struct uid old_uid = ent->_uid; + struct uid old_uid = ent->uid; /* Release old from lookup */ if (!uid_eq(old_uid, UID0)) { @@ -137,7 +155,7 @@ void sim_ent_set_uid(struct sim_ent *ent, struct uid uid) struct sim_ent *e = sim_ent_from_handle(ss, bucket->first); while (e->valid) { next = sim_ent_from_handle(ss, e->next_in_uid_bucket); - if (uid_eq(e->_uid, old_uid)) { + if (uid_eq(e->uid, old_uid)) { break; } prev = e; @@ -171,7 +189,7 @@ void sim_ent_set_uid(struct sim_ent *ent, struct uid uid) bucket->last = ent->handle; } - ent->_uid = uid; + ent->uid = uid; } struct sim_ent *sim_ent_from_uid(struct sim_snapshot *ss, struct uid uid) @@ -182,7 +200,7 @@ struct sim_ent *sim_ent_from_uid(struct sim_snapshot *ss, struct uid uid) u64 hash = hash_from_uid(uid); struct sim_ent_bucket *bucket = &ss->uid_buckets[hash % num_buckets]; for (struct sim_ent *e = sim_ent_from_handle(ss, bucket->first); e->valid; e = sim_ent_from_handle(ss, e->next_in_uid_bucket)) { - if (uid_eq(e->_uid, uid)) { + if (uid_eq(e->uid, uid)) { res = e; break; } @@ -303,17 +321,6 @@ void sim_ent_unlink_from_parent(struct sim_ent *ent) ent->next = sim_ent_nil()->handle; } -/* ========================== * - * Activate - * ========================== */ - -void sim_ent_activate(struct sim_ent *ent, u64 current_tick) -{ - sim_ent_enable_prop(ent, SIM_ENT_PROP_ACTIVE); - ent->activation_tick = current_tick; - ++ent->continuity_gen; -} - /* ========================== * * Ent xform * ========================== */ @@ -530,7 +537,7 @@ void sim_ent_decode(struct bitbuff_reader *br, struct sim_ent *e) { struct sim_snapshot *ss = e->ss; - struct uid old_uid = sim_ent_get_uid(e); + struct uid old_uid = e->uid; u64 pos = 0; while (pos < sizeof(*e)) { @@ -543,8 +550,8 @@ void sim_ent_decode(struct bitbuff_reader *br, struct sim_ent *e) pos += 8; } - struct uid new_uid = sim_ent_get_uid(e); - e->_uid = old_uid; + struct uid new_uid = e->uid; + e->uid = old_uid; if (!uid_eq(old_uid, new_uid)) { sim_ent_set_uid(e, new_uid); } diff --git a/src/sim_ent.h b/src/sim_ent.h index db95355f..4db0ac05 100644 --- a/src/sim_ent.h +++ b/src/sim_ent.h @@ -67,11 +67,7 @@ struct sim_ent { b32 valid; /* Is this ent allocated in memory that can be written to (can always be read) */ struct sim_ent_handle handle; - - /* The unique ID of the entity determined at allocation time. - * Mainly used for networking. - * Use uid getter to access. */ - struct uid _uid; + struct uid uid; u64 props[(SIM_ENT_PROP_COUNT + 63) / 64]; u64 continuity_gen; @@ -398,15 +394,18 @@ INLINE b32 sim_ent_is_valid_and_active(struct sim_ent *ent) /* Alloc */ struct sim_ent *sim_ent_alloc_raw(struct sim_snapshot *ss); struct sim_ent *sim_ent_alloc_local(struct sim_ent *parent); +struct sim_ent *sim_ent_alloc_local_with_uid(struct sim_ent *parent, struct uid uid); struct sim_ent *sim_ent_alloc_sync_src(struct sim_ent *parent); struct sim_ent *sim_ent_alloc_sync_dst(struct sim_ent *parent, struct sim_client_handle client_handle, struct uid uid); void sim_ent_release_raw(struct sim_ent *ent); void sim_ent_release(struct sim_ent *ent); +/* Activate */ +void sim_ent_activate(struct sim_ent *ent, u64 current_tick); + /* Uid */ -struct uid sim_ent_get_uid(struct sim_ent *ent); void sim_ent_set_uid(struct sim_ent *ent, struct uid uid); struct sim_ent *sim_ent_from_uid(struct sim_snapshot *ss, struct uid uid); @@ -419,9 +418,6 @@ struct sim_ent *sim_ent_find_first_match_all(struct sim_snapshot *ss, struct sim void sim_ent_link_parent(struct sim_ent *parent, struct sim_ent *child); void sim_ent_unlink_from_parent(struct sim_ent *ent); -/* Activate */ -void sim_ent_activate(struct sim_ent *ent, u64 current_tick); - /* Xform */ struct xform sim_ent_get_xform(struct sim_ent *ent); struct xform sim_ent_get_local_xform(struct sim_ent *ent); diff --git a/src/sim_step.c b/src/sim_step.c index d6faefa4..42ce92b7 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -124,16 +124,6 @@ void sim_lookup_remove(struct sim_lookup *l, struct sim_lookup_entry *entry) l->first_free_entry = entry; } -struct sim_lookup_key sim_lookup_key_from_two_handles(struct sim_ent_handle h0, struct sim_ent_handle h1) -{ - struct sim_lookup_key key = ZI; - struct string b0 = STRING_FROM_STRUCT(&h0); - struct string b1 = STRING_FROM_STRUCT(&h1); - key.hash = hash_fnv64(HASH_FNV64_BASIS, b0); - key.hash = hash_fnv64(key.hash, b1); - return key; -} - /* ========================== * * Sim accel * ========================== */ @@ -142,19 +132,11 @@ struct sim_accel sim_accel_alloc(void) { struct sim_accel accel = ZI; accel.space = space_alloc(1, 256); - accel.contact_lookup = sim_lookup_alloc(4096); -#if COLLIDER_DEBUG - accel.collision_debug_lookup = sim_lookup_alloc(4096); -#endif return accel; } void sim_accel_release(struct sim_accel *accel) { -#if COLLIDER_DEBUG - sim_lookup_release(&accel->collision_debug_lookup); -#endif - sim_lookup_release(&accel->contact_lookup); space_release(accel->space); } @@ -163,7 +145,6 @@ void sim_accel_rebuild(struct sim_snapshot *ss, struct sim_accel *accel) /* FIXME: Rebuild collision debug lookup */ space_reset(accel->space); - sim_lookup_reset(&accel->contact_lookup); /* Reset ent space handles */ for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { @@ -174,17 +155,6 @@ void sim_accel_rebuild(struct sim_snapshot *ss, struct sim_accel *accel) } /* NOTE: Not rebuilding space since it'll happen during phys step */ - - /* Rebuild lookup tables */ - for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *ent = &ss->ents[sim_ent_index]; - if (sim_ent_is_valid_and_active(ent)) { - if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) { - struct sim_lookup_key contact_lookup_key = sim_lookup_key_from_two_handles(ent->contact_constraint_data.e0, ent->contact_constraint_data.e1); - sim_lookup_set(&accel->contact_lookup, contact_lookup_key, ent->handle); - } - } - } } /* ========================== * diff --git a/src/sim_step.h b/src/sim_step.h index 5938b7d5..c0a0e61c 100644 --- a/src/sim_step.h +++ b/src/sim_step.h @@ -44,9 +44,6 @@ struct sim_lookup_entry *sim_lookup_get(struct sim_lookup *l, struct sim_lookup_ void sim_lookup_set(struct sim_lookup *l, struct sim_lookup_key key, struct sim_ent_handle handle); void sim_lookup_remove(struct sim_lookup *l, struct sim_lookup_entry *entry); - -struct sim_lookup_key sim_lookup_key_from_two_handles(struct sim_ent_handle h0, struct sim_ent_handle h1); - /* ========================== * * Sim accel * ========================== */ @@ -56,10 +53,6 @@ struct sim_lookup_key sim_lookup_key_from_two_handles(struct sim_ent_handle h0, struct sim_accel { struct space *space; - struct sim_lookup contact_lookup; -#if COLLIDER_DEBUG - struct sim_lookup collision_debug_lookup; -#endif }; struct sim_accel sim_accel_alloc(void); diff --git a/src/uid.c b/src/uid.c new file mode 100644 index 00000000..3573ecea --- /dev/null +++ b/src/uid.c @@ -0,0 +1,20 @@ +#include "uid.h" +#include "sys.h" +#include "util.h" + +/* Returns a uid generated from the system's random number generator */ +struct uid uid_rand(void) +{ + u128 v = 0; + sys_rand(STRING_FROM_STRUCT(&v)); + return (struct uid) { .v = v }; +} + +/* Returns the deterministic outcome of two uids formed into a new uid */ +struct uid uid_combine(struct uid a, struct uid b) +{ + struct uid res; + res.v = hash_fnv128(HASH_FNV128_BASIS, STRING_FROM_STRUCT(&a)); + res.v = hash_fnv128(res.v, STRING_FROM_STRUCT(&b)); + return res; +} diff --git a/src/uid.h b/src/uid.h new file mode 100644 index 00000000..1dd5e2b7 --- /dev/null +++ b/src/uid.h @@ -0,0 +1,7 @@ +#ifndef UID_H +#define UID_H + +struct uid uid_rand(void); +struct uid uid_combine(struct uid a, struct uid b); + +#endif diff --git a/src/user.c b/src/user.c index af5237de..8fcd8fc6 100644 --- a/src/user.c +++ b/src/user.c @@ -351,7 +351,7 @@ INTERNAL struct string get_ent_debug_text(struct arena *arena, struct sim_ent *e res.len += string_format(arena, LIT("<%F>"), FMT_HANDLE(ent->handle)).len; /* TODO: String fmt function */ - struct uid uid = sim_ent_get_uid(ent); + struct uid uid = ent->uid; res.len += string_copy(arena, LIT(" [")).len; res.len += string_from_uint(arena, (U128_HI(uid.v) >> 36) & 0xFFFFFFF, 16, 7).len; res.len += string_copy(arena, LIT("]\n")).len; @@ -1531,7 +1531,7 @@ INTERNAL void user_update(void) u32 old_flags = G.user_sim_cmd_control.flags; G.user_sim_cmd_control = control; G.user_sim_cmd_control.flags |= old_flags; - G.user_sim_cmd_hovered_ent_uid = sim_ent_get_uid(hovered_ent); + G.user_sim_cmd_hovered_ent_uid = hovered_ent->uid; sys_mutex_unlock(&lock); } } @@ -1844,7 +1844,7 @@ INTERNAL struct sim_ent_handle _translate(struct sim_snapshot *local_ss, struct struct sim_ent_handle local_handle = SIM_ENT_NIL_HANDLE; struct sim_ent *remote_ent = sim_ent_from_handle(remote_ss, remote_ent_handle); if (remote_ent->valid) { - struct uid uid = sim_ent_get_uid(remote_ent); + struct uid uid = remote_ent->uid; struct sim_ent *local_ent = sim_ent_from_uid(local_ss, uid); local_handle = local_ent->handle; } @@ -1860,6 +1860,9 @@ INTERNAL void sim_ent_sync_tree(struct sim_ent *local, struct sim_ent *remote) struct sim_ent old = *local; MEMCPY_STRUCT(local, remote); + /* Why would 2 ents w/ different uids ever be synced? */ + ASSERT(uid_eq(local->uid, old.uid)); + sim_ent_disable_prop(local, SIM_ENT_PROP_SYNC_SRC); sim_ent_enable_prop(local, SIM_ENT_PROP_SYNC_DST); @@ -1867,7 +1870,7 @@ INTERNAL void sim_ent_sync_tree(struct sim_ent *local, struct sim_ent *remote) local->ss = old.ss; local->handle = old.handle; local->sync_src_client = remote_client_handle; - local->_uid = old._uid; + local->uid = old.uid; local->parent = old.parent; local->prev = old.prev; local->next = old.next; @@ -1903,7 +1906,7 @@ INTERNAL void sim_ent_alloc_any_new_sync_dsts(struct sim_ent *local_parent, stru struct sim_snapshot *remote_ss = remote->ss; struct sim_client_handle remote_client_handle = remote_ss->client->handle; - struct uid uid = sim_ent_get_uid(remote); + struct uid uid = remote->uid; struct sim_ent *local_ent = sim_ent_from_uid(local_ss, uid); if (!local_ent->valid) { local_ent = sim_ent_alloc_sync_dst(local_parent, remote_client_handle, uid); @@ -1932,8 +1935,7 @@ INTERNAL void sim_snapshot_sync(struct sim_snapshot *local_ss, struct sim_snapsh for (u64 i = 0; i < local_ss->num_ents_reserved; ++i) { struct sim_ent *local_ent = &local_ss->ents[i]; if (local_ent->valid && sim_ent_has_prop(local_ent, SIM_ENT_PROP_SYNC_DST) && sim_client_handle_eq(local_ent->sync_src_client, remote_client_handle)) { - struct uid uid = sim_ent_get_uid(local_ent); - struct sim_ent *remote_ent = sim_ent_from_uid(remote_ss, uid); + struct sim_ent *remote_ent = sim_ent_from_uid(remote_ss, local_ent->uid); if (remote_ent->valid) { /* Copy all ent data from remote */ sim_ent_sync_tree(local_ent, remote_ent); @@ -2209,9 +2211,9 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) client_ent->client_handle = client->handle; sim_ent_enable_prop(client_ent, SIM_ENT_PROP_CLIENT); sim_ent_enable_prop(client_ent, SIM_ENT_PROP_ACTIVE); - client->ent_uid = sim_ent_get_uid(client_ent); + client->ent_uid = client_ent->uid; if (client == user_input_client) { - local_ss->local_client_ent_uid = sim_ent_get_uid(client_ent); + local_ss->local_client_ent_uid = client_ent->uid; } } }