prediction progress
This commit is contained in:
parent
4d7ab508fb
commit
7ab7af81a3
@ -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_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_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_CLIENT,
|
||||||
SIM_ENT_PROP_LOCAL_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)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
|
|||||||
252
src/sim_step.c
252
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 = 5000;
|
||||||
e->control_torque = F32_INFINITY;
|
e->control_torque = F32_INFINITY;
|
||||||
|
|
||||||
|
|
||||||
sim_ent_enable_prop(e, SIM_ENT_PROP_PHYSICAL_DYNAMIC);
|
sim_ent_enable_prop(e, SIM_ENT_PROP_PHYSICAL_DYNAMIC);
|
||||||
|
|
||||||
|
sim_ent_enable_prop(e, SIM_ENT_PROP_SYNC_PREDICT);
|
||||||
|
|
||||||
player_ent = e;
|
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 *e0 = sim_ent_from_id(world, data->e0);
|
||||||
struct sim_ent *e1 = sim_ent_from_id(world, data->e1);
|
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 */
|
/* Bullet hit entity */
|
||||||
if (sim_ent_has_prop(e0, SIM_ENT_PROP_BULLET) || sim_ent_has_prop(e1, SIM_ENT_PROP_BULLET)) {
|
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 */
|
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 */
|
/* Update tracer */
|
||||||
struct sim_ent *tracer = sim_ent_from_id(world, bullet->bullet_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);
|
struct xform xf = sim_ent_get_xform(tracer);
|
||||||
xf.og = point;
|
xf.og = point;
|
||||||
sim_ent_set_xform(tracer, xf);
|
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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!ent->valid) continue;
|
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)) {
|
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_ACTIVE)) {
|
||||||
u64 atick = ent->activation_tick;
|
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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[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_should_simulate(ent)) continue;
|
||||||
|
|
||||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_TRIGGER_NEXT_TICK)) {
|
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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *cmd_ent = &world->ents[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)) {
|
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);
|
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)) {
|
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 */
|
/* We are not the master and the command is not our own, skip processing */
|
||||||
continue;
|
continue;
|
||||||
@ -471,7 +471,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
if (ctx->is_master) {
|
if (ctx->is_master) {
|
||||||
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
|
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
|
||||||
struct sim_ent *ent = &world->ents[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)) {
|
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CLIENT)) {
|
||||||
/* FIXME: Ents never released when client disconnects */
|
/* FIXME: Ents never released when client disconnects */
|
||||||
struct sim_ent *control_ent = sim_ent_from_id(world, ent->client_control_ent);
|
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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[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_should_simulate(ent)) continue;
|
||||||
|
|
||||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) {
|
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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[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_should_simulate(ent)) continue;
|
||||||
if (sprite_tag_is_nil(ent->sprite)) 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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[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_should_simulate(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_ATTACHED)) 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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[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_should_simulate(ent)) continue;
|
||||||
|
|
||||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_TRIGGERING_EQUIPPED)) {
|
if (sim_ent_has_prop(ent, SIM_ENT_PROP_TRIGGERING_EQUIPPED)) {
|
||||||
struct sim_ent *eq = sim_ent_from_id(world, ent->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);
|
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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[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_should_simulate(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_TRIGGERED_THIS_TICK)) 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;
|
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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[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_should_simulate(ent)) continue;
|
||||||
|
|
||||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) {
|
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) {
|
||||||
struct sim_ent *joint_ent = sim_ent_from_id(world, ent->move_joint);
|
struct sim_ent *joint_ent = sim_ent_from_id(world, ent->move_joint);
|
||||||
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
if (ctx->is_master && !sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
joint_ent = sim_ent_alloc_local(root);
|
joint_ent = sim_ent_alloc_sync_src(root);
|
||||||
joint_ent->mass_unscaled = F32_INFINITY;
|
joint_ent->mass_unscaled = F32_INFINITY;
|
||||||
joint_ent->inertia_unscaled = F32_INFINITY;
|
joint_ent->inertia_unscaled = F32_INFINITY;
|
||||||
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_MOTOR_JOINT);
|
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_force = ent->control_force;
|
||||||
def.max_torque = 0;
|
def.max_torque = 0;
|
||||||
joint_ent->motor_joint_data = phys_motor_joint_from_def(def);
|
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 */
|
if (sim_ent_should_simulate(joint_ent)) {
|
||||||
sim_ent_set_linear_velocity(joint_ent, v2_mul(v2_clamp_len(ent->control.move, 1), ent->control_force_max_speed));
|
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
|
#if SIM_PLAYER_AIM
|
||||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[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_should_simulate(ent)) continue;
|
||||||
|
|
||||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) {
|
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 */
|
/* Retrieve / create aim joint */
|
||||||
struct sim_ent *joint_ent = sim_ent_from_id(world, ent->aim_joint);
|
struct sim_ent *joint_ent = sim_ent_from_id(world, ent->aim_joint);
|
||||||
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
if (ctx->is_master && !sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
joint_ent = sim_ent_alloc_local(root);
|
joint_ent = sim_ent_alloc_sync_src(root);
|
||||||
joint_ent->mass_unscaled = F32_INFINITY;
|
joint_ent->mass_unscaled = F32_INFINITY;
|
||||||
joint_ent->inertia_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 */
|
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_force = 0;
|
||||||
def.max_torque = ent->control_torque;
|
def.max_torque = ent->control_torque;
|
||||||
joint_ent->motor_joint_data = phys_motor_joint_from_def(def);
|
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 */
|
if (sim_ent_should_simulate(joint_ent)) {
|
||||||
joint_ent->motor_joint_data.correction_rate = 10 * sim_dt;
|
/* 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 */
|
/* Solve for final angle using law of sines */
|
||||||
f32 new_angle;
|
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;
|
|
||||||
{
|
{
|
||||||
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
|
struct v2 ent_pos = xf.og;
|
||||||
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, LIT("attach.wep"), ent->animation_frame);
|
struct v2 focus_pos = v2_add(ent_pos, ent->control.focus);
|
||||||
sprite_hold_pos = slice.center;
|
|
||||||
sprite_hold_dir = slice.dir;
|
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);
|
f32 new_vel = 0;
|
||||||
struct v2 hold_pos = xform_mul_v2(sprite_xf, sprite_hold_pos);
|
if (!F32_IS_NAN(new_angle)) {
|
||||||
if (v2_eq(hold_pos, ent_pos)) {
|
const f32 angle_error_allowed = 0.001f;
|
||||||
/* 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 */
|
struct xform joint_xf = sim_ent_get_xform(joint_ent);
|
||||||
sprite_hold_pos = v2_add(sprite_hold_pos, V2(0, -1));
|
f32 diff = math_unwind_angle(new_angle - xform_get_rotation(joint_xf));
|
||||||
hold_pos = xform_mul_v2(sprite_xf, sprite_hold_pos);
|
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);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
#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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[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_should_simulate(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC)) 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_force = ent->linear_ground_friction;
|
||||||
def.max_torque = ent->angular_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 (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)) {
|
if (ctx->is_master && !sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
joint_ent = sim_ent_alloc_local(root);
|
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_MOTOR_JOINT);
|
||||||
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_ACTIVE);
|
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_ACTIVE);
|
||||||
joint_ent->motor_joint_data = phys_motor_joint_from_def(def);
|
joint_ent->motor_joint_data = phys_motor_joint_from_def(def);
|
||||||
ent->ground_friction_joint = joint_ent->id;
|
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
|
* Create mouse joints from client debug drag
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
|
if (ctx->is_master) {
|
||||||
struct sim_ent *client_ent = &world->ents[i];
|
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
|
||||||
if (!sim_ent_is_valid_and_active(client_ent)) continue;
|
struct sim_ent *client_ent = &world->ents[i];
|
||||||
if (!sim_ent_should_simulate(client_ent)) continue;
|
if (!sim_ent_should_simulate(client_ent)) continue;
|
||||||
if (!sim_ent_has_prop(client_ent, SIM_ENT_PROP_CLIENT)) continue;
|
if (!sim_ent_has_prop(client_ent, SIM_ENT_PROP_CLIENT)) continue;
|
||||||
|
|
||||||
struct v2 cursor = client_ent->client_cursor_pos;
|
struct v2 cursor = client_ent->client_cursor_pos;
|
||||||
b32 start_dragging = client_ent->client_dbg_drag_start;
|
b32 start_dragging = client_ent->client_dbg_drag_start;
|
||||||
b32 stop_dragging = client_ent->client_dbg_drag_stop;
|
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 *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 *target_ent = sim_ent_from_id(world, joint_ent->mouse_joint_data.target);
|
||||||
|
|
||||||
if (stop_dragging) {
|
if (stop_dragging) {
|
||||||
target_ent = sim_ent_nil();
|
target_ent = sim_ent_nil();
|
||||||
} else if (start_dragging) {
|
} else if (start_dragging) {
|
||||||
target_ent = sim_ent_from_id(world, client_ent->client_hovered_ent);
|
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);
|
|
||||||
}
|
}
|
||||||
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;
|
if (sim_ent_should_simulate(target_ent)) {
|
||||||
def.target = target_ent->id;
|
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
if (sim_ent_id_eq(joint_ent->mouse_joint_data.target, target_ent->id)) {
|
/* FIXME: Joint ent may never release */
|
||||||
def.point_local_start = joint_ent->mouse_joint_data.point_local_start;
|
joint_ent = sim_ent_alloc_sync_src(root);
|
||||||
} else {
|
joint_ent->mass_unscaled = F32_INFINITY;
|
||||||
def.point_local_start = xform_invert_mul_v2(xf, cursor);
|
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
|
* Physics step
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
if (ctx->is_master) {
|
{
|
||||||
struct phys_step_ctx phys = ZI;
|
struct phys_step_ctx phys = ZI;
|
||||||
phys.sim_step_ctx = ctx;
|
phys.sim_step_ctx = ctx;
|
||||||
phys.pre_solve_callback = on_collision;
|
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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[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_should_simulate(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_TRACER)) 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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[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_should_simulate(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_BULLET)) 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 */
|
/* Initialize tracer */
|
||||||
struct sim_ent *tracer = sim_ent_from_id(world, ent->bullet_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_set_xform(tracer, xf);
|
||||||
sim_ent_enable_prop(tracer, SIM_ENT_PROP_PHYSICAL_KINEMATIC);
|
sim_ent_enable_prop(tracer, SIM_ENT_PROP_PHYSICAL_KINEMATIC);
|
||||||
sim_ent_set_linear_velocity(tracer, ent->linear_velocity);
|
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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[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_should_simulate(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_CAMERA)) 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;
|
ent->shake = 0;
|
||||||
for (u64 quake_ent_index = 0; quake_ent_index < world->num_ents_reserved; ++quake_ent_index) {
|
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];
|
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;
|
if (!sim_ent_has_prop(quake, SIM_ENT_PROP_QUAKE)) continue;
|
||||||
ent->shake += quake->quake_intensity;
|
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) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[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_should_simulate(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_QUAKE)) 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;
|
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)) {
|
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;
|
child->final_layer = parent_layer + child->layer;
|
||||||
*arena_push(temp.arena, struct sim_ent *) = child;
|
*arena_push(temp.arena, struct sim_ent *) = child;
|
||||||
++stack_count;
|
++stack_count;
|
||||||
|
|||||||
118
src/user.c
118
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(" 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_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)) {
|
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);
|
struct sim_ent *child = sim_ent_from_id(ss, ent->first);
|
||||||
if (!sim_ent_id_eq(ent->first, ent->last) || !child->valid) {
|
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;
|
res.len += string_format(arena, LIT("last child: [%F]\n"), FMT_UID(ent->last.uid)).len;
|
||||||
}
|
}
|
||||||
while (child->valid) {
|
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);
|
struct string child_text = get_ent_debug_text(scratch.arena, child);
|
||||||
res.len += string_indent(arena, child_text, 4).len;
|
res.len += string_indent(arena, child_text, 4).len;
|
||||||
child = sim_ent_from_id(ss, child->next);
|
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) {
|
if (!control_cmd_ent->valid) {
|
||||||
control_cmd_ent = sim_ent_alloc_sync_src(user_input_root);
|
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_CMD_CONTROL);
|
||||||
|
sim_ent_enable_prop(control_cmd_ent, SIM_ENT_PROP_SYNC_PREDICT);
|
||||||
sim_ent_activate(control_cmd_ent, user_input_ss->tick);
|
sim_ent_activate(control_cmd_ent, user_input_ss->tick);
|
||||||
}
|
}
|
||||||
/* Update local control cmd ent */
|
/* 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 = sim_ent_alloc_sync_src(local_root);
|
||||||
client_ent->client_handle = client->handle;
|
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_CLIENT);
|
||||||
|
sim_ent_enable_prop(client_ent, SIM_ENT_PROP_SYNC_PREDICT);
|
||||||
sim_ent_enable_prop(client_ent, SIM_ENT_PROP_ACTIVE);
|
sim_ent_enable_prop(client_ent, SIM_ENT_PROP_ACTIVE);
|
||||||
client->ent_id = client_ent->id;
|
client->ent_id = client_ent->id;
|
||||||
if (client == user_input_client) {
|
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;
|
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) {
|
if (client_ss->valid) {
|
||||||
sim_snapshot_sync(local_ss, client_ss);
|
sim_snapshot_sync(local_ss, client_ss);
|
||||||
if (!is_master && client == master_client) {
|
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;
|
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 cmds to correct client ents */
|
||||||
/* Point incoming client cmds to correct client ents */
|
for (u64 i = 0; i < local_ss->num_ents_reserved; ++i) {
|
||||||
for (u64 i = 0; i < local_ss->num_ents_reserved; ++i) {
|
struct sim_ent *ent = &local_ss->ents[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)) {
|
||||||
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_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);
|
||||||
struct sim_ent *client_ent = sim_ent_from_id(local_ss, src_client->ent_id);
|
ent->cmd_client = 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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 */
|
/* 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 */
|
/* 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;
|
struct sim_snapshot *pub_ss;
|
||||||
if (is_master) {
|
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);
|
sim_snapshot_sync(pub_ss, local_ss);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user