From 7ab7af81a3ce9768e4f4fe7317b0cfe6f987314e Mon Sep 17 00:00:00 2001 From: jacob Date: Tue, 25 Feb 2025 08:05:58 -0600 Subject: [PATCH] prediction progress --- src/sim_ent.h | 10 +- src/sim_step.c | 252 +++++++++++++++++++++++++------------------------ src/user.c | 118 ++++++++++------------- 3 files changed, 187 insertions(+), 193 deletions(-) diff --git a/src/sim_ent.h b/src/sim_ent.h index 040e2bdd..c5c907cf 100644 --- a/src/sim_ent.h +++ b/src/sim_ent.h @@ -18,6 +18,7 @@ enum sim_ent_prop { SIM_ENT_PROP_SYNC_SRC, /* This entity should be networked to other clients */ SIM_ENT_PROP_SYNC_DST, /* This entity is not locally created, and should sync with incoming net src ents */ + SIM_ENT_PROP_SYNC_PREDICT, SIM_ENT_PROP_CLIENT, SIM_ENT_PROP_LOCAL_CLIENT, @@ -377,7 +378,14 @@ INLINE b32 sim_ent_is_valid_and_active(struct sim_ent *ent) INLINE b32 sim_ent_should_simulate(struct sim_ent *ent) { - return !sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST); + b32 res = false; + if (sim_ent_is_valid_and_active(ent)) { + res = true; + if (sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST) && !sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_PREDICT)) { + res = false; + } + } + return res; } /* ========================== * diff --git a/src/sim_step.c b/src/sim_step.c index baee61ba..4f084a44 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -181,9 +181,10 @@ INTERNAL struct sim_ent *spawn_test_player(struct sim_snapshot *world) //e->control_torque = 5000; e->control_torque = F32_INFINITY; - sim_ent_enable_prop(e, SIM_ENT_PROP_PHYSICAL_DYNAMIC); + sim_ent_enable_prop(e, SIM_ENT_PROP_SYNC_PREDICT); + player_ent = e; } @@ -253,7 +254,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, st struct sim_ent *e0 = sim_ent_from_id(world, data->e0); struct sim_ent *e1 = sim_ent_from_id(world, data->e1); - if (sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) { + if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) { /* Bullet hit entity */ if (sim_ent_has_prop(e0, SIM_ENT_PROP_BULLET) || sim_ent_has_prop(e1, SIM_ENT_PROP_BULLET)) { struct v2 normal = data->normal; /* Impact normal */ @@ -283,7 +284,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, st /* Update tracer */ struct sim_ent *tracer = sim_ent_from_id(world, bullet->bullet_tracer); - if (sim_ent_is_valid_and_active(tracer)) { + if (sim_ent_should_simulate(tracer)) { struct xform xf = sim_ent_get_xform(tracer); xf.og = point; sim_ent_set_xform(tracer, xf); @@ -365,7 +366,7 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; if (!ent->valid) continue; - if (!sim_ent_should_simulate(ent)) continue; + if (sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST) && !sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_PREDICT)) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_ACTIVE)) { u64 atick = ent->activation_tick; @@ -381,7 +382,6 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_should_simulate(ent)) continue; if (sim_ent_has_prop(ent, SIM_ENT_PROP_TRIGGER_NEXT_TICK)) { @@ -398,11 +398,11 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *cmd_ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(cmd_ent)) continue; + if (!sim_ent_should_simulate(cmd_ent)) continue; if (sim_ent_has_prop(cmd_ent, SIM_ENT_PROP_CMD_CONTROL)) { struct sim_ent *client_ent = sim_ent_from_id(world, cmd_ent->cmd_client); - if (sim_ent_is_valid_and_active(client_ent)) { + if (sim_ent_should_simulate(client_ent)) { if (!ctx->is_master && !sim_ent_id_eq(client_ent->id, world->local_client_ent)) { /* We are not the master and the command is not our own, skip processing */ continue; @@ -471,7 +471,7 @@ void sim_step(struct sim_step_ctx *ctx) if (ctx->is_master) { for (u64 i = 0; i < world->num_ents_reserved; ++i) { struct sim_ent *ent = &world->ents[i]; - if (!sim_ent_is_valid_and_active(ent)) continue; + if (!sim_ent_should_simulate(ent)) continue; if (sim_ent_has_prop(ent, SIM_ENT_PROP_CLIENT)) { /* FIXME: Ents never released when client disconnects */ struct sim_ent *control_ent = sim_ent_from_id(world, ent->client_control_ent); @@ -496,7 +496,6 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_should_simulate(ent)) continue; if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) { @@ -519,7 +518,6 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_should_simulate(ent)) continue; if (sprite_tag_is_nil(ent->sprite)) continue; @@ -620,7 +618,6 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_ATTACHED)) continue; @@ -697,12 +694,11 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_should_simulate(ent)) continue; if (sim_ent_has_prop(ent, SIM_ENT_PROP_TRIGGERING_EQUIPPED)) { struct sim_ent *eq = sim_ent_from_id(world, ent->equipped); - if (sim_ent_is_valid_and_active(eq)) { + if (sim_ent_should_simulate(eq)) { sim_ent_enable_prop(eq, SIM_ENT_PROP_TRIGGERED_THIS_TICK); } } @@ -714,7 +710,6 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_TRIGGERED_THIS_TICK)) continue; if ((world->sim_time_ns - ent->last_triggered_ns < NS_FROM_SECONDS(ent->trigger_delay)) && ent->last_triggered_ns != 0) continue; @@ -774,18 +769,17 @@ void sim_step(struct sim_step_ctx *ctx) } /* ========================== * - * Create motor joints from control move + * Create & update motor joints from control move * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_should_simulate(ent)) continue; if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) { struct sim_ent *joint_ent = sim_ent_from_id(world, ent->move_joint); - if (!sim_ent_is_valid_and_active(joint_ent)) { - joint_ent = sim_ent_alloc_local(root); + if (ctx->is_master && !sim_ent_is_valid_and_active(joint_ent)) { + joint_ent = sim_ent_alloc_sync_src(root); joint_ent->mass_unscaled = F32_INFINITY; joint_ent->inertia_unscaled = F32_INFINITY; sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_MOTOR_JOINT); @@ -799,21 +793,26 @@ void sim_step(struct sim_step_ctx *ctx) def.max_force = ent->control_force; def.max_torque = 0; joint_ent->motor_joint_data = phys_motor_joint_from_def(def); + + if (sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_PREDICT)) { + sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_SYNC_PREDICT); + } } - sim_ent_set_xform(joint_ent, XFORM_IDENT); /* Reset joint ent position */ - sim_ent_set_linear_velocity(joint_ent, v2_mul(v2_clamp_len(ent->control.move, 1), ent->control_force_max_speed)); + if (sim_ent_should_simulate(joint_ent)) { + sim_ent_set_xform(joint_ent, XFORM_IDENT); /* Reset joint ent position */ + sim_ent_set_linear_velocity(joint_ent, v2_mul(v2_clamp_len(ent->control.move, 1), ent->control_force_max_speed)); + } } } /* ========================== * - * Create motor joints from control focus (aim) + * Create & update motor joints from control focus (aim) * ========================== */ #if SIM_PLAYER_AIM for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_should_simulate(ent)) continue; if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) { @@ -822,8 +821,8 @@ void sim_step(struct sim_step_ctx *ctx) /* Retrieve / create aim joint */ struct sim_ent *joint_ent = sim_ent_from_id(world, ent->aim_joint); - if (!sim_ent_is_valid_and_active(joint_ent)) { - joint_ent = sim_ent_alloc_local(root); + if (ctx->is_master && !sim_ent_is_valid_and_active(joint_ent)) { + joint_ent = sim_ent_alloc_sync_src(root); joint_ent->mass_unscaled = F32_INFINITY; joint_ent->inertia_unscaled = F32_INFINITY; sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_PHYSICAL_KINEMATIC); /* Since we'll be setting velocity manually */ @@ -837,66 +836,73 @@ void sim_step(struct sim_step_ctx *ctx) def.max_force = 0; def.max_torque = ent->control_torque; joint_ent->motor_joint_data = phys_motor_joint_from_def(def); + + if (sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_PREDICT)) { + sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_SYNC_PREDICT); + } } - /* Set correction rate dynamically since motor velocity is only set for one frame */ - joint_ent->motor_joint_data.correction_rate = 10 * sim_dt; + if (sim_ent_should_simulate(joint_ent)) { + /* Set correction rate dynamically since motor velocity is only set for one frame */ + joint_ent->motor_joint_data.correction_rate = 10 * sim_dt; - /* Solve for final angle using law of sines */ - f32 new_angle; - { - struct v2 ent_pos = xf.og; - struct v2 focus_pos = v2_add(ent_pos, ent->control.focus); - - struct v2 sprite_hold_pos; - struct v2 sprite_hold_dir; + /* Solve for final angle using law of sines */ + f32 new_angle; { - struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite); - struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, LIT("attach.wep"), ent->animation_frame); - sprite_hold_pos = slice.center; - sprite_hold_dir = slice.dir; + struct v2 ent_pos = xf.og; + struct v2 focus_pos = v2_add(ent_pos, ent->control.focus); + + struct v2 sprite_hold_pos; + struct v2 sprite_hold_dir; + { + struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite); + struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, LIT("attach.wep"), ent->animation_frame); + sprite_hold_pos = slice.center; + sprite_hold_dir = slice.dir; + } + + struct v2 hold_dir = xform_basis_mul_v2(sprite_xf, sprite_hold_dir); + struct v2 hold_pos = xform_mul_v2(sprite_xf, sprite_hold_pos); + if (v2_eq(hold_pos, ent_pos)) { + /* If hold pos is same as origin (E.G if pivot is being used as hold pos), then move hold pos forward a tad to avoid issue */ + sprite_hold_pos = v2_add(sprite_hold_pos, V2(0, -1)); + hold_pos = xform_mul_v2(sprite_xf, sprite_hold_pos); + } + + f32 forward_hold_angle_offset; + { + struct xform xf_unrotated = xform_basis_with_rotation_world(xf, 0); + struct v2 hold_pos_unrotated = xform_mul_v2(xf_unrotated, xform_mul_v2(ent->sprite_local_xform, sprite_hold_pos)); + forward_hold_angle_offset = v2_angle_from_dirs(V2(0, -1), v2_sub(hold_pos_unrotated, xf_unrotated.og)); + } + + struct v2 hold_ent_dir = v2_sub(ent_pos, hold_pos); + struct v2 focus_ent_dir = v2_sub(ent_pos, focus_pos); + + f32 hold_ent_len = v2_len(hold_ent_dir); + f32 focus_ent_len = v2_len(focus_ent_dir); + + f32 final_hold_angle_btw_ent_and_focus = v2_angle_from_dirs(hold_ent_dir, hold_dir); + f32 final_focus_angle_btw_ent_and_hold = math_asin((math_sin(final_hold_angle_btw_ent_and_focus) * hold_ent_len) / focus_ent_len); + f32 final_ent_angle_btw_focus_and_hold = PI - (final_focus_angle_btw_ent_and_hold + final_hold_angle_btw_ent_and_focus); + + new_angle = math_unwind_angle(v2_angle_from_dirs(V2(0, -1), v2_sub(focus_pos, ent_pos)) + final_ent_angle_btw_focus_and_hold - forward_hold_angle_offset); } - struct v2 hold_dir = xform_basis_mul_v2(sprite_xf, sprite_hold_dir); - struct v2 hold_pos = xform_mul_v2(sprite_xf, sprite_hold_pos); - if (v2_eq(hold_pos, ent_pos)) { - /* If hold pos is same as origin (E.G if pivot is being used as hold pos), then move hold pos forward a tad to avoid issue */ - sprite_hold_pos = v2_add(sprite_hold_pos, V2(0, -1)); - hold_pos = xform_mul_v2(sprite_xf, sprite_hold_pos); + f32 new_vel = 0; + if (!F32_IS_NAN(new_angle)) { + const f32 angle_error_allowed = 0.001f; + struct xform joint_xf = sim_ent_get_xform(joint_ent); + f32 diff = math_unwind_angle(new_angle - xform_get_rotation(joint_xf)); + if (math_fabs(diff) > angle_error_allowed) { + /* Instantly snap joint ent to new angle */ + new_vel = diff / sim_dt; + } } - - f32 forward_hold_angle_offset; - { - struct xform xf_unrotated = xform_basis_with_rotation_world(xf, 0); - struct v2 hold_pos_unrotated = xform_mul_v2(xf_unrotated, xform_mul_v2(ent->sprite_local_xform, sprite_hold_pos)); - forward_hold_angle_offset = v2_angle_from_dirs(V2(0, -1), v2_sub(hold_pos_unrotated, xf_unrotated.og)); - } - - struct v2 hold_ent_dir = v2_sub(ent_pos, hold_pos); - struct v2 focus_ent_dir = v2_sub(ent_pos, focus_pos); - - f32 hold_ent_len = v2_len(hold_ent_dir); - f32 focus_ent_len = v2_len(focus_ent_dir); - - f32 final_hold_angle_btw_ent_and_focus = v2_angle_from_dirs(hold_ent_dir, hold_dir); - f32 final_focus_angle_btw_ent_and_hold = math_asin((math_sin(final_hold_angle_btw_ent_and_focus) * hold_ent_len) / focus_ent_len); - f32 final_ent_angle_btw_focus_and_hold = PI - (final_focus_angle_btw_ent_and_hold + final_hold_angle_btw_ent_and_focus); - - new_angle = math_unwind_angle(v2_angle_from_dirs(V2(0, -1), v2_sub(focus_pos, ent_pos)) + final_ent_angle_btw_focus_and_hold - forward_hold_angle_offset); + sim_ent_set_angular_velocity(joint_ent, new_vel); } - f32 new_vel = 0; - if (!F32_IS_NAN(new_angle)) { - const f32 angle_error_allowed = 0.001f; - struct xform joint_xf = sim_ent_get_xform(joint_ent); - f32 diff = math_unwind_angle(new_angle - xform_get_rotation(joint_xf)); - if (math_fabs(diff) > angle_error_allowed) { - /* Instantly snap joint ent to new angle */ - new_vel = diff / sim_dt; - } - } - sim_ent_set_angular_velocity(joint_ent, new_vel); } } #endif @@ -907,7 +913,6 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC)) continue; @@ -920,12 +925,16 @@ void sim_step(struct sim_step_ctx *ctx) def.max_force = ent->linear_ground_friction; def.max_torque = ent->angular_ground_friction; if (joint_ent->motor_joint_data.max_force != def.max_force || joint_ent->motor_joint_data.max_torque != def.max_torque) { - if (!sim_ent_is_valid_and_active(joint_ent)) { - joint_ent = sim_ent_alloc_local(root); + if (ctx->is_master && !sim_ent_is_valid_and_active(joint_ent)) { + joint_ent = sim_ent_alloc_sync_src(root); sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_MOTOR_JOINT); sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_ACTIVE); joint_ent->motor_joint_data = phys_motor_joint_from_def(def); ent->ground_friction_joint = joint_ent->id; + + if (sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_PREDICT)) { + sim_ent_enable_prop(ent, SIM_ENT_PROP_SYNC_PREDICT); + } } } } @@ -934,50 +943,51 @@ void sim_step(struct sim_step_ctx *ctx) * Create mouse joints from client debug drag * ========================== */ - for (u64 i = 0; i < world->num_ents_reserved; ++i) { - struct sim_ent *client_ent = &world->ents[i]; - if (!sim_ent_is_valid_and_active(client_ent)) continue; - if (!sim_ent_should_simulate(client_ent)) continue; - if (!sim_ent_has_prop(client_ent, SIM_ENT_PROP_CLIENT)) continue; + if (ctx->is_master) { + for (u64 i = 0; i < world->num_ents_reserved; ++i) { + struct sim_ent *client_ent = &world->ents[i]; + if (!sim_ent_should_simulate(client_ent)) continue; + if (!sim_ent_has_prop(client_ent, SIM_ENT_PROP_CLIENT)) continue; - struct v2 cursor = client_ent->client_cursor_pos; - b32 start_dragging = client_ent->client_dbg_drag_start; - b32 stop_dragging = client_ent->client_dbg_drag_stop; + struct v2 cursor = client_ent->client_cursor_pos; + b32 start_dragging = client_ent->client_dbg_drag_start; + b32 stop_dragging = client_ent->client_dbg_drag_stop; - struct sim_ent *joint_ent = sim_ent_from_id(world, client_ent->client_dbg_drag_joint_ent); - struct sim_ent *target_ent = sim_ent_from_id(world, joint_ent->mouse_joint_data.target); + struct sim_ent *joint_ent = sim_ent_from_id(world, client_ent->client_dbg_drag_joint_ent); + struct sim_ent *target_ent = sim_ent_from_id(world, joint_ent->mouse_joint_data.target); - if (stop_dragging) { - target_ent = sim_ent_nil(); - } else if (start_dragging) { - target_ent = sim_ent_from_id(world, client_ent->client_hovered_ent); - } - - if (sim_ent_is_valid_and_active(target_ent)) { - if (!sim_ent_is_valid_and_active(joint_ent)) { - /* FIXME: Joint ent may never release */ - joint_ent = sim_ent_alloc_local(root); - joint_ent->mass_unscaled = F32_INFINITY; - joint_ent->inertia_unscaled = F32_INFINITY; - client_ent->client_dbg_drag_joint_ent = joint_ent->id; - sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_MOUSE_JOINT); - sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_ACTIVE); + if (stop_dragging) { + target_ent = sim_ent_nil(); + } else if (start_dragging) { + target_ent = sim_ent_from_id(world, client_ent->client_hovered_ent); } - struct xform xf = sim_ent_get_xform(target_ent); - f32 mass = target_ent->mass_unscaled * math_fabs(xform_get_determinant(xf)); - struct phys_mouse_joint_def def = ZI; - def.target = target_ent->id; - if (sim_ent_id_eq(joint_ent->mouse_joint_data.target, target_ent->id)) { - def.point_local_start = joint_ent->mouse_joint_data.point_local_start; - } else { - def.point_local_start = xform_invert_mul_v2(xf, cursor); + if (sim_ent_should_simulate(target_ent)) { + if (!sim_ent_is_valid_and_active(joint_ent)) { + /* FIXME: Joint ent may never release */ + joint_ent = sim_ent_alloc_sync_src(root); + joint_ent->mass_unscaled = F32_INFINITY; + joint_ent->inertia_unscaled = F32_INFINITY; + client_ent->client_dbg_drag_joint_ent = joint_ent->id; + sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_MOUSE_JOINT); + sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_ACTIVE); + } + struct xform xf = sim_ent_get_xform(target_ent); + f32 mass = target_ent->mass_unscaled * math_fabs(xform_get_determinant(xf)); + + struct phys_mouse_joint_def def = ZI; + def.target = target_ent->id; + if (sim_ent_id_eq(joint_ent->mouse_joint_data.target, target_ent->id)) { + def.point_local_start = joint_ent->mouse_joint_data.point_local_start; + } else { + def.point_local_start = xform_invert_mul_v2(xf, cursor); + } + def.point_local_end = xform_invert_mul_v2(xf, cursor); + def.max_force = mass * 1000; + joint_ent->mouse_joint_data = phys_mouse_joint_from_def(def); + } else if (sim_ent_is_valid_and_active(joint_ent)) { + joint_ent->mouse_joint_data.target = target_ent->id; } - def.point_local_end = xform_invert_mul_v2(xf, cursor); - def.max_force = mass * 1000; - joint_ent->mouse_joint_data = phys_mouse_joint_from_def(def); - } else if (sim_ent_is_valid_and_active(joint_ent)) { - joint_ent->mouse_joint_data.target = target_ent->id; } } @@ -985,7 +995,7 @@ void sim_step(struct sim_step_ctx *ctx) * Physics step * ========================== */ - if (ctx->is_master) { + { struct phys_step_ctx phys = ZI; phys.sim_step_ctx = ctx; phys.pre_solve_callback = on_collision; @@ -998,7 +1008,6 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_TRACER)) continue; @@ -1023,7 +1032,6 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_BULLET)) continue; @@ -1052,7 +1060,7 @@ void sim_step(struct sim_step_ctx *ctx) /* Initialize tracer */ struct sim_ent *tracer = sim_ent_from_id(world, ent->bullet_tracer); - if (sim_ent_is_valid_and_active(tracer)) { + if (sim_ent_should_simulate(tracer)) { sim_ent_set_xform(tracer, xf); sim_ent_enable_prop(tracer, SIM_ENT_PROP_PHYSICAL_KINEMATIC); sim_ent_set_linear_velocity(tracer, ent->linear_velocity); @@ -1079,7 +1087,6 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_CAMERA)) continue; @@ -1121,7 +1128,7 @@ void sim_step(struct sim_step_ctx *ctx) ent->shake = 0; for (u64 quake_ent_index = 0; quake_ent_index < world->num_ents_reserved; ++quake_ent_index) { struct sim_ent *quake = &world->ents[quake_ent_index]; - if (!sim_ent_is_valid_and_active(quake)) continue; + if (!sim_ent_should_simulate(quake)) continue; if (!sim_ent_has_prop(quake, SIM_ENT_PROP_QUAKE)) continue; ent->shake += quake->quake_intensity; } @@ -1136,7 +1143,6 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_QUAKE)) continue; @@ -1164,7 +1170,7 @@ void sim_step(struct sim_step_ctx *ctx) i32 parent_layer = parent->final_layer; for (struct sim_ent *child = sim_ent_from_id(world, parent->first); child->valid; child = sim_ent_from_id(world, child->next)) { - if (sim_ent_is_valid_and_active(child) && sim_ent_should_simulate(child)) { + if (sim_ent_should_simulate(child)) { child->final_layer = parent_layer + child->layer; *arena_push(temp.arena, struct sim_ent *) = child; ++stack_count; diff --git a/src/user.c b/src/user.c index 2bb88fd3..644d7b9b 100644 --- a/src/user.c +++ b/src/user.c @@ -363,7 +363,7 @@ INTERNAL struct string get_ent_debug_text(struct arena *arena, struct sim_ent *e res.len += string_copy(arena, LIT(" local")).len; } - res.len += string_copy(arena, LIT("\n")).len; + res.len += string_copy(arena, LIT("\n\n")).len; } { @@ -391,6 +391,17 @@ INTERNAL struct string get_ent_debug_text(struct arena *arena, struct sim_ent *e res.len += string_format(arena, LIT("next: [%F]\n"), FMT_UID(ent->next.uid)).len; } + res.len += string_copy(arena, LIT("\n")).len; + + /* Pos */ + struct xform xf = sim_ent_get_xform(ent); + struct v2 linear_velocity = ent->linear_velocity; + f32 angular_velocity = ent->angular_velocity; + res.len += string_format(arena, LIT("pos: (%F, %F)\n"), FMT_FLOAT_P(xf.og.x, 3), FMT_FLOAT_P(xf.og.y, 3)).len; + res.len += string_format(arena, LIT("linear velocity: (%F, %F)\n"), FMT_FLOAT_P(linear_velocity.x, 3), FMT_FLOAT_P(linear_velocity.y, 3)).len; + res.len += string_format(arena, LIT("angular velocity: %F\n"), FMT_FLOAT_P(angular_velocity, 3)).len; + + /* Children */ if (!sim_ent_id_eq(ent->first, SIM_ENT_NIL_ID) || !sim_ent_id_eq(ent->last, SIM_ENT_NIL_ID)) { struct sim_ent *child = sim_ent_from_id(ss, ent->first); if (!sim_ent_id_eq(ent->first, ent->last) || !child->valid) { @@ -398,7 +409,8 @@ INTERNAL struct string get_ent_debug_text(struct arena *arena, struct sim_ent *e res.len += string_format(arena, LIT("last child: [%F]\n"), FMT_UID(ent->last.uid)).len; } while (child->valid) { - res.len += string_copy(arena, LIT("\nCHILD\n")).len; + res.len += string_copy(arena, LIT("\n---------------------------------\n")).len; + res.len += string_copy(arena, LIT("CHILD\n")).len; struct string child_text = get_ent_debug_text(scratch.arena, child); res.len += string_indent(arena, child_text, 4).len; child = sim_ent_from_id(ss, child->next); @@ -2052,6 +2064,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) if (!control_cmd_ent->valid) { control_cmd_ent = sim_ent_alloc_sync_src(user_input_root); sim_ent_enable_prop(control_cmd_ent, SIM_ENT_PROP_CMD_CONTROL); + sim_ent_enable_prop(control_cmd_ent, SIM_ENT_PROP_SYNC_PREDICT); sim_ent_activate(control_cmd_ent, user_input_ss->tick); } /* Update local control cmd ent */ @@ -2082,9 +2095,12 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) client_ent = sim_ent_alloc_sync_src(local_root); 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_SYNC_PREDICT); sim_ent_enable_prop(client_ent, SIM_ENT_PROP_ACTIVE); client->ent_id = client_ent->id; if (client == user_input_client) { + user_input_client->ent_id = client_ent->id; + local_client->ent_id = client_ent->id; local_ss->local_client_ent = client_ent->id; } } @@ -2097,6 +2113,8 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) if (client_ss->valid) { sim_snapshot_sync(local_ss, client_ss); if (!is_master && client == master_client) { + user_input_client->ent_id = client_ss->local_client_ent; + local_client->ent_id = client_ss->local_client_ent; local_ss->local_client_ent = client_ss->local_client_ent; } } @@ -2105,23 +2123,13 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) } } - if (is_master) { - /* Point incoming client cmds to correct client ents */ - for (u64 i = 0; i < local_ss->num_ents_reserved; ++i) { - struct sim_ent *ent = &local_ss->ents[i]; - if (ent->valid && sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST)) { - struct sim_client *src_client = sim_client_from_handle(store, ent->sync_src_client); - struct sim_ent *client_ent = sim_ent_from_id(local_ss, src_client->ent_id); - ent->cmd_client = client_ent->id; - } - } - } else { - /* Mark all local commands as networked */ - for (u64 i = 0; i < local_ss->num_ents_reserved; ++i) { - struct sim_ent *ent = &local_ss->ents[i]; - if (ent->valid && sim_ent_has_prop(ent, SIM_ENT_PROP_CMD_CONTROL) && sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST)) { - sim_ent_enable_prop(ent, SIM_ENT_PROP_SYNC_SRC); - } + /* Point cmds to correct client ents */ + for (u64 i = 0; i < local_ss->num_ents_reserved; ++i) { + struct sim_ent *ent = &local_ss->ents[i]; + if (ent->valid && sim_ent_has_prop(ent, SIM_ENT_PROP_CMD_CONTROL) && sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST)) { + struct sim_client *src_client = sim_client_from_handle(store, ent->sync_src_client); + struct sim_ent *client_ent = sim_ent_from_id(local_ss, src_client->ent_id); + ent->cmd_client = client_ent->id; } } @@ -2164,46 +2172,13 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) } } -#if 0 -#if 0 - u64 oldest_client_ack = 0; - for (u64 i = 0; i < store->num_clients_reserved; ++i) { - struct sim_client *client = &store->clients[i]; - enum sim_client_kind kind = client->kind; - if (client->valid && kind != SIM_CLIENT_KIND_LOCAL_SIM) { - u64 ack = client->ack; - u64 double_ack = client->double_ack; - if (double_ack > 1) { - sim_snapshot_release_ticks_in_range(client, 0, double_ack - 1); - } - if (ack < oldest_client_ack || oldest_client_ack == 0) { - oldest_client_ack = ack; - } - } - } - if (oldest_client_ack > 1) { - sim_snapshot_release_ticks_in_range(local_client, 0, oldest_client_ack - 1); - } -#else - for (u64 i = 0; i < store->num_clients_reserved; ++i) { - struct sim_client *client = &store->clients[i]; - if (client->valid) { - if (client->is_remote) { - u64 double_ack = client->double_ack; - if (double_ack > 1) { - sim_snapshot_release_ticks_in_range(client, 0, double_ack - 1); - } - } else { - u64 keep_ticks_count = 500; - if (step_tick > keep_ticks_count) { - u64 keep_tick = client->last_tick - keep_ticks_count; - sim_snapshot_release_ticks_in_range(client, 0, keep_tick); - } - } - } - } -#endif -#endif + + + + + + + /* Step */ { @@ -2220,6 +2195,21 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) + /* Signal any locally created CMDs as sync sources */ + for (u64 i = 0; i < local_ss->num_ents_reserved; ++i) { + struct sim_ent *ent = &local_ss->ents[i]; + if (sim_ent_is_valid_and_active(ent) && sim_ent_has_prop(ent, SIM_ENT_PROP_CMD_CONTROL)) { + if (!sim_ent_id_eq(ent->cmd_client, SIM_ENT_NIL_ID) && sim_ent_id_eq(ent->cmd_client, local_ss->local_client_ent)) { + sim_ent_enable_prop(ent, SIM_ENT_PROP_SYNC_SRC); + } + } + } + + + + + + @@ -2229,15 +2219,6 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) /* Construct publishable snapshot */ -#if 0 - { - 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; - } - } -#else { struct sim_snapshot *pub_ss; if (is_master) { @@ -2247,7 +2228,6 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) } sim_snapshot_sync(pub_ss, local_ss); } -#endif