sim ctx decoupling progress
This commit is contained in:
parent
bc2dccb872
commit
f6aa25760e
36
src/phys.c
36
src/phys.c
@ -45,9 +45,11 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
|
|||||||
struct phys_collision_data_array res = ZI;
|
struct phys_collision_data_array res = ZI;
|
||||||
res.a = arena_dry_push(arena, struct phys_collision_data);
|
res.a = arena_dry_push(arena, struct phys_collision_data);
|
||||||
struct sim_snapshot *ss = ctx->ss;
|
struct sim_snapshot *ss = ctx->ss;
|
||||||
struct sim_ent_lookup *contact_lookup = ctx->contact_lookup;
|
struct sim_ent_lookup *contact_lookup = &ss->contact_lookup;
|
||||||
struct sim_ent_lookup *debug_lookup = ctx->debug_lookup;
|
struct space *space = ss->space;
|
||||||
struct space *space = ctx->space;
|
#if COLLIDER_DEBUG
|
||||||
|
struct sim_ent_lookup *debug_lookup = &ss->collision_debug_lookup;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct sim_ent *root = sim_ent_from_handle(ss, SIM_ENT_ROOT_HANDLE);
|
struct sim_ent *root = sim_ent_from_handle(ss, SIM_ENT_ROOT_HANDLE);
|
||||||
u64 tick = ss->tick;
|
u64 tick = ss->tick;
|
||||||
@ -271,8 +273,6 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
|
|||||||
dbg->closest1 = closest_points_res.p1;
|
dbg->closest1 = closest_points_res.p1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
(UNUSED)debug_lookup;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
space_iter_end(&iter);
|
space_iter_end(&iter);
|
||||||
@ -283,8 +283,8 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
|
|||||||
void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration)
|
void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct sim_ent_lookup *contact_lookup = ctx->contact_lookup;
|
|
||||||
struct sim_snapshot *ss = ctx->ss;
|
struct sim_snapshot *ss = ctx->ss;
|
||||||
|
struct sim_ent_lookup *contact_lookup = &ss->contact_lookup;
|
||||||
|
|
||||||
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
|
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];
|
struct sim_ent *constraint_ent = &ss->ents[sim_ent_index];
|
||||||
@ -985,6 +985,7 @@ void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt)
|
|||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct sim_snapshot *ss = ctx->ss;
|
struct sim_snapshot *ss = ctx->ss;
|
||||||
|
struct space *space = ss->space;
|
||||||
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
|
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];
|
struct sim_ent *ent = &ss->ents[sim_ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
@ -993,7 +994,7 @@ void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt)
|
|||||||
struct xform xf = get_derived_xform(ent, dt);
|
struct xform xf = get_derived_xform(ent, dt);
|
||||||
sim_ent_set_xform(ent, xf);
|
sim_ent_set_xform(ent, xf);
|
||||||
|
|
||||||
struct space_entry *space_entry = space_entry_from_handle(ctx->space, ent->space_handle);
|
struct space_entry *space_entry = space_entry_from_handle(space, ent->space_handle);
|
||||||
if (space_entry->valid) {
|
if (space_entry->valid) {
|
||||||
space_entry_update_aabb(space_entry, collider_aabb_from_collider(&ent->local_collider, xf));
|
space_entry_update_aabb(space_entry, collider_aabb_from_collider(&ent->local_collider, xf));
|
||||||
}
|
}
|
||||||
@ -1008,7 +1009,7 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f
|
|||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct sim_snapshot *ss = ctx->ss;
|
struct sim_snapshot *ss = ctx->ss;
|
||||||
struct space *space = ctx->space;
|
struct space *space = ss->space;
|
||||||
f32 smallest_t = 1;
|
f32 smallest_t = 1;
|
||||||
|
|
||||||
for (u64 e0_index = 0; e0_index < ss->num_ents_reserved; ++e0_index) {
|
for (u64 e0_index = 0; e0_index < ss->num_ents_reserved; ++e0_index) {
|
||||||
@ -1058,15 +1059,16 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f
|
|||||||
void phys_update_aabbs(struct phys_ctx *ctx)
|
void phys_update_aabbs(struct phys_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct sim_snapshot *ss = ctx->ss;
|
struct sim_snapshot *ss = ctx->ss;
|
||||||
|
struct space *space = ss->space;
|
||||||
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
|
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];
|
struct sim_ent *ent = &ss->ents[sim_ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
if (ent->local_collider.count <= 0) continue;
|
if (ent->local_collider.count <= 0) continue;
|
||||||
|
|
||||||
struct xform xf = sim_ent_get_xform(ent);
|
struct xform xf = sim_ent_get_xform(ent);
|
||||||
struct space_entry *space_entry = space_entry_from_handle(ctx->space, ent->space_handle);
|
struct space_entry *space_entry = space_entry_from_handle(space, ent->space_handle);
|
||||||
if (!space_entry->valid) {
|
if (!space_entry->valid) {
|
||||||
space_entry = space_entry_alloc(ctx->space, ent->handle);
|
space_entry = space_entry_alloc(space, ent->handle);
|
||||||
ent->space_handle = space_entry->handle;
|
ent->space_handle = space_entry->handle;
|
||||||
}
|
}
|
||||||
space_entry_update_aabb(space_entry, collider_aabb_from_collider(&ent->local_collider, xf));
|
space_entry_update_aabb(space_entry, collider_aabb_from_collider(&ent->local_collider, xf));
|
||||||
@ -1078,11 +1080,13 @@ void phys_update_aabbs(struct phys_ctx *ctx)
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
/* Returns phys iteration to be fed into next step. Supplied iteration must be > 0. */
|
/* Returns phys iteration to be fed into next step. Supplied iteration must be > 0. */
|
||||||
u64 phys_step(struct phys_ctx *ctx, f32 timestep, u64 last_iteration)
|
void phys_step(struct phys_ctx *ctx, f32 timestep)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
phys_integrate_forces(ctx, timestep);
|
phys_integrate_forces(ctx, timestep);
|
||||||
u64 phys_iteration = last_iteration;
|
u64 phys_iteration = ctx->ss->phys_iteration;
|
||||||
|
|
||||||
|
phys_update_aabbs(ctx);
|
||||||
|
|
||||||
f32 remaining_dt = timestep;
|
f32 remaining_dt = timestep;
|
||||||
while (remaining_dt > 0) {
|
while (remaining_dt > 0) {
|
||||||
@ -1090,8 +1094,6 @@ u64 phys_step(struct phys_ctx *ctx, f32 timestep, u64 last_iteration)
|
|||||||
++phys_iteration;
|
++phys_iteration;
|
||||||
struct temp_arena scratch = scratch_begin_no_conflict();
|
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||||
|
|
||||||
phys_update_aabbs(ctx);
|
|
||||||
|
|
||||||
/* TOI */
|
/* TOI */
|
||||||
f32 step_dt = remaining_dt;
|
f32 step_dt = remaining_dt;
|
||||||
{
|
{
|
||||||
@ -1115,7 +1117,7 @@ u64 phys_step(struct phys_ctx *ctx, f32 timestep, u64 last_iteration)
|
|||||||
|
|
||||||
if (ctx->pre_solve_callback) {
|
if (ctx->pre_solve_callback) {
|
||||||
__profscope(pre_solve_callback);
|
__profscope(pre_solve_callback);
|
||||||
ctx->pre_solve_callback(collision_data, ctx->pre_solve_callback_udata);
|
ctx->pre_solve_callback(collision_data, ctx->ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 substep_dt = step_dt / SIM_PHYSICS_SUBSTEPS;
|
f32 substep_dt = step_dt / SIM_PHYSICS_SUBSTEPS;
|
||||||
@ -1147,11 +1149,11 @@ u64 phys_step(struct phys_ctx *ctx, f32 timestep, u64 last_iteration)
|
|||||||
|
|
||||||
if (ctx->post_solve_callback) {
|
if (ctx->post_solve_callback) {
|
||||||
__profscope(post_solve_callback);
|
__profscope(post_solve_callback);
|
||||||
ctx->post_solve_callback(collision_data, ctx->post_solve_callback_udata);
|
ctx->post_solve_callback(collision_data, ctx->ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
return phys_iteration;
|
ctx->ss->phys_iteration = phys_iteration;
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/phys.h
15
src/phys.h
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
struct space;
|
struct space;
|
||||||
struct sim_ent_lookup;
|
struct sim_ent_lookup;
|
||||||
|
struct sim_snapshot;
|
||||||
|
|
||||||
struct phys_contact_constraint;
|
struct phys_contact_constraint;
|
||||||
struct phys_collision_data {
|
struct phys_collision_data {
|
||||||
@ -24,22 +25,14 @@ struct phys_collision_data_array {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct phys_collision_data;
|
struct phys_collision_data;
|
||||||
#define PHYS_COLLISION_CALLBACK_FUNC_DEF(name, arg_collision_data, arg_udata) void name(struct phys_collision_data_array arg_collision_data, void *arg_udata)
|
#define PHYS_COLLISION_CALLBACK_FUNC_DEF(name, arg_collision_data, arg_ss) void name(struct phys_collision_data_array arg_collision_data, struct sim_snapshot *arg_ss)
|
||||||
typedef PHYS_COLLISION_CALLBACK_FUNC_DEF(phys_collision_callback_func, collision_data, udata);
|
typedef PHYS_COLLISION_CALLBACK_FUNC_DEF(phys_collision_callback_func, collision_data, ss);
|
||||||
|
|
||||||
/* Structure containing data used for a single physics step */
|
/* Structure containing data used for a single physics step */
|
||||||
struct phys_ctx {
|
struct phys_ctx {
|
||||||
struct sim_snapshot *ss;
|
struct sim_snapshot *ss;
|
||||||
struct space *space;
|
|
||||||
struct sim_ent_lookup *contact_lookup;
|
|
||||||
|
|
||||||
phys_collision_callback_func *pre_solve_callback;
|
phys_collision_callback_func *pre_solve_callback;
|
||||||
phys_collision_callback_func *post_solve_callback;
|
phys_collision_callback_func *post_solve_callback;
|
||||||
void *pre_solve_callback_udata;
|
|
||||||
void *post_solve_callback_udata;
|
|
||||||
|
|
||||||
struct sim_ent_lookup *debug_lookup;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -208,6 +201,6 @@ void phys_update_aabbs(struct phys_ctx *ctx);
|
|||||||
* Step
|
* Step
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
u64 phys_step(struct phys_ctx *ctx, f32 timestep, u64 phys_iteration);
|
void phys_step(struct phys_ctx *ctx, f32 timestep);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
292
src/sim.c
292
src/sim.c
@ -21,6 +21,7 @@
|
|||||||
* Ctx
|
* Ctx
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
|
#if 0
|
||||||
struct sim_ctx *sim_ctx_alloc(struct sprite_startup_receipt *sprite_sr,
|
struct sim_ctx *sim_ctx_alloc(struct sprite_startup_receipt *sprite_sr,
|
||||||
struct phys_startup_receipt *phys_sr,
|
struct phys_startup_receipt *phys_sr,
|
||||||
struct host_startup_receipt *host_sr,
|
struct host_startup_receipt *host_sr,
|
||||||
@ -37,10 +38,10 @@ struct sim_ctx *sim_ctx_alloc(struct sprite_startup_receipt *sprite_sr,
|
|||||||
(UNUSED)sim_snapshot_sr;
|
(UNUSED)sim_snapshot_sr;
|
||||||
|
|
||||||
/* Intialize host */
|
/* Intialize host */
|
||||||
ctx->host = host_alloc(host_port);
|
host = host_alloc(host_port);
|
||||||
|
|
||||||
/* Allocate encoder bitbuff */
|
/* Allocate encoder bitbuff */
|
||||||
ctx->encoder_bitbuff = bitbuff_alloc(GIGABYTE(64));
|
encoder_bitbuff = bitbuff_alloc(GIGABYTE(64));
|
||||||
|
|
||||||
/* Create bookkeeping */
|
/* Create bookkeeping */
|
||||||
ctx->contact_lookup = sim_ent_lookup_alloc(4096);
|
ctx->contact_lookup = sim_ent_lookup_alloc(4096);
|
||||||
@ -50,8 +51,8 @@ struct sim_ctx *sim_ctx_alloc(struct sprite_startup_receipt *sprite_sr,
|
|||||||
ctx->space = space_alloc(SPACE_CELL_SIZE, SPACE_CELL_BUCKETS_SQRT);
|
ctx->space = space_alloc(SPACE_CELL_SIZE, SPACE_CELL_BUCKETS_SQRT);
|
||||||
|
|
||||||
/* Create snapshot store */
|
/* Create snapshot store */
|
||||||
ctx->snapshot_store = sim_snapshot_store_alloc();
|
snapshot_store = sim_snapshot_store_alloc();
|
||||||
ctx->world = sim_snapshot_nil();
|
world = sim_snapshot_nil();
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
@ -61,7 +62,7 @@ void sim_ctx_release(struct sim_ctx *ctx)
|
|||||||
__prof;
|
__prof;
|
||||||
|
|
||||||
/* Release snapshot store */
|
/* Release snapshot store */
|
||||||
sim_snapshot_store_release(ctx->snapshot_store);
|
sim_snapshot_store_release(snapshot_store);
|
||||||
|
|
||||||
/* Release bookkeeping */
|
/* Release bookkeeping */
|
||||||
space_release(ctx->space);
|
space_release(ctx->space);
|
||||||
@ -71,13 +72,14 @@ void sim_ctx_release(struct sim_ctx *ctx)
|
|||||||
sim_ent_lookup_release(&ctx->contact_lookup);
|
sim_ent_lookup_release(&ctx->contact_lookup);
|
||||||
|
|
||||||
/* Release encoder bitbuff */
|
/* Release encoder bitbuff */
|
||||||
bitbuff_release(&ctx->encoder_bitbuff);
|
bitbuff_release(&encoder_bitbuff);
|
||||||
|
|
||||||
/* Release host */
|
/* Release host */
|
||||||
host_release(ctx->host);
|
host_release(host);
|
||||||
|
|
||||||
arena_release(&ctx->arena);
|
arena_release(&ctx->arena);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Test
|
* Test
|
||||||
@ -85,9 +87,9 @@ void sim_ctx_release(struct sim_ctx *ctx)
|
|||||||
|
|
||||||
/* TODO: Remove this */
|
/* TODO: Remove this */
|
||||||
|
|
||||||
INTERNAL void spawn_test_entities(struct sim_ctx *ctx, struct v2 offset)
|
INTERNAL void spawn_test_entities(struct sim_snapshot *world, struct v2 offset)
|
||||||
{
|
{
|
||||||
struct sim_ent *root = sim_ent_from_handle(ctx->world, SIM_ENT_ROOT_HANDLE);
|
struct sim_ent *root = sim_ent_from_handle(world, SIM_ENT_ROOT_HANDLE);
|
||||||
root->mass_unscaled = F32_INFINITY;
|
root->mass_unscaled = F32_INFINITY;
|
||||||
root->inertia_unscaled = F32_INFINITY;
|
root->inertia_unscaled = F32_INFINITY;
|
||||||
|
|
||||||
@ -161,9 +163,9 @@ INTERNAL void spawn_test_entities(struct sim_ctx *ctx, struct v2 offset)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL struct sim_ent *spawn_test_player(struct sim_ctx *ctx)
|
INTERNAL struct sim_ent *spawn_test_player(struct sim_snapshot *world)
|
||||||
{
|
{
|
||||||
struct sim_ent *root = sim_ent_from_handle(ctx->world, SIM_ENT_ROOT_HANDLE);
|
struct sim_ent *root = sim_ent_from_handle(world, SIM_ENT_ROOT_HANDLE);
|
||||||
|
|
||||||
/* Player */
|
/* Player */
|
||||||
struct sim_ent *player_ent = sim_ent_nil();
|
struct sim_ent *player_ent = sim_ent_nil();
|
||||||
@ -236,9 +238,9 @@ INTERNAL struct sim_ent *spawn_test_player(struct sim_ctx *ctx)
|
|||||||
return player_ent;
|
return player_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL struct sim_ent *spawn_test_player_camera(struct sim_ctx *ctx, struct sim_ent *player_ent)
|
INTERNAL struct sim_ent *spawn_test_player_camera(struct sim_snapshot *world, struct sim_ent *player_ent)
|
||||||
{
|
{
|
||||||
struct sim_ent *root = sim_ent_from_handle(ctx->world, SIM_ENT_ROOT_HANDLE);
|
struct sim_ent *root = sim_ent_from_handle(world, SIM_ENT_ROOT_HANDLE);
|
||||||
|
|
||||||
struct sim_ent *camera_ent = sim_ent_nil();
|
struct sim_ent *camera_ent = sim_ent_nil();
|
||||||
if (player_ent->valid) {
|
if (player_ent->valid) {
|
||||||
@ -257,10 +259,10 @@ INTERNAL struct sim_ent *spawn_test_player_camera(struct sim_ctx *ctx, struct si
|
|||||||
return camera_ent;
|
return camera_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void test_clear_level(struct sim_ctx *ctx)
|
INTERNAL void test_clear_level(struct sim_snapshot *world)
|
||||||
{
|
{
|
||||||
for (u64 j = 0; j < ctx->world->num_ents_reserved; ++j) {
|
for (u64 j = 0; j < world->num_ents_reserved; ++j) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[j];
|
struct sim_ent *ent = &world->ents[j];
|
||||||
if (ent->valid) {
|
if (ent->valid) {
|
||||||
sim_ent_enable_prop(ent, SIM_ENT_PROP_RELEASE_NEXT_TICK);
|
sim_ent_enable_prop(ent, SIM_ENT_PROP_RELEASE_NEXT_TICK);
|
||||||
}
|
}
|
||||||
@ -271,15 +273,15 @@ INTERNAL void test_clear_level(struct sim_ctx *ctx)
|
|||||||
* Release entities
|
* Release entities
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INTERNAL void release_entities_with_prop(struct sim_ctx *ctx, enum sim_ent_prop prop)
|
INTERNAL void release_entities_with_prop(struct sim_snapshot *world, enum sim_ent_prop prop)
|
||||||
{
|
{
|
||||||
struct temp_arena scratch = scratch_begin_no_conflict();
|
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||||
struct space *space = ctx->space;
|
struct space *space = world->space;
|
||||||
|
|
||||||
struct sim_ent **ents_to_release = arena_dry_push(scratch.arena, struct sim_ent *);
|
struct sim_ent **ents_to_release = arena_dry_push(scratch.arena, struct sim_ent *);
|
||||||
u64 ents_to_release_count = 0;
|
u64 ents_to_release_count = 0;
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (ent->valid && sim_ent_has_prop(ent, prop)) {
|
if (ent->valid && sim_ent_has_prop(ent, prop)) {
|
||||||
*arena_push(scratch.arena, struct sim_ent *) = ent;
|
*arena_push(scratch.arena, struct sim_ent *) = ent;
|
||||||
++ents_to_release_count;
|
++ents_to_release_count;
|
||||||
@ -315,17 +317,16 @@ INTERNAL void release_entities_with_prop(struct sim_ctx *ctx, enum sim_ent_prop
|
|||||||
* Respond to physics collisions
|
* Respond to physics collisions
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, udata)
|
INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, world)
|
||||||
{
|
{
|
||||||
struct sim_ctx *ctx = (struct sim_ctx *)udata;
|
struct sim_ent *root = sim_ent_from_handle(world, SIM_ENT_ROOT_HANDLE);
|
||||||
struct sim_ent *root = sim_ent_from_handle(ctx->world, SIM_ENT_ROOT_HANDLE);
|
|
||||||
|
|
||||||
for (u64 i = 0; i < collision_data_array.count; ++i) {
|
for (u64 i = 0; i < collision_data_array.count; ++i) {
|
||||||
struct phys_collision_data *data = &collision_data_array.a[i];
|
struct phys_collision_data *data = &collision_data_array.a[i];
|
||||||
|
|
||||||
struct phys_contact_constraint *constraint = data->constraint;
|
struct phys_contact_constraint *constraint = data->constraint;
|
||||||
struct sim_ent *e0 = sim_ent_from_handle(ctx->world, data->e0);
|
struct sim_ent *e0 = sim_ent_from_handle(world, data->e0);
|
||||||
struct sim_ent *e1 = sim_ent_from_handle(ctx->world, data->e1);
|
struct sim_ent *e1 = sim_ent_from_handle(world, data->e1);
|
||||||
|
|
||||||
if (sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) {
|
if (sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) {
|
||||||
/* Bullet hit entity */
|
/* Bullet hit entity */
|
||||||
@ -341,7 +342,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, ud
|
|||||||
normal = v2_neg(normal);
|
normal = v2_neg(normal);
|
||||||
vrel = v2_neg(vrel);
|
vrel = v2_neg(vrel);
|
||||||
}
|
}
|
||||||
struct sim_ent *src = sim_ent_from_handle(ctx->world, bullet->bullet_src);
|
struct sim_ent *src = sim_ent_from_handle(world, bullet->bullet_src);
|
||||||
|
|
||||||
if (bullet->bullet_has_hit || sim_ent_handle_eq(src->top, target->top)) {
|
if (bullet->bullet_has_hit || sim_ent_handle_eq(src->top, target->top)) {
|
||||||
/* Ignore collision if bullet already spent or if weapon and
|
/* Ignore collision if bullet already spent or if weapon and
|
||||||
@ -356,7 +357,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, ud
|
|||||||
sim_ent_enable_prop(bullet, SIM_ENT_PROP_RELEASE_THIS_TICK);
|
sim_ent_enable_prop(bullet, SIM_ENT_PROP_RELEASE_THIS_TICK);
|
||||||
|
|
||||||
/* Update tracer */
|
/* Update tracer */
|
||||||
struct sim_ent *tracer = sim_ent_from_handle(ctx->world, bullet->bullet_tracer);
|
struct sim_ent *tracer = sim_ent_from_handle(world, bullet->bullet_tracer);
|
||||||
if (sim_ent_is_valid_and_active(tracer)) {
|
if (sim_ent_is_valid_and_active(tracer)) {
|
||||||
struct xform xf = sim_ent_get_xform(tracer);
|
struct xform xf = sim_ent_get_xform(tracer);
|
||||||
xf.og = point;
|
xf.og = point;
|
||||||
@ -402,61 +403,50 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, ud
|
|||||||
* Update
|
* Update
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
void sim_step(struct host *host, struct bitbuff *encoder_bitbuff, struct sim_snapshot_store *snapshot_store, struct sim_snapshot *prev_snapshot, i64 real_dt_ns, struct sim_cmd_list user_sim_cmds)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
|
|
||||||
{
|
|
||||||
__profscope(sim_update_sleep);
|
|
||||||
sleep_frame(ctx->last_tick_ns, target_dt_ns);
|
|
||||||
ctx->last_tick_ns = sys_time_ns();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct temp_arena scratch = scratch_begin_no_conflict();
|
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Begin frame
|
* Begin frame
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
struct sim_snapshot *prev_snapshot = ctx->world;
|
struct sim_snapshot *world = sim_snapshot_alloc(snapshot_store, prev_snapshot, prev_snapshot->tick + 1);
|
||||||
ctx->world = sim_snapshot_alloc(ctx->snapshot_store, prev_snapshot, prev_snapshot->tick + 1);
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Release old snapshots */
|
/* Release old snapshots */
|
||||||
{
|
{
|
||||||
/* TODO: Something better */
|
/* TODO: Something better */
|
||||||
i64 release_tick = (i64)ctx->world->tick - 25; /* Arbitrary tick offset */
|
i64 release_tick = (i64)world->tick - 25; /* Arbitrary tick offset */
|
||||||
if (release_tick > 0) {
|
if (release_tick > 0) {
|
||||||
struct sim_snapshot *old = sim_snapshot_from_tick(ctx->snapshot_store, release_tick);
|
struct sim_snapshot *old = sim_snapshot_from_tick(snapshot_store, release_tick);
|
||||||
if (old->valid) {
|
if (old->valid) {
|
||||||
sim_snapshot_release(old);
|
sim_snapshot_release(old);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
world->real_dt_ns = max_i64(0, real_dt_ns);
|
||||||
|
world->real_time_ns += world->real_dt_ns;
|
||||||
|
|
||||||
ctx->world->real_dt_ns = max_i64(0, target_dt_ns);
|
world->world_timescale = SIM_TIMESCALE;
|
||||||
ctx->world->real_time_ns += ctx->world->real_dt_ns;
|
world->world_dt_ns = max_i64(0, real_dt_ns * world->world_timescale);
|
||||||
|
world->world_time_ns += world->world_dt_ns;
|
||||||
|
|
||||||
ctx->world->world_timescale = SIM_TIMESCALE;
|
f64 real_dt = SECONDS_FROM_NS(world->real_dt_ns);
|
||||||
ctx->world->world_dt_ns = max_i64(0, target_dt_ns * ctx->world->world_timescale);
|
f64 real_time = SECONDS_FROM_NS(world->real_time_ns);
|
||||||
ctx->world->world_time_ns += ctx->world->world_dt_ns;
|
f64 world_dt = SECONDS_FROM_NS(world->world_dt_ns);
|
||||||
|
f64 world_time = SECONDS_FROM_NS(world->world_time_ns);
|
||||||
f64 sim_time = SECONDS_FROM_NS(ctx->world->world_time_ns);
|
|
||||||
ctx->sprite_frame_scope = sprite_scope_begin();
|
|
||||||
|
|
||||||
f64 real_dt = SECONDS_FROM_NS(ctx->world->real_dt_ns);
|
|
||||||
f64 real_time = SECONDS_FROM_NS(ctx->world->real_time_ns);
|
|
||||||
f64 world_dt = SECONDS_FROM_NS(ctx->world->world_dt_ns);
|
|
||||||
f64 world_time = SECONDS_FROM_NS(ctx->world->world_time_ns);
|
|
||||||
(UNUSED)real_dt;
|
(UNUSED)real_dt;
|
||||||
(UNUSED)real_time;
|
(UNUSED)real_time;
|
||||||
(UNUSED)world_dt;
|
(UNUSED)world_dt;
|
||||||
(UNUSED)world_time;
|
(UNUSED)world_time;
|
||||||
|
|
||||||
struct space *space = ctx->space;
|
struct sprite_scope *sprite_frame_scope = sprite_scope_begin();
|
||||||
struct sprite_scope *sprite_frame_scope = ctx->sprite_frame_scope;
|
|
||||||
|
|
||||||
struct sim_ent *root = sim_ent_from_handle(ctx->world, SIM_ENT_ROOT_HANDLE);
|
struct sim_ent *root = sim_ent_from_handle(world, SIM_ENT_ROOT_HANDLE);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Spawn test entities
|
* Spawn test entities
|
||||||
@ -468,7 +458,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
static b32 run = 0;
|
static b32 run = 0;
|
||||||
if (!run) {
|
if (!run) {
|
||||||
run = 1;
|
run = 1;
|
||||||
spawn_test_entities(ctx, V2(0, 0));
|
spawn_test_entities(world, V2(0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,20 +466,20 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Release entities
|
* Release entities
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
release_entities_with_prop(ctx, SIM_ENT_PROP_RELEASE_NEXT_TICK);
|
release_entities_with_prop(world, SIM_ENT_PROP_RELEASE_NEXT_TICK);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Activate entities
|
* Activate entities
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!ent->valid) continue;
|
if (!ent->valid) 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;
|
||||||
if (atick != 0 || ctx->world->tick >= atick) {
|
if (atick != 0 || world->tick >= atick) {
|
||||||
sim_ent_activate(ent, ctx->world->tick);
|
sim_ent_activate(ent, world->tick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -498,8 +488,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Reset triggered entities
|
* Reset triggered entities
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(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)) {
|
||||||
@ -510,14 +500,21 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Create user client if it doesn't exist
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
(UNUSED)user_sim_cmds;
|
||||||
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Process host events into sim cmds
|
* Process host events into sim cmds
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
struct sim_cmd_list *client_cmds;
|
struct sim_cmd_list *client_cmds;
|
||||||
{
|
{
|
||||||
host_update(ctx->host);
|
host_update(host);
|
||||||
struct host_event_array host_events = host_pop_events(scratch.arena, ctx->host);
|
struct host_event_array host_events = host_pop_events(scratch.arena, host);
|
||||||
|
|
||||||
struct sim_cmd_list sim_cmds = ZI;
|
struct sim_cmd_list sim_cmds = ZI;
|
||||||
sim_cmds_decode(scratch.arena, host_events, &sim_cmds);
|
sim_cmds_decode(scratch.arena, host_events, &sim_cmds);
|
||||||
@ -526,20 +523,20 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
for (struct sim_cmd *cmd = sim_cmds.first; cmd; cmd = cmd->next) {
|
for (struct sim_cmd *cmd = sim_cmds.first; cmd; cmd = cmd->next) {
|
||||||
enum sim_cmd_kind kind = cmd->kind;
|
enum sim_cmd_kind kind = cmd->kind;
|
||||||
struct host_channel_id channel_id = cmd->channel_id;
|
struct host_channel_id channel_id = cmd->channel_id;
|
||||||
struct sim_client *client = sim_client_from_channel_id(ctx->world, channel_id);
|
struct sim_client *client = sim_client_from_channel_id(world, channel_id);
|
||||||
if (!client->valid && kind == SIM_CMD_KIND_SIM_CLIENT_CONNECT && !host_channel_id_is_nil(channel_id)) {
|
if (!client->valid && kind == SIM_CMD_KIND_SIM_CLIENT_CONNECT && !host_channel_id_is_nil(channel_id)) {
|
||||||
client = sim_client_alloc(ctx->world, channel_id);
|
client = sim_client_alloc(world, channel_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Split cmds by client */
|
/* Split cmds by client */
|
||||||
client_cmds = arena_push_array_zero(scratch.arena, struct sim_cmd_list, ctx->world->num_clients_reserved);
|
client_cmds = arena_push_array_zero(scratch.arena, struct sim_cmd_list, world->num_clients_reserved);
|
||||||
{
|
{
|
||||||
struct sim_cmd *cmd = sim_cmds.first;
|
struct sim_cmd *cmd = sim_cmds.first;
|
||||||
while (cmd) {
|
while (cmd) {
|
||||||
struct sim_cmd *next = cmd->next;
|
struct sim_cmd *next = cmd->next;
|
||||||
struct host_channel_id channel_id = cmd->channel_id;
|
struct host_channel_id channel_id = cmd->channel_id;
|
||||||
struct sim_client *client = sim_client_from_channel_id(ctx->world, channel_id);
|
struct sim_client *client = sim_client_from_channel_id(world, channel_id);
|
||||||
if (client->valid) {
|
if (client->valid) {
|
||||||
struct sim_cmd_list *cmd_list = &client_cmds[client->handle.idx];
|
struct sim_cmd_list *cmd_list = &client_cmds[client->handle.idx];
|
||||||
if (cmd_list->last) {
|
if (cmd_list->last) {
|
||||||
@ -560,9 +557,9 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
/* Process client cmds */
|
/* Process client cmds */
|
||||||
ctx->oldest_client_ack_tick = ctx->world->tick;
|
u64 oldest_client_ack_tick = world->tick;
|
||||||
for (u64 i = 0; i < ctx->world->num_clients_reserved; ++i) {
|
for (u64 i = 0; i < world->num_clients_reserved; ++i) {
|
||||||
struct sim_client *client = &ctx->world->clients[i];
|
struct sim_client *client = &world->clients[i];
|
||||||
if (client->valid) {
|
if (client->valid) {
|
||||||
struct host_channel_id channel_id = client->channel_id;
|
struct host_channel_id channel_id = client->channel_id;
|
||||||
struct sim_cmd_list cmds = client_cmds[client->handle.idx];
|
struct sim_cmd_list cmds = client_cmds[client->handle.idx];
|
||||||
@ -626,7 +623,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
/* Clear level */
|
/* Clear level */
|
||||||
case SIM_CMD_KIND_CLEAR_ALL:
|
case SIM_CMD_KIND_CLEAR_ALL:
|
||||||
{
|
{
|
||||||
test_clear_level(ctx);
|
test_clear_level(world);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
/* Spawn test */
|
/* Spawn test */
|
||||||
@ -636,14 +633,14 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
u32 count = 1;
|
u32 count = 1;
|
||||||
f32 spread = 1;
|
f32 spread = 1;
|
||||||
for (u32 j = 0; j < count; ++j) {
|
for (u32 j = 0; j < count; ++j) {
|
||||||
spawn_test_entities(ctx, V2(0, (((f32)j / (f32)count) - 0.5) * spread));
|
spawn_test_entities(world, V2(0, (((f32)j / (f32)count) - 0.5) * spread));
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
/* Disconnect client */
|
/* Disconnect client */
|
||||||
case SIM_CMD_KIND_SIM_CLIENT_DISCONNECT:
|
case SIM_CMD_KIND_SIM_CLIENT_DISCONNECT:
|
||||||
{
|
{
|
||||||
host_queue_disconnect(ctx->host, channel_id);
|
host_queue_disconnect(host, channel_id);
|
||||||
sim_client_release(client);
|
sim_client_release(client);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -651,8 +648,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->ack_tick < ctx->oldest_client_ack_tick || ctx->oldest_client_ack_tick == 0) {
|
if (client->ack_tick < oldest_client_ack_tick || oldest_client_ack_tick == 0) {
|
||||||
ctx->oldest_client_ack_tick = client->ack_tick;
|
oldest_client_ack_tick = client->ack_tick;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -661,21 +658,20 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Create client ents
|
* Create client ents
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
ctx->oldest_client_ack_tick = ctx->world->tick;
|
for (u64 i = 0; i < world->num_clients_reserved; ++i) {
|
||||||
for (u64 i = 0; i < ctx->world->num_clients_reserved; ++i) {
|
struct sim_client *client = &world->clients[i];
|
||||||
struct sim_client *client = &ctx->world->clients[i];
|
|
||||||
if (client->valid) {
|
if (client->valid) {
|
||||||
/* FIXME: Ents never released when client disconnects */
|
/* FIXME: Ents never released when client disconnects */
|
||||||
struct sim_ent *player_ent = sim_ent_from_handle(ctx->world, client->control_ent);
|
struct sim_ent *player_ent = sim_ent_from_handle(world, client->control_ent);
|
||||||
if (!player_ent->valid) {
|
if (!player_ent->valid) {
|
||||||
player_ent = spawn_test_player(ctx);
|
player_ent = spawn_test_player(world);
|
||||||
sim_ent_enable_prop(player_ent, SIM_ENT_PROP_CONTROLLED);
|
sim_ent_enable_prop(player_ent, SIM_ENT_PROP_CONTROLLED);
|
||||||
client->control_ent = player_ent->handle;
|
client->control_ent = player_ent->handle;
|
||||||
player_ent->controlling_client = client->handle;
|
player_ent->controlling_client = client->handle;
|
||||||
}
|
}
|
||||||
struct sim_ent *camera_ent = sim_ent_from_handle(ctx->world, client->camera_ent);
|
struct sim_ent *camera_ent = sim_ent_from_handle(world, client->camera_ent);
|
||||||
if (!camera_ent->valid) {
|
if (!camera_ent->valid) {
|
||||||
camera_ent = spawn_test_player_camera(ctx, player_ent);
|
camera_ent = spawn_test_player_camera(world, player_ent);
|
||||||
client->camera_ent = camera_ent->handle;
|
client->camera_ent = camera_ent->handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -685,12 +681,12 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Update entity control from client control
|
* Update entity control from client control
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
|
|
||||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) {
|
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) {
|
||||||
struct sim_client *client = sim_client_from_handle(ctx->world, ent->controlling_client);
|
struct sim_client *client = sim_client_from_handle(world, ent->controlling_client);
|
||||||
if (client->valid) {
|
if (client->valid) {
|
||||||
ent->control = client->control;
|
ent->control = client->control;
|
||||||
/* TODO: Move this */
|
/* TODO: Move this */
|
||||||
@ -707,8 +703,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Update entities from sprite
|
* Update entities from sprite
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
if (sprite_tag_is_nil(ent->sprite)) continue;
|
if (sprite_tag_is_nil(ent->sprite)) continue;
|
||||||
|
|
||||||
@ -802,12 +798,12 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Update attachments
|
* Update attachments
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_ATTACHED)) continue;
|
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_ATTACHED)) continue;
|
||||||
|
|
||||||
struct sim_ent *parent = sim_ent_from_handle(ctx->world, ent->parent);
|
struct sim_ent *parent = sim_ent_from_handle(world, ent->parent);
|
||||||
struct sprite_tag parent_sprite = parent->sprite;
|
struct sprite_tag parent_sprite = parent->sprite;
|
||||||
struct sprite_sheet *parent_sheet = sprite_sheet_from_tag_await(sprite_frame_scope, parent_sprite);
|
struct sprite_sheet *parent_sheet = sprite_sheet_from_tag_await(sprite_frame_scope, parent_sprite);
|
||||||
|
|
||||||
@ -828,8 +824,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_TEST)) continue;
|
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_TEST)) continue;
|
||||||
|
|
||||||
@ -878,12 +874,12 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Trigger equipped
|
* Trigger equipped
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(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_handle(ctx->world, ent->equipped);
|
struct sim_ent *eq = sim_ent_from_handle(world, ent->equipped);
|
||||||
if (sim_ent_is_valid_and_active(eq)) {
|
if (sim_ent_is_valid_and_active(eq)) {
|
||||||
sim_ent_enable_prop(eq, SIM_ENT_PROP_TRIGGERED_THIS_TICK);
|
sim_ent_enable_prop(eq, SIM_ENT_PROP_TRIGGERED_THIS_TICK);
|
||||||
}
|
}
|
||||||
@ -894,13 +890,13 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Process triggered entities
|
* Process triggered entities
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(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 ((sim_time - ent->last_triggered < ent->trigger_delay) && ent->last_triggered != 0) continue;
|
if ((world_time - ent->last_triggered < ent->trigger_delay) && ent->last_triggered != 0) continue;
|
||||||
|
|
||||||
ent->last_triggered = sim_time;
|
ent->last_triggered = world_time;
|
||||||
|
|
||||||
/* Fire weapon */
|
/* Fire weapon */
|
||||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_WEAPON)) {
|
if (sim_ent_has_prop(ent, SIM_ENT_PROP_WEAPON)) {
|
||||||
@ -958,12 +954,12 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Create motor joints from control move
|
* Create motor joints from control move
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(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_handle(ctx->world, ent->move_joint);
|
struct sim_ent *joint_ent = sim_ent_from_handle(world, ent->move_joint);
|
||||||
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
joint_ent = sim_ent_alloc(root);
|
joint_ent = sim_ent_alloc(root);
|
||||||
joint_ent->mass_unscaled = F32_INFINITY;
|
joint_ent->mass_unscaled = F32_INFINITY;
|
||||||
@ -991,8 +987,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
#if SIM_PLAYER_AIM
|
#if SIM_PLAYER_AIM
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
|
|
||||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) {
|
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) {
|
||||||
@ -1000,7 +996,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
struct xform sprite_xf = xform_mul(xf, ent->sprite_local_xform);
|
struct xform sprite_xf = xform_mul(xf, ent->sprite_local_xform);
|
||||||
|
|
||||||
/* Retrieve / create aim joint */
|
/* Retrieve / create aim joint */
|
||||||
struct sim_ent *joint_ent = sim_ent_from_handle(ctx->world, ent->aim_joint);
|
struct sim_ent *joint_ent = sim_ent_from_handle(world, ent->aim_joint);
|
||||||
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
joint_ent = sim_ent_alloc(root);
|
joint_ent = sim_ent_alloc(root);
|
||||||
joint_ent->mass_unscaled = F32_INFINITY;
|
joint_ent->mass_unscaled = F32_INFINITY;
|
||||||
@ -1083,12 +1079,12 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Create motor joints from ground friction (gravity)
|
* Create motor joints from ground friction (gravity)
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(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;
|
||||||
|
|
||||||
struct sim_ent *joint_ent = sim_ent_from_handle(ctx->world, ent->ground_friction_joint);
|
struct sim_ent *joint_ent = sim_ent_from_handle(world, ent->ground_friction_joint);
|
||||||
|
|
||||||
struct phys_motor_joint_def def = ZI;
|
struct phys_motor_joint_def def = ZI;
|
||||||
def.e0 = root->handle;
|
def.e0 = root->handle;
|
||||||
@ -1111,15 +1107,15 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Create mouse joints from client debug drag
|
* Create mouse joints from client debug drag
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 i = 0; i < ctx->world->num_clients_reserved; ++i) {
|
for (u64 i = 0; i < world->num_clients_reserved; ++i) {
|
||||||
struct sim_client *client = &ctx->world->clients[i];
|
struct sim_client *client = &world->clients[i];
|
||||||
if (client->valid) {
|
if (client->valid) {
|
||||||
struct v2 cursor = client->cursor_pos;
|
struct v2 cursor = client->cursor_pos;
|
||||||
b32 start_dragging = client->dbg_drag_start;
|
b32 start_dragging = client->dbg_drag_start;
|
||||||
b32 stop_dragging = client->dbg_drag_stop;
|
b32 stop_dragging = client->dbg_drag_stop;
|
||||||
|
|
||||||
struct sim_ent *joint_ent = sim_ent_from_handle(ctx->world, client->dbg_drag_joint_ent);
|
struct sim_ent *joint_ent = sim_ent_from_handle(world, client->dbg_drag_joint_ent);
|
||||||
struct sim_ent *target_ent = sim_ent_from_handle(ctx->world, joint_ent->mouse_joint_data.target);
|
struct sim_ent *target_ent = sim_ent_from_handle(world, joint_ent->mouse_joint_data.target);
|
||||||
|
|
||||||
if (start_dragging) {
|
if (start_dragging) {
|
||||||
struct xform mouse_xf = xform_from_pos(cursor);
|
struct xform mouse_xf = xform_from_pos(cursor);
|
||||||
@ -1127,8 +1123,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
mouse_shape.points[0] = V2(0, 0);
|
mouse_shape.points[0] = V2(0, 0);
|
||||||
mouse_shape.count = 1;
|
mouse_shape.count = 1;
|
||||||
|
|
||||||
for (u64 sim_ent_index = 0; sim_ent_index < ctx->world->num_ents_reserved; ++sim_ent_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < world->num_ents_reserved; ++sim_ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[sim_ent_index];
|
struct sim_ent *ent = &world->ents[sim_ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(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;
|
||||||
|
|
||||||
@ -1183,25 +1179,19 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
|
|
||||||
{
|
{
|
||||||
struct phys_ctx phys = ZI;
|
struct phys_ctx phys = ZI;
|
||||||
phys.ss = ctx->world;
|
phys.ss = world;
|
||||||
phys.space = space;
|
|
||||||
phys.contact_lookup = &ctx->contact_lookup;
|
|
||||||
phys.pre_solve_callback = on_collision;
|
phys.pre_solve_callback = on_collision;
|
||||||
phys.pre_solve_callback_udata = ctx;
|
|
||||||
#if COLLIDER_DEBUG
|
|
||||||
phys.debug_lookup = &ctx->collision_debug_lookup;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Step */
|
/* Step */
|
||||||
ctx->last_phys_iteration = phys_step(&phys, world_dt, ctx->last_phys_iteration);
|
phys_step(&phys, world_dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update tracers
|
* Update tracers
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_TRACER)) continue;
|
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_TRACER)) continue;
|
||||||
|
|
||||||
@ -1224,13 +1214,13 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Initialize bullet kinematics from sources
|
* Initialize bullet kinematics from sources
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_BULLET)) continue;
|
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_BULLET)) continue;
|
||||||
|
|
||||||
if (ent->activation_tick == ctx->world->tick) {
|
if (ent->activation_tick == world->tick) {
|
||||||
struct sim_ent *src = sim_ent_from_handle(ctx->world, ent->bullet_src);
|
struct sim_ent *src = sim_ent_from_handle(world, ent->bullet_src);
|
||||||
struct xform src_xf = sim_ent_get_xform(src);
|
struct xform src_xf = sim_ent_get_xform(src);
|
||||||
|
|
||||||
struct v2 pos = xform_mul_v2(src_xf, ent->bullet_src_pos);
|
struct v2 pos = xform_mul_v2(src_xf, ent->bullet_src_pos);
|
||||||
@ -1241,7 +1231,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
/* Add shooter velocity to bullet */
|
/* Add shooter velocity to bullet */
|
||||||
{
|
{
|
||||||
/* TODO: Add angular velocity as well? */
|
/* TODO: Add angular velocity as well? */
|
||||||
struct sim_ent *top = sim_ent_from_handle(ctx->world, src->top);
|
struct sim_ent *top = sim_ent_from_handle(world, src->top);
|
||||||
impulse = v2_add(impulse, v2_mul(top->linear_velocity, dt));
|
impulse = v2_add(impulse, v2_mul(top->linear_velocity, dt));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1253,7 +1243,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
sim_ent_apply_linear_impulse_to_center(ent, impulse);
|
sim_ent_apply_linear_impulse_to_center(ent, impulse);
|
||||||
|
|
||||||
/* Initialize tracer */
|
/* Initialize tracer */
|
||||||
struct sim_ent *tracer = sim_ent_from_handle(ctx->world, ent->bullet_tracer);
|
struct sim_ent *tracer = sim_ent_from_handle(world, ent->bullet_tracer);
|
||||||
if (sim_ent_is_valid_and_active(tracer)) {
|
if (sim_ent_is_valid_and_active(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);
|
||||||
@ -1279,8 +1269,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Update cameras
|
* Update cameras
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_CAMERA)) continue;
|
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_CAMERA)) continue;
|
||||||
|
|
||||||
@ -1288,7 +1278,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
|
|
||||||
/* Camera follow */
|
/* Camera follow */
|
||||||
{
|
{
|
||||||
struct sim_ent *follow = sim_ent_from_handle(ctx->world, ent->camera_follow);
|
struct sim_ent *follow = sim_ent_from_handle(world, ent->camera_follow);
|
||||||
|
|
||||||
f32 aspect_ratio = 1.0;
|
f32 aspect_ratio = 1.0;
|
||||||
{
|
{
|
||||||
@ -1320,8 +1310,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
{
|
{
|
||||||
/* TODO: Update based on distance to quake */
|
/* TODO: Update based on distance to quake */
|
||||||
ent->shake = 0;
|
ent->shake = 0;
|
||||||
for (u64 quake_ent_index = 0; quake_ent_index < ctx->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 = &ctx->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_is_valid_and_active(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;
|
||||||
@ -1335,8 +1325,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Update quakes
|
* Update quakes
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &ctx->world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_QUAKE)) continue;
|
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_QUAKE)) continue;
|
||||||
|
|
||||||
@ -1363,7 +1353,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
--stack_count;
|
--stack_count;
|
||||||
|
|
||||||
i32 parent_layer = parent->final_layer;
|
i32 parent_layer = parent->final_layer;
|
||||||
for (struct sim_ent *child = sim_ent_from_handle(ctx->world, parent->first); child->valid; child = sim_ent_from_handle(ctx->world, child->next)) {
|
for (struct sim_ent *child = sim_ent_from_handle(world, parent->first); child->valid; child = sim_ent_from_handle(world, child->next)) {
|
||||||
if (sim_ent_is_valid_and_active(child)) {
|
if (sim_ent_is_valid_and_active(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;
|
||||||
@ -1379,21 +1369,21 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
* Release entities
|
* Release entities
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
release_entities_with_prop(ctx, SIM_ENT_PROP_RELEASE_THIS_TICK);
|
release_entities_with_prop(world, SIM_ENT_PROP_RELEASE_THIS_TICK);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Publish tick
|
* Publish tick
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 i = 0; i < ctx->world->num_clients_reserved; ++i) {
|
for (u64 i = 0; i < world->num_clients_reserved; ++i) {
|
||||||
struct sim_client *client = &ctx->world->clients[i];
|
struct sim_client *client = &world->clients[i];
|
||||||
if (client->valid) {
|
if (client->valid) {
|
||||||
struct temp_arena temp = arena_temp_begin(scratch.arena);
|
struct temp_arena temp = arena_temp_begin(scratch.arena);
|
||||||
|
|
||||||
u64 ss0_tick = client->ack_tick;
|
u64 ss0_tick = client->ack_tick;
|
||||||
u64 ss1_tick = ctx->world->tick;
|
u64 ss1_tick = world->tick;
|
||||||
struct sim_snapshot *ss0 = sim_snapshot_from_tick(ctx->snapshot_store, ss0_tick);
|
struct sim_snapshot *ss0 = sim_snapshot_from_tick(snapshot_store, ss0_tick);
|
||||||
struct sim_snapshot *ss1 = ctx->world;
|
struct sim_snapshot *ss1 = world;
|
||||||
ss0_tick = ss0->tick; /* In case ack tick is no longer in store we need to do a full resend */
|
ss0_tick = ss0->tick; /* In case ack tick is no longer in store we need to do a full resend */
|
||||||
|
|
||||||
struct sim_event_list l = ZI;
|
struct sim_event_list l = ZI;
|
||||||
@ -1402,12 +1392,12 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
/* Create & encode snapshot event */
|
/* Create & encode snapshot event */
|
||||||
{
|
{
|
||||||
snapshot_event.kind = SIM_EVENT_KIND_SNAPSHOT;
|
snapshot_event.kind = SIM_EVENT_KIND_SNAPSHOT;
|
||||||
snapshot_event.tick = ctx->world->tick;
|
snapshot_event.tick = world->tick;
|
||||||
snapshot_event.snapshot_tick_start = ss0_tick;
|
snapshot_event.snapshot_tick_start = ss0_tick;
|
||||||
snapshot_event.snapshot_tick_end = ss1_tick;
|
snapshot_event.snapshot_tick_end = ss1_tick;
|
||||||
|
|
||||||
{
|
{
|
||||||
struct bitbuff_writer bw = bw_from_bitbuff(&ctx->encoder_bitbuff);
|
struct bitbuff_writer bw = bw_from_bitbuff(encoder_bitbuff);
|
||||||
sim_snapshot_encode(&bw, ss0, ss1, client);
|
sim_snapshot_encode(&bw, ss0, ss1, client);
|
||||||
snapshot_event.snapshot_encoded = bw_get_written(temp.arena, &bw);
|
snapshot_event.snapshot_encoded = bw_get_written(temp.arena, &bw);
|
||||||
}
|
}
|
||||||
@ -1423,18 +1413,18 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
|
|||||||
/* Encode events */
|
/* Encode events */
|
||||||
struct string events_msg = ZI;
|
struct string events_msg = ZI;
|
||||||
{
|
{
|
||||||
struct bitbuff_writer bw = bw_from_bitbuff(&ctx->encoder_bitbuff);
|
struct bitbuff_writer bw = bw_from_bitbuff(encoder_bitbuff);
|
||||||
sim_events_encode(&bw, l);
|
sim_events_encode(&bw, l);
|
||||||
events_msg = bw_get_written(temp.arena, &bw);
|
events_msg = bw_get_written(temp.arena, &bw);
|
||||||
}
|
}
|
||||||
|
|
||||||
host_queue_write(ctx->host, client->channel_id, events_msg, 0);
|
host_queue_write(host, client->channel_id, events_msg, 0);
|
||||||
|
|
||||||
arena_temp_end(temp);
|
arena_temp_end(temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
host_update(ctx->host);
|
host_update(host);
|
||||||
__profframe("Sim");
|
__profframe("Sim");
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
|
|||||||
@ -122,6 +122,7 @@ struct sim_event_list {
|
|||||||
* Ctx
|
* Ctx
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
|
#if 0
|
||||||
struct sim_ctx {
|
struct sim_ctx {
|
||||||
struct arena arena;
|
struct arena arena;
|
||||||
|
|
||||||
@ -162,8 +163,12 @@ struct sim_ctx *sim_ctx_alloc(struct sprite_startup_receipt *sprite_sr,
|
|||||||
u16 host_port);
|
u16 host_port);
|
||||||
|
|
||||||
void sim_ctx_release(struct sim_ctx *ctx);
|
void sim_ctx_release(struct sim_ctx *ctx);
|
||||||
|
#endif
|
||||||
|
|
||||||
void sim_update(struct sim_ctx *ctx, i64 target_dt_ns);
|
struct host;
|
||||||
|
struct bitbuff;
|
||||||
|
struct sim_snapshot;
|
||||||
|
void sim_step(struct host *host, struct bitbuff *encoder_bitbuff, struct sim_snapshot_store *snapshot_store, struct sim_snapshot *prev_snapshot, i64 real_dt_ns, struct sim_cmd_list user_sim_cmds);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Event & cmd encode/decode
|
* Event & cmd encode/decode
|
||||||
|
|||||||
@ -4,6 +4,16 @@
|
|||||||
#include "sim_ent.h"
|
#include "sim_ent.h"
|
||||||
#include "sim_client.h"
|
#include "sim_client.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: Remove this */
|
||||||
|
struct space;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct sim_snapshot_store {
|
struct sim_snapshot_store {
|
||||||
b32 valid;
|
b32 valid;
|
||||||
struct arena arena;
|
struct arena arena;
|
||||||
@ -32,6 +42,49 @@ struct sim_snapshot {
|
|||||||
|
|
||||||
struct arena arena;
|
struct arena arena;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* FIXME: Remove this */
|
||||||
|
struct space *space;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* FIXME: Encode / decode*/
|
||||||
|
|
||||||
|
u64 phys_iteration;
|
||||||
|
|
||||||
|
/* This is the oldest tick stored in ctx that we need to hold a reference to for delta encoding */
|
||||||
|
u64 oldest_client_ack_tick;
|
||||||
|
|
||||||
|
/* Bookkeeping structures */
|
||||||
|
/* TODO: Store in snapshot for determinism */
|
||||||
|
struct sim_ent_lookup contact_lookup;
|
||||||
|
#if COLLIDER_DEBUG
|
||||||
|
struct sim_ent_lookup collision_debug_lookup;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Real time (increases with clock assuming no lag) */
|
/* Real time (increases with clock assuming no lag) */
|
||||||
i64 real_dt_ns;
|
i64 real_dt_ns;
|
||||||
i64 real_time_ns;
|
i64 real_time_ns;
|
||||||
|
|||||||
@ -17,7 +17,7 @@ struct space_entry {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Links a cell to a entry.
|
/* Links a cell to a entry.
|
||||||
* Acts as both a list of entries contained by cell & a list of cells containing entry. */
|
* Acts as both a node in the list of entries contained by the cell, and a node in the list of cells containing the entry. */
|
||||||
struct space_cell_node {
|
struct space_cell_node {
|
||||||
struct space_entry *entry;
|
struct space_entry *entry;
|
||||||
struct space_cell *cell;
|
struct space_cell *cell;
|
||||||
|
|||||||
64
src/user.c
64
src/user.c
@ -205,6 +205,7 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr,
|
|||||||
sys_window_register_event_callback(G.window, &window_event_callback);
|
sys_window_register_event_callback(G.window, &window_event_callback);
|
||||||
|
|
||||||
/* TODO: Remove this */
|
/* TODO: Remove this */
|
||||||
|
#if 0
|
||||||
connect_address_str = STRING(0, 0);
|
connect_address_str = STRING(0, 0);
|
||||||
if (connect_address_str.len == 0) {
|
if (connect_address_str.len == 0) {
|
||||||
G.local_sim_ctx = sim_ctx_alloc(sprite_sr, phys_sr, host_sr, sim_snapshot_sr, 12345);
|
G.local_sim_ctx = sim_ctx_alloc(sprite_sr, phys_sr, host_sr, sim_snapshot_sr, 12345);
|
||||||
@ -213,6 +214,9 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr,
|
|||||||
} else {
|
} else {
|
||||||
G.connect_address_str = string_copy(&G.arena, connect_address_str);
|
G.connect_address_str = string_copy(&G.arena, connect_address_str);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
(UNUSED)connect_address_str;
|
||||||
|
#endif
|
||||||
|
|
||||||
G.debug_draw = true;
|
G.debug_draw = true;
|
||||||
|
|
||||||
@ -228,11 +232,18 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(user_shutdown)
|
|||||||
atomic_i32_eval_exchange(&G.user_thread_shutdown, true);
|
atomic_i32_eval_exchange(&G.user_thread_shutdown, true);
|
||||||
sys_thread_wait_release(&G.user_thread);
|
sys_thread_wait_release(&G.user_thread);
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (G.local_sim_ctx) {
|
if (G.local_sim_ctx) {
|
||||||
atomic_i32_eval_exchange(&G.local_sim_thread_shutdown, true);
|
atomic_i32_eval_exchange(&G.local_sim_thread_shutdown, true);
|
||||||
sys_thread_wait_release(&G.local_sim_thread);
|
sys_thread_wait_release(&G.local_sim_thread);
|
||||||
sim_ctx_release(G.local_sim_ctx);
|
sim_ctx_release(G.local_sim_ctx);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (G.local_sim_ctx) {
|
||||||
|
atomic_i32_eval_exchange(&G.local_sim_thread_shutdown, true);
|
||||||
|
sys_thread_wait_release(&G.local_sim_thread);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -1743,7 +1754,7 @@ INTERNAL void user_update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* User thread entry point
|
* User thread
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_thread_entry_point, arg)
|
INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_thread_entry_point, arg)
|
||||||
@ -1762,14 +1773,61 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_thread_entry_point, arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Local sim thread entry point
|
* Local sim thread
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct host *host = host_alloc(12345);
|
||||||
|
struct bitbuff encoder_bitbuff = bitbuff_alloc(GIGABYTE(64));
|
||||||
|
struct sim_snapshot_store *ss_store = sim_snapshot_store_alloc();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct sim_ctx *ctx = (struct sim_ctx *)arg;
|
struct sim_ctx *ctx = (struct sim_ctx *)arg;
|
||||||
|
i64 last_tick_ns = 0;
|
||||||
i64 target_dt_ns = NS_FROM_SECONDS(1) / SIM_TICKS_PER_SECOND;;
|
i64 target_dt_ns = NS_FROM_SECONDS(1) / SIM_TICKS_PER_SECOND;;
|
||||||
while (!atomic_i32_eval(&G.local_sim_thread_shutdown)) {
|
while (!atomic_i32_eval(&G.local_sim_thread_shutdown)) {
|
||||||
sim_update(ctx, target_dt_ns);
|
{
|
||||||
|
__profscope(local_sim_sleep);
|
||||||
|
sleep_frame(last_tick_ns, target_dt_ns);
|
||||||
|
last_tick_ns = sys_time_ns();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||||
|
/* Copy user sim cmds */
|
||||||
|
struct sim_cmd_list user_sim_cmds = ZI;
|
||||||
|
{
|
||||||
|
struct sys_lock lock = sys_mutex_lock_s(&G.user_sim_cmds_arena);
|
||||||
|
for (struct sim_cmd *cmd = G.user_sim_cmds.first; cmd; cmd = cmd->next) {
|
||||||
|
struct sim_cmd *dst = arena_push(scratch.arena, struct sim_cmd);
|
||||||
|
*dst = *cmd;
|
||||||
|
dst->next = NULL;
|
||||||
|
if (user_sim_cmds.last) {
|
||||||
|
user_sim_cmds.last->next = dst;
|
||||||
|
} else {
|
||||||
|
user_sim_cmds.first = dst;
|
||||||
|
}
|
||||||
|
user_sim_cmds.last = dst;
|
||||||
|
}
|
||||||
|
sys_mutex_unlock(&lock);
|
||||||
|
}
|
||||||
|
sim_step(host, &encoder_bitbuff, snapshot_store, snapshot, target_dt_ns, user_sim_cmds);
|
||||||
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sim_snapshot_store_release(ss_store);
|
||||||
|
bitbuff_release(&encoder_bitbuff);
|
||||||
|
host_release(host);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user