move phys arguments into phys_ctx

This commit is contained in:
jacob 2025-01-10 16:05:22 -06:00
parent 0716ebd398
commit 0c1d6a58de
3 changed files with 106 additions and 69 deletions

View File

@ -918,27 +918,28 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
* Physics * Physics
* ========================== */ * ========================== */
/* Mouse drag */ {
b32 dbg_start_dragging = false; struct phys_ctx ctx = ZI;
b32 dbg_stop_dragging = false; ctx.tick_id = G.tick.tick_id;
for (u64 i = 0; i < game_cmds.count; ++i) { ctx.store = store;
struct game_cmd cmd = game_cmds.cmds[i]; ctx.contact_lookup = &G.contact_lookup;
b32 start = cmd.state == GAME_CMD_STATE_START; ctx.debug_lookup = &G.collision_debug_lookup;
b32 stop = cmd.state == GAME_CMD_STATE_STOP;
switch (cmd.kind) {
case GAME_CMD_KIND_DRAG_OBJECT:
{
if (start) {
dbg_start_dragging = true;
} else if (stop) {
dbg_stop_dragging = true;
}
} break;
default: break;
}
}
phys_step(store, dt, &G.contact_lookup, &G.collision_debug_lookup, G.tick.tick_id, G.user_cursor, dbg_start_dragging, dbg_stop_dragging); /* Mouse drag */
ctx.dbg_cursor_pos = G.user_cursor;
for (u64 i = 0; i < game_cmds.count; ++i) {
struct game_cmd cmd = game_cmds.cmds[i];
if (cmd.kind == GAME_CMD_KIND_DRAG_OBJECT) {
if (cmd.state == GAME_CMD_STATE_START) {
ctx.dbg_start_dragging = true;
} else if (cmd.state == GAME_CMD_STATE_STOP) {
ctx.dbg_stop_dragging = true;
}
}
}
phys_step(&ctx, dt);
}
/* ========================== * /* ========================== *
* Respond to hit events * Respond to hit events

View File

@ -37,8 +37,12 @@ struct phys_startup_receipt phys_startup(void)
* Contact * Contact
* ========================== */ * ========================== */
void phys_create_contacts(struct entity_store *store, struct entity_lookup *contact_lookup, struct entity_lookup *debug_lookup, u64 tick_id) void phys_create_contacts(struct phys_ctx *ctx)
{ {
u64 tick_id = ctx->tick_id;
struct entity_lookup *contact_lookup = ctx->contact_lookup;
struct entity_lookup *debug_lookup = ctx->debug_lookup;
struct entity_store *store = ctx->store;
struct entity *root = entity_from_handle(store, store->root); struct entity *root = entity_from_handle(store, store->root);
for (u64 check0_index = 0; check0_index < store->reserved; ++check0_index) { for (u64 check0_index = 0; check0_index < store->reserved; ++check0_index) {
@ -273,8 +277,12 @@ void phys_create_contacts(struct entity_store *store, struct entity_lookup *cont
} }
} }
void phys_prepare_contacts(struct entity_store *store, struct entity_lookup *contact_lookup, struct entity_lookup *debug_lookup) void phys_prepare_contacts(struct phys_ctx *ctx)
{ {
struct entity_lookup *contact_lookup = ctx->contact_lookup;
struct entity_lookup *debug_lookup = ctx->debug_lookup;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *constraint_ent = &store->entities[entity_index]; struct entity *constraint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(constraint_ent)) continue; if (!entity_is_valid_and_active(constraint_ent)) continue;
@ -402,8 +410,9 @@ void phys_prepare_contacts(struct entity_store *store, struct entity_lookup *con
#endif #endif
} }
void phys_warm_start_contacts(struct entity_store *store) void phys_warm_start_contacts(struct phys_ctx *ctx)
{ {
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *constraint_ent = &store->entities[entity_index]; struct entity *constraint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(constraint_ent)) continue; if (!entity_is_valid_and_active(constraint_ent)) continue;
@ -455,8 +464,9 @@ void phys_warm_start_contacts(struct entity_store *store)
} }
} }
void phys_solve_contacts(struct entity_store *store, f32 dt, b32 apply_bias) void phys_solve_contacts(struct phys_ctx *ctx, f32 dt, b32 apply_bias)
{ {
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *constraint_ent = &store->entities[entity_index]; struct entity *constraint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(constraint_ent)) continue; if (!entity_is_valid_and_active(constraint_ent)) continue;
@ -584,8 +594,9 @@ struct phys_motor_joint motor_joint_from_def(struct phys_motor_joint_def def)
return res; return res;
} }
void phys_prepare_motor_joints(struct entity_store *store) void phys_prepare_motor_joints(struct phys_ctx *ctx)
{ {
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index]; struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue; if (!entity_is_valid_and_active(joint_ent)) continue;
@ -646,8 +657,9 @@ void phys_prepare_motor_joints(struct entity_store *store)
} }
} }
void phys_warm_start_motor_joints(struct entity_store *store) void phys_warm_start_motor_joints(struct phys_ctx *ctx)
{ {
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index]; struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue; if (!entity_is_valid_and_active(joint_ent)) continue;
@ -676,8 +688,9 @@ void phys_warm_start_motor_joints(struct entity_store *store)
} }
} }
void phys_solve_motor_joints(struct entity_store *store, f32 dt) void phys_solve_motor_joints(struct phys_ctx *ctx, f32 dt)
{ {
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index]; struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue; if (!entity_is_valid_and_active(joint_ent)) continue;
@ -754,8 +767,12 @@ void phys_solve_motor_joints(struct entity_store *store, f32 dt)
* Mouse joint * Mouse joint
* ========================== */ * ========================== */
void phys_create_mouse_joints(struct entity_store *store, struct v2 cursor, b32 start_dragging, b32 stop_dragging) void phys_create_mouse_joints(struct phys_ctx *ctx)
{ {
struct entity_store *store = ctx->store;
struct v2 cursor = ctx->dbg_cursor_pos;
b32 start_dragging = ctx->dbg_start_dragging;
b32 stop_dragging = ctx->dbg_stop_dragging;
struct entity *root = entity_from_handle(store, store->root); struct entity *root = entity_from_handle(store, store->root);
struct entity *joint_ent = entity_find_first_match_one(store, ENTITY_PROP_MOUSE_JOINT); struct entity *joint_ent = entity_find_first_match_one(store, ENTITY_PROP_MOUSE_JOINT);
@ -817,8 +834,9 @@ void phys_create_mouse_joints(struct entity_store *store, struct v2 cursor, b32
} }
} }
void phys_prepare_mouse_joints(struct entity_store *store) void phys_prepare_mouse_joints(struct phys_ctx *ctx)
{ {
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index]; struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue; if (!entity_is_valid_and_active(joint_ent)) continue;
@ -862,8 +880,9 @@ void phys_prepare_mouse_joints(struct entity_store *store)
} }
} }
void phys_warm_start_mouse_joints(struct entity_store *store) void phys_warm_start_mouse_joints(struct phys_ctx *ctx)
{ {
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index]; struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue; if (!entity_is_valid_and_active(joint_ent)) continue;
@ -882,8 +901,9 @@ void phys_warm_start_mouse_joints(struct entity_store *store)
} }
} }
void phys_solve_mouse_joints(struct entity_store *store, f32 dt) void phys_solve_mouse_joints(struct phys_ctx *ctx, f32 dt)
{ {
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index]; struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue; if (!entity_is_valid_and_active(joint_ent)) continue;
@ -965,8 +985,9 @@ void phys_solve_mouse_joints(struct entity_store *store, f32 dt)
* Earliest time of impact * Earliest time of impact
* ========================== */ * ========================== */
f32 phys_determine_earliest_toi_for_bullets(struct entity_store *store, f32 step_dt, f32 tolerance, u32 max_iterations) f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f32 tolerance, u32 max_iterations)
{ {
struct entity_store *store = ctx->store;
__prof; __prof;
f32 smallest_t = 1; f32 smallest_t = 1;
@ -1031,8 +1052,9 @@ f32 phys_determine_earliest_toi_for_bullets(struct entity_store *store, f32 step
* Integration * Integration
* ========================== */ * ========================== */
void phys_integrate_forces(struct entity_store *store, f32 dt) void phys_integrate_forces(struct phys_ctx *ctx, f32 dt)
{ {
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
@ -1057,8 +1079,9 @@ void phys_integrate_forces(struct entity_store *store, f32 dt)
} }
} }
void phys_integrate_velocities(struct entity_store *store, f32 dt) void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt)
{ {
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
@ -1082,53 +1105,54 @@ void phys_integrate_velocities(struct entity_store *store, f32 dt)
* Step * Step
* ========================== */ * ========================== */
void phys_step(struct entity_store *store, f32 step_dt, struct entity_lookup *contact_lookup, struct entity_lookup *collision_debug_lookup, u64 tick_id, struct v2 dbg_cursor_pos, b32 dbg_start_dragging, b32 dbg_stop_dragging) void phys_step(struct phys_ctx *ctx, f32 timestep)
{ {
f32 remaining_dt = step_dt; phys_integrate_forces(ctx, timestep);
phys_integrate_forces(store, remaining_dt); f32 remaining_dt = timestep;
while (remaining_dt > 0) { while (remaining_dt > 0) {
/* TOI */ /* TOI */
f32 step_dt = remaining_dt;
{ {
#if GAME_PHYSICS_ENABLE_TOI #if GAME_PHYSICS_ENABLE_TOI
const f32 min_toi = 0.000001f; const f32 min_toi = 0.000001f;
const f32 tolerance = 0.00001f; const f32 tolerance = 0.00001f;
const u32 max_iterations = 16; const u32 max_iterations = 16;
f32 earliest_toi = max_f32(phys_determine_earliest_toi_for_bullets(store, remaining_dt, tolerance, max_iterations), min_toi); f32 earliest_toi = max_f32(phys_determine_earliest_toi_for_bullets(ctx, step_dt, tolerance, max_iterations), min_toi);
remaining_dt = remaining_dt * earliest_toi; step_dt = remaining_dt * earliest_toi;
#else #else
(UNUSED)toi; (UNUSED)toi;
(UNUSED)determine_earliest_toi_for_bullets; (UNUSED)determine_earliest_toi_for_bullets;
#endif #endif
} }
phys_create_contacts(store, contact_lookup, collision_debug_lookup, tick_id); phys_create_contacts(ctx);
phys_create_mouse_joints(store, dbg_cursor_pos, dbg_start_dragging, dbg_stop_dragging); phys_create_mouse_joints(ctx);
phys_prepare_contacts(store, contact_lookup, collision_debug_lookup); phys_prepare_contacts(ctx);
phys_prepare_motor_joints(store); phys_prepare_motor_joints(ctx);
phys_prepare_mouse_joints(store); phys_prepare_mouse_joints(ctx);
f32 substep_dt = remaining_dt / GAME_PHYSICS_SUBSTEPS; f32 substep_dt = step_dt / GAME_PHYSICS_SUBSTEPS;
for (u32 i = 0; i < GAME_PHYSICS_SUBSTEPS; ++i) { for (u32 i = 0; i < GAME_PHYSICS_SUBSTEPS; ++i) {
#if GAME_PHYSICS_ENABLE_WARM_STARTING #if GAME_PHYSICS_ENABLE_WARM_STARTING
phys_warm_start_contacts(store); phys_warm_start_contacts(ctx);
phys_warm_start_motor_joints(store); phys_warm_start_motor_joints(ctx);
phys_warm_start_mouse_joints(store); phys_warm_start_mouse_joints(ctx);
#endif #endif
#if GAME_PHYSICS_ENABLE_COLLISION #if GAME_PHYSICS_ENABLE_COLLISION
phys_solve_contacts(store, substep_dt, true); phys_solve_contacts(ctx, substep_dt, true);
#endif #endif
phys_solve_motor_joints(store, substep_dt); phys_solve_motor_joints(ctx, substep_dt);
phys_solve_mouse_joints(store, substep_dt); phys_solve_mouse_joints(ctx, substep_dt);
phys_integrate_velocities(store, substep_dt); phys_integrate_velocities(ctx, substep_dt);
#if GAME_PHYSICS_ENABLE_COLLISION && GAME_PHYSICS_ENABLE_RELAXATION #if GAME_PHYSICS_ENABLE_COLLISION && GAME_PHYSICS_ENABLE_RELAXATION
phys_solve_contacts(store, substep_dt, false); /* Relaxation */ phys_solve_contacts(ctx, substep_dt, false); /* Relaxation */
#endif #endif
} }
remaining_dt -= remaining_dt; remaining_dt -= step_dt;
} }
} }

View File

@ -7,6 +7,18 @@
struct entity_store; struct entity_store;
struct entity_lookup; struct entity_lookup;
/* Structure containing data used for a single physics step */
struct phys_ctx {
u64 tick_id;
struct entity_store *store;
struct entity_lookup *contact_lookup;
struct entity_lookup *debug_lookup;
struct v2 dbg_cursor_pos;
b32 dbg_start_dragging;
b32 dbg_stop_dragging;
};
struct phys_hit_event { struct phys_hit_event {
struct entity_handle e0; struct entity_handle e0;
struct entity_handle e1; struct entity_handle e1;
@ -79,10 +91,10 @@ struct phys_collision_debug {
struct xform xf1; struct xform xf1;
}; };
void phys_create_contacts(struct entity_store *store, struct entity_lookup *contact_lookup, struct entity_lookup *debug_lookup, u64 tick_id); void phys_create_contacts(struct phys_ctx *ctx);
void phys_prepare_contacts(struct entity_store *store, struct entity_lookup *contact_lookup, struct entity_lookup *debug_lookup); void phys_prepare_contacts(struct phys_ctx *ctx);
void phys_warm_start_contacts(struct entity_store *store); void phys_warm_start_contacts(struct phys_ctx *ctx);
void phys_solve_contacts(struct entity_store *store, f32 dt, b32 apply_bias); void phys_solve_contacts(struct phys_ctx *ctx, f32 dt, b32 apply_bias);
/* ========================== * /* ========================== *
* Motor joint * Motor joint
@ -119,9 +131,9 @@ struct phys_motor_joint {
}; };
struct phys_motor_joint motor_joint_from_def(struct phys_motor_joint_def def); struct phys_motor_joint motor_joint_from_def(struct phys_motor_joint_def def);
void phys_prepare_motor_joints(struct entity_store *store); void phys_prepare_motor_joints(struct phys_ctx *ctx);
void phys_warm_start_motor_joints(struct entity_store *store); void phys_warm_start_motor_joints(struct phys_ctx *ctx);
void phys_solve_motor_joints(struct entity_store *store, f32 dt); void phys_solve_motor_joints(struct phys_ctx *ctx, f32 dt);
/* ========================== * /* ========================== *
* Mouse joint * Mouse joint
@ -144,28 +156,28 @@ struct phys_mouse_joint {
struct xform linear_mass_xf; struct xform linear_mass_xf;
}; };
void phys_create_mouse_joints(struct entity_store *store, struct v2 cursor, b32 start_dragging, b32 stop_dragging); void phys_create_mouse_joints(struct phys_ctx *ctx);
void phys_prepare_mouse_joints(struct entity_store *store); void phys_prepare_mouse_joints(struct phys_ctx *ctx);
void phys_warm_start_mouse_joints(struct entity_store *store); void phys_warm_start_mouse_joints(struct phys_ctx *ctx);
void phys_solve_mouse_joints(struct entity_store *store, f32 dt); void phys_solve_mouse_joints(struct phys_ctx *ctx, f32 dt);
/* ========================== * /* ========================== *
* Earliest time of impact * Earliest time of impact
* ========================== */ * ========================== */
f32 phys_determine_earliest_toi_for_bullets(struct entity_store *store, f32 step_dt, f32 tolerance, u32 max_iterations); f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f32 tolerance, u32 max_iterations);
/* ========================== * /* ========================== *
* Integration * Integration
* ========================== */ * ========================== */
void phys_integrate_forces(struct entity_store *store, f32 dt); void phys_integrate_forces(struct phys_ctx *ctx, f32 dt);
void phys_integrate_velocities(struct entity_store *store, f32 dt); void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt);
/* ========================== * /* ========================== *
* Step * Step
* ========================== */ * ========================== */
void phys_step(struct entity_store *store, f32 step_dt, struct entity_lookup *contact_lookup, struct entity_lookup *collision_debug_lookup, u64 tick_id, struct v2 dbg_cursor_pos, b32 dbg_start_dragging, b32 dbg_stop_dragging); void phys_step(struct phys_ctx *ctx, f32 timestep);
#endif #endif