diff --git a/src/config.h b/src/config.h index 7b2334a5..313d1935 100644 --- a/src/config.h +++ b/src/config.h @@ -33,7 +33,7 @@ #define SPACE_CELL_BUCKETS_SQRT (256) #define SPACE_CELL_SIZE 1.0f -#define SIM_TICKS_PER_SECOND 100 +#define SIM_TICKS_PER_SECOND 50 #define SIM_TIMESCALE 1 #define SIM_PHYSICS_SUBSTEPS 4 @@ -62,7 +62,7 @@ #define COLLIDER_DEBUG_DETAILED_DRAW_MENKOWSKI 0 /* If enabled, bitbuffs will insert/verify magic numbers & length for each read & write */ -#define BITBUFF_DEBUG RTC +#define BITBUFF_DEBUG 0 #define BITBUFF_TEST RTC /* ========================== * diff --git a/src/phys.c b/src/phys.c index 09406df5..7279edd2 100644 --- a/src/phys.c +++ b/src/phys.c @@ -363,7 +363,7 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration) /* Mark constraint for removal */ 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_THIS_TICK); + 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); @@ -392,7 +392,7 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration) || !(sim_ent_has_prop(e1, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e1, SIM_ENT_PROP_PHYSICAL_KINEMATIC))) { /* Mark dbg ent for removal */ sim_ent_disable_prop(dbg_ent, SIM_ENT_PROP_ACTIVE); - sim_ent_enable_prop(dbg_ent, SIM_ENT_PROP_RELEASE_THIS_TICK); + sim_ent_enable_prop(dbg_ent, SIM_ENT_PROP_RELEASE); /* Remove from lookup */ struct sim_lookup_key key = sim_lookup_key_from_two_handles(dbg->e0, dbg->e1); @@ -653,7 +653,7 @@ void phys_prepare_motor_joints(struct phys_step_ctx *ctx) } else { /* Mark joint for removal */ sim_ent_disable_prop(joint_ent, SIM_ENT_PROP_ACTIVE); - sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_RELEASE_THIS_TICK); + sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_RELEASE); } } } @@ -825,7 +825,7 @@ void phys_prepare_mouse_joints(struct phys_step_ctx *ctx) } else { /* Mark joint for removal */ sim_ent_disable_prop(joint_ent, SIM_ENT_PROP_ACTIVE); - sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_RELEASE_THIS_TICK); + sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_RELEASE); } } } diff --git a/src/sim_ent.h b/src/sim_ent.h index e3180a96..267e423b 100644 --- a/src/sim_ent.h +++ b/src/sim_ent.h @@ -17,8 +17,7 @@ enum sim_ent_prop { SIM_ENT_PROP_ACTIVE, - SIM_ENT_PROP_RELEASE_THIS_TICK, - SIM_ENT_PROP_RELEASE_NEXT_TICK, + SIM_ENT_PROP_RELEASE, SIM_ENT_PROP_REMOTE, SIM_ENT_PROP_CLIENT, diff --git a/src/sim_step.c b/src/sim_step.c index 14a3b2af..dcf02466 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -403,7 +403,7 @@ INTERNAL void test_clear_level(struct sim_snapshot *world) for (u64 j = 0; j < world->num_ents_reserved; ++j) { struct sim_ent *ent = &world->ents[j]; if (ent->valid) { - sim_ent_enable_prop(ent, SIM_ENT_PROP_RELEASE_NEXT_TICK); + sim_ent_enable_prop(ent, SIM_ENT_PROP_RELEASE); } } } @@ -523,7 +523,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, st /* Update bullet */ bullet->bullet_has_hit = true; - sim_ent_enable_prop(bullet, SIM_ENT_PROP_RELEASE_THIS_TICK); + sim_ent_enable_prop(bullet, SIM_ENT_PROP_RELEASE); /* Update tracer */ struct sim_ent *tracer = sim_ent_from_handle(world, bullet->bullet_tracer); @@ -572,13 +572,13 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, st * Update * ========================== */ -void sim_step(struct sim_step_ctx *step_ctx) +void sim_step(struct sim_step_ctx *ctx) { __prof; struct temp_arena scratch = scratch_begin_no_conflict(); - struct sim_snapshot *world = step_ctx->world; - i64 sim_dt_ns = step_ctx->sim_dt_ns; + struct sim_snapshot *world = ctx->world; + i64 sim_dt_ns = ctx->sim_dt_ns; /* ========================== * * Begin frame @@ -595,27 +595,13 @@ void sim_step(struct sim_step_ctx *step_ctx) struct sim_ent *root = sim_ent_from_handle(world, SIM_ENT_ROOT_HANDLE); - if (step_ctx->is_master) { - /* ========================== * - * Spawn test entities - * ========================== */ + /* ========================== * + * Release entities + * ========================== */ - /* TODO: remove this (testing) */ - /* Initialize entities */ - { - static b32 run = 0; - if (!run) { - run = 1; - spawn_test_entities(world, V2(0, 0)); - } - } - - /* ========================== * - * Release entities - * ========================== */ - - release_entities_with_prop(world, SIM_ENT_PROP_RELEASE_NEXT_TICK); + release_entities_with_prop(world, SIM_ENT_PROP_RELEASE); + if (ctx->is_master) { /* ========================== * * Activate entities * ========================== */ @@ -632,6 +618,20 @@ void sim_step(struct sim_step_ctx *step_ctx) } } + /* ========================== * + * Spawn test entities + * ========================== */ + + /* TODO: remove this (testing) */ + /* Initialize entities */ + { + static b32 run = 0; + if (!run) { + run = 1; + spawn_test_entities(world, V2(0, 0)); + } + } + /* ========================== * * Reset triggered entities * ========================== */ @@ -1324,7 +1324,7 @@ void sim_step(struct sim_step_ctx *step_ctx) { struct phys_step_ctx phys = ZI; - phys.sim_step_ctx = step_ctx; + phys.sim_step_ctx = ctx; phys.pre_solve_callback = on_collision; phys_step(&phys, sim_dt); } @@ -1346,7 +1346,7 @@ void sim_step(struct sim_step_ctx *step_ctx) if (v2_dot(tick_velocity, v2_sub(gradient_start, end)) > 0) { /* Tracer has disappeared */ - sim_ent_enable_prop(ent, SIM_ENT_PROP_RELEASE_NEXT_TICK); + sim_ent_enable_prop(ent, SIM_ENT_PROP_RELEASE); } ent->tracer_gradient_start = gradient_start; @@ -1475,7 +1475,7 @@ void sim_step(struct sim_step_ctx *step_ctx) ent->quake_intensity = max_f32(0, ent->quake_intensity - (ent->quake_fade * sim_dt)); if (ent->quake_intensity <= 0) { - sim_ent_enable_prop(ent, SIM_ENT_PROP_RELEASE_NEXT_TICK); + sim_ent_enable_prop(ent, SIM_ENT_PROP_RELEASE); } } @@ -1507,14 +1507,14 @@ void sim_step(struct sim_step_ctx *step_ctx) arena_temp_end(temp); } - - /* ========================== * - * Release entities - * ========================== */ - - release_entities_with_prop(world, SIM_ENT_PROP_RELEASE_THIS_TICK); } + /* ========================== * + * Release entities + * ========================== */ + + release_entities_with_prop(world, SIM_ENT_PROP_RELEASE); + /* ========================== * * End frame * ========================== */ diff --git a/src/sim_step.h b/src/sim_step.h index 8e6e25be..9ed68d01 100644 --- a/src/sim_step.h +++ b/src/sim_step.h @@ -81,6 +81,6 @@ struct sim_step_ctx { i64 sim_dt_ns; }; -void sim_step(struct sim_step_ctx *step_ctx); +void sim_step(struct sim_step_ctx *ctx); #endif diff --git a/src/user.c b/src/user.c index 8d32afe5..190b258f 100644 --- a/src/user.c +++ b/src/user.c @@ -859,12 +859,13 @@ INTERNAL void user_update(void) struct v2 vdc = v2_neg(vcd); f32 opacity_a = 1; - if (v2_dot(velocity, vca) < 0) { + if (v2_dot(velocity, vca) <= 0) { a = c; opacity_a = 0; } else { opacity_a = v2_dot(vcd, vca) / v2_len_sq(vcd); } + opacity_a = clamp_f32(opacity_a, 0, 1); f32 opacity_b = clamp_f32(1.f - (v2_dot(vdc, vdb) / v2_len_sq(vdc)), 0, 1); @@ -1740,11 +1741,14 @@ INTERNAL void sim_ent_sync_with_remote(struct sim_accel *accel, struct sim_ent * local->remote_client = remote_client_handle; local->remote_ent = remote->handle; sim_ent_enable_prop(local, SIM_ENT_PROP_REMOTE); - sim_ent_set_xform(local, sim_ent_get_xform(remote)); + //sim_ent_set_xform(local, sim_ent_get_xform(remote)); /* Translate remote handles */ - translate(top); translate(parent); + if (!sim_ent_from_handle(local->ss, local->parent)->valid) { + local->parent = SIM_ENT_ROOT_HANDLE; + } + translate(top); translate(next); translate(prev); translate(first); @@ -1768,6 +1772,34 @@ INTERNAL void sim_ent_sync_with_remote(struct sim_accel *accel, struct sim_ent * } +INTERNAL void sim_ent_alloc_from_remote(struct sim_accel *accel, struct sim_ent *local_parent, struct sim_ent *remote) +{ + struct sim_snapshot *local_ss = local_parent->ss; + struct sim_snapshot *remote_ss = remote->ss; + struct sim_client_handle remote_client_handle = remote_ss->client->handle; + struct sim_lookup *remote_lookup = &accel->remote_lookup; + + if (remote->valid) { + struct sim_lookup_key key = sim_lookup_key_from_client_and_ent_handles(remote_client_handle, remote->handle); + struct sim_ent *local_ent = sim_ent_nil(); + { + struct sim_lookup_entry *entry = sim_lookup_get(remote_lookup, key); + if (entry) { + local_ent = sim_ent_from_handle(local_ss, entry->ent); + } + } + if (!local_ent->valid) { + local_ent = sim_ent_alloc(local_parent); + sim_ent_enable_prop(local_ent, SIM_ENT_PROP_REMOTE); + local_ent->remote_client = remote_client_handle; + local_ent->remote_ent = remote->handle; + sim_lookup_set(remote_lookup, key, local_ent->handle); + } + for (struct sim_ent *remote_child = sim_ent_from_handle(remote_ss, remote->first); remote_child->valid; remote_child = sim_ent_from_handle(remote_ss, remote_child->next)) { + sim_ent_alloc_from_remote(accel, local_ent, remote_child); + } + } +} INTERNAL void sim_snapshot_sync_with_remote(struct sim_accel *accel, struct sim_snapshot *local_ss, struct sim_snapshot *remote_ss) @@ -1776,6 +1808,7 @@ INTERNAL void sim_snapshot_sync_with_remote(struct sim_accel *accel, struct sim_ /* FIXME: Only sync cmds from non-master remote */ struct sim_ent *local_root = sim_ent_from_handle(local_ss, SIM_ENT_ROOT_HANDLE); + struct sim_ent *remote_root = sim_ent_from_handle(remote_ss, SIM_ENT_ROOT_HANDLE); struct sim_client_handle remote_client_handle = remote_ss->client->handle; struct sim_lookup *remote_lookup = &accel->remote_lookup; @@ -1788,7 +1821,6 @@ INTERNAL void sim_snapshot_sync_with_remote(struct sim_accel *accel, struct sim_ client_ent = client_entry ? sim_ent_from_handle(local_ss, client_entry->ent) : sim_ent_nil(); } - /* Build remote lookup table */ for (u64 i = 0; i < local_ss->num_ents_reserved; ++i) { struct sim_ent *ent = &local_ss->ents[i]; @@ -1799,27 +1831,8 @@ INTERNAL void sim_snapshot_sync_with_remote(struct sim_accel *accel, struct sim_ } /* Create new ents from remote */ - /* Skipping root entity */ - for (u64 i = SIM_ENT_ROOT_HANDLE.idx + 1; i < remote_ss->num_ents_reserved; ++i) { - struct sim_ent *remote_ent = &remote_ss->ents[i]; - if (remote_ent->valid) { - struct sim_lookup_key key = sim_lookup_key_from_client_and_ent_handles(remote_client_handle, remote_ent->handle); - struct sim_ent *local_ent = sim_ent_nil(); - { - struct sim_lookup_entry *entry = sim_lookup_get(remote_lookup, key); - if (entry) { - local_ent = sim_ent_from_handle(local_ss, entry->ent); - } - } - if (!local_ent->valid) { - local_ent = sim_ent_alloc(local_root); - sim_ent_enable_prop(local_ent, SIM_ENT_PROP_REMOTE); - local_ent->remote_client = remote_client_handle; - local_ent->remote_ent = remote_ent->handle; - sim_lookup_set(remote_lookup, key, local_ent->handle); - } - - } + for (struct sim_ent *remote_top = sim_ent_from_handle(remote_ss, remote_root->first); remote_top->valid; remote_top = sim_ent_from_handle(remote_ss, remote_top->next)) { + sim_ent_alloc_from_remote(accel, local_root, remote_top); } /* Sync ents with remote */ @@ -1832,7 +1845,7 @@ INTERNAL void sim_snapshot_sync_with_remote(struct sim_accel *accel, struct sim_ sim_ent_sync_with_remote(accel, local_ent, remote_ent, client_ent); } else { /* Remote ent is no longer valid / networked, release it */ - sim_ent_enable_prop(local_ent, SIM_ENT_PROP_RELEASE_THIS_TICK); + sim_ent_enable_prop(local_ent, SIM_ENT_PROP_RELEASE); sim_ent_disable_prop(local_ent, SIM_ENT_PROP_REMOTE); } } @@ -1855,7 +1868,6 @@ INTERNAL void sim_snapshot_sync_with_remote(struct sim_accel *accel, struct sim_ - INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) { #if 0 @@ -1942,9 +1954,10 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) /* Read snapshots */ u64 tmp_encoded_len = br_read_uv(&msg_br); - u8 *tmp_encoded_bytes = br_read_bytes_raw(&msg_br, tmp_encoded_len); - if (!tmp_encoded_bytes) tmp_encoded_len = 0; while (tmp_encoded_len > 0) { + u8 *tmp_encoded_bytes = br_read_bytes_raw(&msg_br, tmp_encoded_len); + if (!tmp_encoded_bytes) break; + struct bitbuff decoder_bb = bitbuff_from_string(STRING(tmp_encoded_len, tmp_encoded_bytes)); struct bitbuff_reader decoder_br = br_from_bitbuff(&decoder_bb); u64 base_tick = br_read_uv(&decoder_br); @@ -1963,8 +1976,6 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) } } tmp_encoded_len = br_read_uv(&msg_br); - tmp_encoded_bytes = br_read_bytes_raw(&msg_br, tmp_encoded_len); - if (!tmp_encoded_bytes) tmp_encoded_len = 0; } } } break; @@ -1974,6 +1985,12 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) } } + if (master_client->valid) { + if (master_client->last_tick > step_tick && (master_client->last_tick - step_tick) > 50) { + step_tick = master_client->last_tick; + } + } + /* Create user input */ { struct sim_snapshot *prev_user_input_ss = sim_snapshot_from_tick(user_input_client, user_input_client->last_tick); @@ -2002,7 +2019,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) /* Rebuild acceleration tables */ sim_accel_rebuild(local_ss, &accel); - /* Sync clients */ + /* Sync ents with local client */ { struct sim_ent *local_root = sim_ent_from_handle(local_ss, SIM_ENT_ROOT_HANDLE); for (u64 client_index = 0; client_index < store->num_clients_reserved; ++client_index) { @@ -2032,6 +2049,9 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) struct sim_snapshot *client_ss = sim_snapshot_from_tick(client, step_tick); if (client_ss->valid) { sim_snapshot_sync_with_remote(&accel, local_ss, client_ss); + if (!is_master && client == master_client) { + local_ss->local_client = client_ss->local_client; + } } } } @@ -2050,11 +2070,6 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) } } - - - - - /* Release unneeded snapshots */ #if 0 #if 0 @@ -2121,7 +2136,13 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) /* Construct publishable snapshot */ - + { + if (is_master) { + //struct sim_snapshot *prev_pub_ss = sim_snapshot_from_tick(publish_client, publish_client->last_tick); + struct sim_snapshot *pub_ss = sim_snapshot_alloc(publish_client, local_ss, local_ss->tick); + (UNUSED)pub_ss; + } + } @@ -2186,11 +2207,11 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) { /* TODO: Double buffer */ struct sys_lock lock = sys_mutex_lock_e(&G.local_to_user_client_mutex); - struct sim_snapshot *pub_ss = sim_snapshot_alloc(G.local_to_user_client, local_ss, local_ss->tick); - pub_ss->local_client = local_ss->local_client; + struct sim_snapshot *copy_ss = sim_snapshot_alloc(G.local_to_user_client, local_ss, local_ss->tick); + copy_ss->local_client = local_ss->local_client; i64 publish_ns = sys_time_ns(); - pub_ss->publish_dt_ns = publish_ns - last_publish_ns; - pub_ss->publish_time_ns = publish_ns; + copy_ss->publish_dt_ns = publish_ns - last_publish_ns; + copy_ss->publish_time_ns = publish_ns; last_publish_ns = publish_ns; sim_snapshot_release_ticks_in_range(G.local_to_user_client, 0, local_ss->tick - 1); sys_mutex_unlock(&lock);