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
* ========================== */
/* Mouse drag */
b32 dbg_start_dragging = false;
b32 dbg_stop_dragging = false;
for (u64 i = 0; i < game_cmds.count; ++i) {
struct game_cmd cmd = game_cmds.cmds[i];
b32 start = cmd.state == GAME_CMD_STATE_START;
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;
}
}
{
struct phys_ctx ctx = ZI;
ctx.tick_id = G.tick.tick_id;
ctx.store = store;
ctx.contact_lookup = &G.contact_lookup;
ctx.debug_lookup = &G.collision_debug_lookup;
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

View File

@ -37,8 +37,12 @@ struct phys_startup_receipt phys_startup(void)
* 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);
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) {
struct entity *constraint_ent = &store->entities[entity_index];
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
}
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) {
struct entity *constraint_ent = &store->entities[entity_index];
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) {
struct entity *constraint_ent = &store->entities[entity_index];
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;
}
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) {
struct entity *joint_ent = &store->entities[entity_index];
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) {
struct entity *joint_ent = &store->entities[entity_index];
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) {
struct entity *joint_ent = &store->entities[entity_index];
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
* ========================== */
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 *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) {
struct entity *joint_ent = &store->entities[entity_index];
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) {
struct entity *joint_ent = &store->entities[entity_index];
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) {
struct entity *joint_ent = &store->entities[entity_index];
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
* ========================== */
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;
f32 smallest_t = 1;
@ -1031,8 +1052,9 @@ f32 phys_determine_earliest_toi_for_bullets(struct entity_store *store, f32 step
* 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) {
struct entity *ent = &store->entities[entity_index];
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) {
struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue;
@ -1082,53 +1105,54 @@ void phys_integrate_velocities(struct entity_store *store, f32 dt)
* 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) {
/* TOI */
f32 step_dt = remaining_dt;
{
#if GAME_PHYSICS_ENABLE_TOI
const f32 min_toi = 0.000001f;
const f32 tolerance = 0.00001f;
const u32 max_iterations = 16;
f32 earliest_toi = max_f32(phys_determine_earliest_toi_for_bullets(store, remaining_dt, tolerance, max_iterations), min_toi);
remaining_dt = remaining_dt * earliest_toi;
f32 earliest_toi = max_f32(phys_determine_earliest_toi_for_bullets(ctx, step_dt, tolerance, max_iterations), min_toi);
step_dt = remaining_dt * earliest_toi;
#else
(UNUSED)toi;
(UNUSED)determine_earliest_toi_for_bullets;
#endif
}
phys_create_contacts(store, contact_lookup, collision_debug_lookup, tick_id);
phys_create_mouse_joints(store, dbg_cursor_pos, dbg_start_dragging, dbg_stop_dragging);
phys_create_contacts(ctx);
phys_create_mouse_joints(ctx);
phys_prepare_contacts(store, contact_lookup, collision_debug_lookup);
phys_prepare_motor_joints(store);
phys_prepare_mouse_joints(store);
phys_prepare_contacts(ctx);
phys_prepare_motor_joints(ctx);
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) {
#if GAME_PHYSICS_ENABLE_WARM_STARTING
phys_warm_start_contacts(store);
phys_warm_start_motor_joints(store);
phys_warm_start_mouse_joints(store);
phys_warm_start_contacts(ctx);
phys_warm_start_motor_joints(ctx);
phys_warm_start_mouse_joints(ctx);
#endif
#if GAME_PHYSICS_ENABLE_COLLISION
phys_solve_contacts(store, substep_dt, true);
phys_solve_contacts(ctx, substep_dt, true);
#endif
phys_solve_motor_joints(store, substep_dt);
phys_solve_mouse_joints(store, substep_dt);
phys_solve_motor_joints(ctx, 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
phys_solve_contacts(store, substep_dt, false); /* Relaxation */
phys_solve_contacts(ctx, substep_dt, false); /* Relaxation */
#endif
}
remaining_dt -= remaining_dt;
remaining_dt -= step_dt;
}
}

View File

@ -7,6 +7,18 @@
struct entity_store;
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 entity_handle e0;
struct entity_handle e1;
@ -79,10 +91,10 @@ struct phys_collision_debug {
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_prepare_contacts(struct entity_store *store, struct entity_lookup *contact_lookup, struct entity_lookup *debug_lookup);
void phys_warm_start_contacts(struct entity_store *store);
void phys_solve_contacts(struct entity_store *store, f32 dt, b32 apply_bias);
void phys_create_contacts(struct phys_ctx *ctx);
void phys_prepare_contacts(struct phys_ctx *ctx);
void phys_warm_start_contacts(struct phys_ctx *ctx);
void phys_solve_contacts(struct phys_ctx *ctx, f32 dt, b32 apply_bias);
/* ========================== *
* Motor joint
@ -119,9 +131,9 @@ struct phys_motor_joint {
};
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_warm_start_motor_joints(struct entity_store *store);
void phys_solve_motor_joints(struct entity_store *store, f32 dt);
void phys_prepare_motor_joints(struct phys_ctx *ctx);
void phys_warm_start_motor_joints(struct phys_ctx *ctx);
void phys_solve_motor_joints(struct phys_ctx *ctx, f32 dt);
/* ========================== *
* Mouse joint
@ -144,28 +156,28 @@ struct phys_mouse_joint {
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_prepare_mouse_joints(struct entity_store *store);
void phys_warm_start_mouse_joints(struct entity_store *store);
void phys_solve_mouse_joints(struct entity_store *store, f32 dt);
void phys_create_mouse_joints(struct phys_ctx *ctx);
void phys_prepare_mouse_joints(struct phys_ctx *ctx);
void phys_warm_start_mouse_joints(struct phys_ctx *ctx);
void phys_solve_mouse_joints(struct phys_ctx *ctx, f32 dt);
/* ========================== *
* 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
* ========================== */
void phys_integrate_forces(struct entity_store *store, f32 dt);
void phys_integrate_velocities(struct entity_store *store, f32 dt);
void phys_integrate_forces(struct phys_ctx *ctx, f32 dt);
void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt);
/* ========================== *
* 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