prediction progress
This commit is contained in:
parent
a6d103f391
commit
2769e98450
@ -173,6 +173,8 @@ struct buddy_block *buddy_alloc(struct buddy_ctx *ctx, u64 size)
|
||||
|
||||
/* TODO: Minimum block size */
|
||||
|
||||
/* TODO: Faster MSB calculation */
|
||||
|
||||
u64 desired_block_size = 1;
|
||||
u64 desired_level_tier = 0;
|
||||
while (desired_block_size < size && desired_level_tier < 64) {
|
||||
|
||||
@ -16,7 +16,7 @@ struct buddy_block {
|
||||
|
||||
struct buddy_level {
|
||||
struct buddy_ctx *ctx;
|
||||
b32 backed; /* Is this level backed by memory in the ctx arena */
|
||||
b32 backed; /* Signals whether this level is backed by memory in the ctx arena */
|
||||
u32 tier;
|
||||
u64 size;
|
||||
struct buddy_block *first_unused_block;
|
||||
|
||||
10
src/host.c
10
src/host.c
@ -661,7 +661,7 @@ void host_update(struct host *host)
|
||||
struct sock_address address = packet->address;
|
||||
struct bitbuff bb = bitbuff_from_string(packet->data);
|
||||
struct bitbuff_reader br = br_from_bitbuff(&bb);
|
||||
u32 magic = br_read_ubits(&br, 32);
|
||||
u32 magic = br_read_ubits(&br, 32); /* TODO: implicitly encode magic into crc32 */
|
||||
if (magic == PACKET_MAGIC) {
|
||||
/* TODO: Combine kind byte with flags byte */
|
||||
struct host_channel *channel = host_channel_from_address(host, address);
|
||||
@ -864,7 +864,7 @@ void host_update(struct host *host)
|
||||
struct host_snd_packet *packet = host_channel_snd_packet_alloc(channel, false);
|
||||
struct bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
|
||||
struct bitbuff_writer bw = bw_from_bitbuff(&bb);
|
||||
bw_write_ubits(&bw, PACKET_MAGIC, 32);
|
||||
bw_write_ubits(&bw, PACKET_MAGIC, 32); /* TODO: implicitly encode magic into crc32 */
|
||||
bw_write_ibits(&bw, HOST_PACKET_KIND_TRY_CONNECT, 8);
|
||||
bw_write_ubits(&bw, packet_flags, 8);
|
||||
bw_write_uv(&bw, channel->our_acked_seq);
|
||||
@ -877,7 +877,7 @@ void host_update(struct host *host)
|
||||
struct host_snd_packet *packet = host_channel_snd_packet_alloc(channel, false);
|
||||
struct bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
|
||||
struct bitbuff_writer bw = bw_from_bitbuff(&bb);
|
||||
bw_write_ubits(&bw, PACKET_MAGIC, 32);
|
||||
bw_write_ubits(&bw, PACKET_MAGIC, 32); /* TODO: implicitly encode magic into crc32 */
|
||||
bw_write_ibits(&bw, HOST_PACKET_KIND_CONNECT_SUCCESS, 8);
|
||||
bw_write_ubits(&bw, packet_flags, 8);
|
||||
bw_write_uv(&bw, channel->our_acked_seq);
|
||||
@ -890,7 +890,7 @@ void host_update(struct host *host)
|
||||
struct host_snd_packet *packet = host_channel_snd_packet_alloc(channel, false);
|
||||
struct bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
|
||||
struct bitbuff_writer bw = bw_from_bitbuff(&bb);
|
||||
bw_write_ubits(&bw, PACKET_MAGIC, 32);
|
||||
bw_write_ubits(&bw, PACKET_MAGIC, 32); /* TODO: implicitly encode magic into crc32 */
|
||||
bw_write_ibits(&bw, HOST_PACKET_KIND_DISCONNECT, 8);
|
||||
bw_write_ubits(&bw, packet_flags, 8);
|
||||
bw_write_uv(&bw, channel->our_acked_seq);
|
||||
@ -922,7 +922,7 @@ void host_update(struct host *host)
|
||||
struct host_snd_packet *packet = host_channel_snd_packet_alloc(channel, is_reliable);
|
||||
struct bitbuff bb = bitbuff_from_string(STRING_FROM_ARRAY(packet->data));
|
||||
struct bitbuff_writer bw = bw_from_bitbuff(&bb);
|
||||
bw_write_ubits(&bw, PACKET_MAGIC, 32);
|
||||
bw_write_ubits(&bw, PACKET_MAGIC, 32); /* TODO: implicitly encode magic into crc32 */
|
||||
bw_write_ibits(&bw, HOST_PACKET_KIND_MSG_CHUNK, 8);
|
||||
bw_write_ubits(&bw, packet_flags, 8);
|
||||
bw_write_uv(&bw, channel->our_acked_seq);
|
||||
|
||||
44
src/phys.c
44
src/phys.c
@ -53,7 +53,7 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
|
||||
|
||||
for (u64 check0_index = 0; check0_index < ss->num_ents_reserved; ++check0_index) {
|
||||
struct sim_ent *check0 = &ss->ents[check0_index];
|
||||
if (!sim_ent_is_valid_and_active(check0)) continue;
|
||||
if (!sim_ent_should_simulate(check0)) continue;
|
||||
if (!(sim_ent_has_prop(check0, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(check0, SIM_ENT_PROP_PHYSICAL_KINEMATIC))) continue;
|
||||
if (check0->local_collider.count <= 0) continue;
|
||||
|
||||
@ -66,7 +66,7 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
|
||||
while ((space_entry = space_iter_next(&iter))) {
|
||||
struct sim_ent *check1 = sim_ent_from_id(ss, space_entry->ent);
|
||||
if (check1 == check0) continue;
|
||||
if (!sim_ent_is_valid_and_active(check1)) continue;
|
||||
if (!sim_ent_should_simulate(check1)) continue;
|
||||
if (!(sim_ent_has_prop(check1, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(check1, SIM_ENT_PROP_PHYSICAL_KINEMATIC))) continue;
|
||||
if (check1->local_collider.count <= 0) continue;
|
||||
|
||||
@ -274,7 +274,7 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration)
|
||||
|
||||
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];
|
||||
if (!sim_ent_is_valid_and_active(constraint_ent)) continue;
|
||||
if (!sim_ent_should_simulate(constraint_ent)) continue;
|
||||
if (!sim_ent_has_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) continue;
|
||||
|
||||
struct phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data;
|
||||
@ -282,7 +282,7 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration)
|
||||
u32 num_points = constraint->num_points;
|
||||
struct sim_ent *e0 = sim_ent_from_id(ss, constraint->e0);
|
||||
struct sim_ent *e1 = sim_ent_from_id(ss, constraint->e1);
|
||||
if (constraint->last_phys_iteration >= phys_iteration && num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) {
|
||||
if (constraint->last_phys_iteration >= phys_iteration && num_points > 0 && sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
|
||||
struct v2 normal = constraint->normal;
|
||||
struct v2 tangent = v2_perp(normal);
|
||||
|
||||
@ -392,7 +392,7 @@ void phys_warm_start_contacts(struct phys_step_ctx *ctx)
|
||||
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
||||
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];
|
||||
if (!sim_ent_is_valid_and_active(constraint_ent)) continue;
|
||||
if (!sim_ent_should_simulate(constraint_ent)) continue;
|
||||
if (!sim_ent_has_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) continue;
|
||||
|
||||
struct phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data;
|
||||
@ -401,7 +401,7 @@ void phys_warm_start_contacts(struct phys_step_ctx *ctx)
|
||||
struct sim_ent *e0 = sim_ent_from_id(ss, constraint->e0);
|
||||
struct sim_ent *e1 = sim_ent_from_id(ss, constraint->e1);
|
||||
|
||||
if (num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1) && !constraint->skip_solve) {
|
||||
if (num_points > 0 && sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1) && !constraint->skip_solve) {
|
||||
struct xform e0_xf = sim_ent_get_xform(e0);
|
||||
struct xform e1_xf = sim_ent_get_xform(e1);
|
||||
|
||||
@ -447,7 +447,7 @@ void phys_solve_contacts(struct phys_step_ctx *ctx, f32 dt, b32 apply_bias)
|
||||
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
||||
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];
|
||||
if (!sim_ent_is_valid_and_active(constraint_ent)) continue;
|
||||
if (!sim_ent_should_simulate(constraint_ent)) continue;
|
||||
if (!sim_ent_has_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) continue;
|
||||
|
||||
struct phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data;
|
||||
@ -461,7 +461,7 @@ void phys_solve_contacts(struct phys_step_ctx *ctx, f32 dt, b32 apply_bias)
|
||||
f32 w1 = e1->angular_velocity;
|
||||
|
||||
u32 num_points = constraint->num_points;
|
||||
if (num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1) && !constraint->skip_solve) {
|
||||
if (num_points > 0 && sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1) && !constraint->skip_solve) {
|
||||
struct xform e0_xf = sim_ent_get_xform(e0);
|
||||
struct xform e1_xf = sim_ent_get_xform(e1);
|
||||
|
||||
@ -578,7 +578,7 @@ void phys_prepare_motor_joints(struct phys_step_ctx *ctx)
|
||||
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
||||
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
|
||||
struct sim_ent *joint_ent = &ss->ents[sim_ent_index];
|
||||
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
|
||||
if (!sim_ent_should_simulate(joint_ent)) continue;
|
||||
if (!sim_ent_has_prop(joint_ent, SIM_ENT_PROP_MOTOR_JOINT)) continue;
|
||||
|
||||
struct phys_motor_joint *joint = &joint_ent->motor_joint_data;
|
||||
@ -586,7 +586,7 @@ void phys_prepare_motor_joints(struct phys_step_ctx *ctx)
|
||||
struct sim_ent *e0 = sim_ent_from_id(ss, joint->e0);
|
||||
struct sim_ent *e1 = sim_ent_from_id(ss, joint->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)) {
|
||||
struct xform e0_xf = sim_ent_get_xform(e0);
|
||||
struct xform e1_xf = sim_ent_get_xform(e1);
|
||||
|
||||
@ -642,7 +642,7 @@ void phys_warm_start_motor_joints(struct phys_step_ctx *ctx)
|
||||
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
||||
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
|
||||
struct sim_ent *joint_ent = &ss->ents[sim_ent_index];
|
||||
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
|
||||
if (!sim_ent_should_simulate(joint_ent)) continue;
|
||||
if (!sim_ent_has_prop(joint_ent, SIM_ENT_PROP_MOTOR_JOINT)) continue;
|
||||
|
||||
struct phys_motor_joint *joint = &joint_ent->motor_joint_data;
|
||||
@ -674,7 +674,7 @@ void phys_solve_motor_joints(struct phys_step_ctx *ctx, f32 dt)
|
||||
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
||||
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
|
||||
struct sim_ent *joint_ent = &ss->ents[sim_ent_index];
|
||||
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
|
||||
if (!sim_ent_should_simulate(joint_ent)) continue;
|
||||
if (!sim_ent_has_prop(joint_ent, SIM_ENT_PROP_MOTOR_JOINT)) continue;
|
||||
|
||||
struct phys_motor_joint *joint = &joint_ent->motor_joint_data;
|
||||
@ -767,12 +767,12 @@ void phys_prepare_mouse_joints(struct phys_step_ctx *ctx)
|
||||
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
||||
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
|
||||
struct sim_ent *joint_ent = &ss->ents[sim_ent_index];
|
||||
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
|
||||
if (!sim_ent_should_simulate(joint_ent)) continue;
|
||||
if (!sim_ent_has_prop(joint_ent, SIM_ENT_PROP_MOUSE_JOINT)) continue;
|
||||
|
||||
struct phys_mouse_joint *joint = &joint_ent->mouse_joint_data;
|
||||
struct sim_ent *ent = sim_ent_from_id(ss, joint->target);
|
||||
if (sim_ent_is_valid_and_active(ent)) {
|
||||
if (sim_ent_should_simulate(ent)) {
|
||||
struct xform xf = sim_ent_get_xform(ent);
|
||||
|
||||
/* TODO: Cache this */
|
||||
@ -814,12 +814,12 @@ void phys_warm_start_mouse_joints(struct phys_step_ctx *ctx)
|
||||
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
||||
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
|
||||
struct sim_ent *joint_ent = &ss->ents[sim_ent_index];
|
||||
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
|
||||
if (!sim_ent_should_simulate(joint_ent)) continue;
|
||||
if (!sim_ent_has_prop(joint_ent, SIM_ENT_PROP_MOUSE_JOINT)) continue;
|
||||
|
||||
struct phys_mouse_joint *joint = &joint_ent->mouse_joint_data;
|
||||
struct sim_ent *ent = sim_ent_from_id(ss, joint->target);
|
||||
if (sim_ent_is_valid_and_active(ent)) {
|
||||
if (sim_ent_should_simulate(ent)) {
|
||||
f32 inv_m = joint->inv_m;
|
||||
f32 inv_i = joint->inv_i;
|
||||
struct xform xf = sim_ent_get_xform(ent);
|
||||
@ -836,12 +836,12 @@ void phys_solve_mouse_joints(struct phys_step_ctx *ctx, f32 dt)
|
||||
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
||||
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
|
||||
struct sim_ent *joint_ent = &ss->ents[sim_ent_index];
|
||||
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
|
||||
if (!sim_ent_should_simulate(joint_ent)) continue;
|
||||
if (!sim_ent_has_prop(joint_ent, SIM_ENT_PROP_MOUSE_JOINT)) continue;
|
||||
|
||||
struct phys_mouse_joint *joint = &joint_ent->mouse_joint_data;
|
||||
struct sim_ent *ent = sim_ent_from_id(ss, joint->target);
|
||||
if (sim_ent_is_valid_and_active(ent)) {
|
||||
if (sim_ent_should_simulate(ent)) {
|
||||
struct v2 v = ent->linear_velocity;
|
||||
f32 w = ent->angular_velocity;
|
||||
|
||||
@ -923,7 +923,7 @@ void phys_integrate_forces(struct phys_step_ctx *ctx, f32 dt)
|
||||
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
||||
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)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
|
||||
b32 is_dynamic = sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC);
|
||||
b32 is_kinematic = sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_KINEMATIC);
|
||||
@ -965,7 +965,7 @@ void phys_integrate_velocities(struct phys_step_ctx *ctx, f32 dt)
|
||||
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
||||
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)) continue;
|
||||
if (!sim_ent_should_simulate(ent)) continue;
|
||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC) && !sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_KINEMATIC)) continue;
|
||||
|
||||
struct xform xf = get_derived_xform(ent, dt);
|
||||
@ -986,7 +986,7 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_step_ctx *ctx, f32 step_
|
||||
|
||||
for (u64 e0_index = 0; e0_index < ss->num_ents_reserved; ++e0_index) {
|
||||
struct sim_ent *e0 = &ss->ents[e0_index];
|
||||
if (!sim_ent_is_valid_and_active(e0)) continue;
|
||||
if (!sim_ent_should_simulate(e0)) continue;
|
||||
if (!(sim_ent_has_prop(e0, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e0, SIM_ENT_PROP_PHYSICAL_KINEMATIC))) continue;
|
||||
if (!sim_ent_has_prop(e0, SIM_ENT_PROP_BULLET)) continue;
|
||||
if (e0->local_collider.count <= 0) continue;
|
||||
@ -1005,7 +1005,7 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_step_ctx *ctx, f32 step_
|
||||
while ((entry = space_iter_next(&iter))) {
|
||||
struct sim_ent *e1 = sim_ent_from_id(ss, entry->ent);
|
||||
if (e1 == e0) continue;
|
||||
if (!sim_ent_is_valid_and_active(e1)) continue;
|
||||
if (!sim_ent_should_simulate(e1)) continue;
|
||||
if (!(sim_ent_has_prop(e1, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e1, SIM_ENT_PROP_PHYSICAL_KINEMATIC))) continue;
|
||||
if (e1->local_collider.count <= 0) continue;
|
||||
|
||||
|
||||
19
src/sim.c
19
src/sim.c
@ -10,17 +10,26 @@
|
||||
*
|
||||
* Client store -> clients -> snapshots -> ents
|
||||
*
|
||||
* A client store holds clients, which can be retrieved by client handle or by a host channel id (if one is set).
|
||||
* A client store holds clients, which can be retrieved by client handle or by a host channel id (if one is assigned).
|
||||
*
|
||||
* A client holds snapshots, which can be retrieved by tick (64 bit unsigned int).
|
||||
* A client holds snapshots, which can be retrieved by tick number.
|
||||
* - The snapshots stored in clients & the contents of those snapshots are determined from data transmitted by the client.
|
||||
* - Different kinds of clients will transmit different subsets of snapshot data (e.g. a master client will transmit most/all ent state, while slave clients may just transmit 1 or more cmds)
|
||||
* - Different kinds of clients will transmit different subsets of snapshot data (e.g. a master client will transmit most ent state, while slave clients may just transmit 1 or more command ents)
|
||||
* - A client will never hold more than one snapshot for the same tick (e.g. a client will never have 2 snapshots at tick 5)
|
||||
*
|
||||
* A snapshot holds the ent tree for a particular tick, in which ents can be retrieved by ent handle.
|
||||
* A snapshot holds the ent tree for a particular tick, in which ents can be retrieved by ent id.
|
||||
* - A tick is the quantized time step that all clients implicitly conform to.
|
||||
*
|
||||
* An ent is the smallest unit of simulation state.
|
||||
* - It is assigned a 128 bit unique identifer generated at allocation time.
|
||||
* - This id is used to refer to other ents in the tree and to sync ents accross clients.
|
||||
* - This id is usually random, but can be deterministic under certain conditions.
|
||||
* - For example, instead of storing a contact constraint lookup table, contact constraints are
|
||||
* retrieved by searching for the ent with the id resulting from combining the ent ids of the
|
||||
* two contacting entities (plus a unique 'basis' ent id used for all contact constraints).
|
||||
* - The ent also implicitly has a 32 bit index, which is just its offset from the start of the entity array in the local snapshot.
|
||||
* - Since index is based on offset which remains stable regardless of snapshot memory location, it
|
||||
* is used when working in contexts where id is irrelevant.
|
||||
*/
|
||||
|
||||
#define CLIENT_LOOKUP_BINS 127
|
||||
@ -590,7 +599,7 @@ struct sim_snapshot *sim_snapshot_alloc_from_lerp(struct sim_client *client, str
|
||||
* ========================== */
|
||||
|
||||
/* Syncs entity data between snapshots */
|
||||
void sim_snapshot_sync(struct sim_snapshot *local_ss, struct sim_snapshot *remote_ss)
|
||||
void sim_snapshot_sync_ents(struct sim_snapshot *local_ss, struct sim_snapshot *remote_ss)
|
||||
{
|
||||
__prof;
|
||||
|
||||
|
||||
@ -208,7 +208,7 @@ struct sim_snapshot *sim_snapshot_from_closest_tick_gte(struct sim_client *clien
|
||||
struct sim_snapshot *sim_snapshot_alloc_from_lerp(struct sim_client *client, struct sim_snapshot *ss0, struct sim_snapshot *ss1, f64 blend);
|
||||
|
||||
/* Sync */
|
||||
void sim_snapshot_sync(struct sim_snapshot *local_ss, struct sim_snapshot *remote_ss);
|
||||
void sim_snapshot_sync_ents(struct sim_snapshot *local_ss, struct sim_snapshot *remote_ss);
|
||||
|
||||
/* Encode / decode */
|
||||
void sim_snapshot_encode(struct bitbuff_writer *bw, struct sim_client *receiver, struct sim_snapshot *ss0, struct sim_snapshot *ss1);
|
||||
|
||||
@ -151,7 +151,7 @@ void sim_ent_release_all_with_prop(struct sim_snapshot *ss, enum sim_ent_prop pr
|
||||
* child entities will be released along with parent anyway) */
|
||||
for (u64 i = 0; i < ents_to_release_count; ++i) {
|
||||
struct sim_ent *ent = ents_to_release[i];
|
||||
if (ent->is_top && !ent->is_root && ent->valid) {
|
||||
if (ent->valid && !ent->is_root && !sim_ent_has_prop(ent, SIM_ENT_PROP_CMD_CONTROL) && !sim_ent_has_prop(ent, SIM_ENT_PROP_CLIENT)) {
|
||||
sim_ent_release(ent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,6 +342,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
struct sim_client *user_input_client = ctx->user_input_client;
|
||||
struct sim_client *publish_client = ctx->publish_client;
|
||||
struct sim_client *master_client = ctx->master_client;
|
||||
(UNUSED)master_client;
|
||||
|
||||
i64 sim_dt_ns = ctx->sim_dt_ns;
|
||||
|
||||
@ -361,6 +362,10 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
* Sync remote ents
|
||||
* ========================== */
|
||||
|
||||
if (user_input_client->valid) {
|
||||
user_input_client->ent_id = world->local_client_ent;
|
||||
}
|
||||
|
||||
{
|
||||
for (u64 client_index = 0; client_index < client_store->num_clients_reserved; ++client_index) {
|
||||
struct sim_client *client = &client_store->clients[client_index];
|
||||
@ -385,15 +390,9 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
}
|
||||
|
||||
/* Sync ents from client */
|
||||
{
|
||||
struct sim_snapshot *src_ss = sim_snapshot_from_tick(client, world->tick);
|
||||
if (src_ss->valid) {
|
||||
sim_snapshot_sync(world, src_ss);
|
||||
if (client == master_client) {
|
||||
world_client->ent_id = src_ss->local_client_ent;
|
||||
world->local_client_ent = src_ss->local_client_ent;
|
||||
}
|
||||
}
|
||||
struct sim_snapshot *src_ss = sim_snapshot_from_tick(client, world->tick);
|
||||
if (src_ss->valid) {
|
||||
sim_snapshot_sync_ents(world, src_ss);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1264,8 +1263,13 @@ void sim_step(struct sim_step_ctx *ctx)
|
||||
if (!pub_world->valid) {
|
||||
struct sim_snapshot *prev_pub_world = sim_snapshot_from_tick(publish_client, publish_client->last_tick);
|
||||
pub_world = sim_snapshot_alloc(publish_client, prev_pub_world, world->tick);
|
||||
/* Sync */
|
||||
sim_snapshot_sync_ents(pub_world, world);
|
||||
pub_world->sim_dt_ns = world->sim_dt_ns;
|
||||
pub_world->sim_time_ns = world->sim_time_ns;
|
||||
pub_world->continuity_gen = world->continuity_gen;
|
||||
pub_world->phys_iteration = world->phys_iteration;
|
||||
pub_world->local_client_ent = world->local_client_ent;
|
||||
sim_snapshot_sync(pub_world, world);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
15
src/user.c
15
src/user.c
@ -1982,7 +1982,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
||||
struct sim_snapshot *base_ss = sim_snapshot_from_tick(client, base_tick);
|
||||
if (base_ss->tick == base_tick) {
|
||||
if (is_master) {
|
||||
/* Decode incoming slave client snapshots */
|
||||
/* Queue incoming slave client snapshot for decoding */
|
||||
b32 should_decode = tick == client->highest_received_tick + 1 || client->highest_received_tick == 0;
|
||||
if (should_decode) {
|
||||
struct sim_ss_decode_node *node = arena_push_zero(scratch.arena, struct sim_ss_decode_node);
|
||||
@ -2000,8 +2000,8 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
||||
client->highest_received_tick = tick;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Decode incoming master client snapshots (only the newest one) */
|
||||
} else if (client == master_client) {
|
||||
/* Decode incoming master client snapshots for decoding (only the newest one) */
|
||||
b32 should_decode = tick > client->highest_received_tick;
|
||||
if (should_decode) {
|
||||
struct sim_ss_decode_node *node = queue.first ? queue.first : arena_push_zero(scratch.arena, struct sim_ss_decode_node);
|
||||
@ -2044,9 +2044,12 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
||||
/* Alloc & decode snapshot */
|
||||
struct sim_snapshot *ss = sim_snapshot_alloc(client, base_ss, tick);
|
||||
sim_snapshot_decode(&br, ss);
|
||||
|
||||
/* Assume all incoming ents want to be sync srcs */
|
||||
for (u64 i = 0; i < ss->num_ents_reserved; ++i) {
|
||||
struct sim_ent *ent = &ss->ents[i];
|
||||
if (ent->valid && sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST)) {
|
||||
|
||||
sim_ent_disable_prop(ent, SIM_ENT_PROP_SYNC_DST);
|
||||
sim_ent_enable_prop(ent, SIM_ENT_PROP_SYNC_SRC);
|
||||
}
|
||||
@ -2070,7 +2073,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
||||
/* Create user input */
|
||||
{
|
||||
struct sim_snapshot *prev_user_input_ss = sim_snapshot_from_tick(user_input_client, user_input_client->last_tick);
|
||||
struct sim_snapshot *user_input_ss = sim_snapshot_alloc(user_input_client, prev_user_input_ss, local_client->last_tick + ahead + 1);
|
||||
struct sim_snapshot *user_input_ss = sim_snapshot_alloc(user_input_client, prev_user_input_ss, local_client->last_tick + 1);
|
||||
struct sim_ent *user_input_root = sim_ent_from_id(user_input_ss, SIM_ENT_ROOT_ID);
|
||||
/* Find / create local control cmd ent */
|
||||
struct sim_ent *control_cmd_ent = sim_ent_find_first_match_one(user_input_ss, SIM_ENT_PROP_CMD_CONTROL);
|
||||
@ -2138,7 +2141,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
||||
}
|
||||
|
||||
/* Release unneeded user input snapshots */
|
||||
sim_snapshot_release_ticks_in_range(user_input_client, 0, local_client->last_tick - 1);
|
||||
sim_snapshot_release_ticks_in_range(user_input_client, 0, local_client->first_tick - 1);
|
||||
|
||||
|
||||
|
||||
@ -2237,7 +2240,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
||||
struct bitbuff_writer msg_bw = bw_from_bitbuff(&msg_writer_bb);
|
||||
|
||||
bw_write_uv(&msg_bw, client->highest_received_tick); /* ack */
|
||||
bw_write_uv(&msg_bw, client->ack); /* double ack */
|
||||
bw_write_uv(&msg_bw, client->ack); /* double ack */
|
||||
|
||||
struct sim_snapshot *base_ss = sim_snapshot_from_tick(publish_client, client->ack);
|
||||
struct sim_snapshot *publish_ss;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user