From 0c1d6a58defcdeee5d520e13d204b90bf7678c78 Mon Sep 17 00:00:00 2001 From: jacob Date: Fri, 10 Jan 2025 16:05:22 -0600 Subject: [PATCH] move phys arguments into phys_ctx --- src/game.c | 41 ++++++++++++------------ src/phys.c | 92 ++++++++++++++++++++++++++++++++++-------------------- src/phys.h | 42 ++++++++++++++++--------- 3 files changed, 106 insertions(+), 69 deletions(-) diff --git a/src/game.c b/src/game.c index 7059f61d..beeec1ba 100644 --- a/src/game.c +++ b/src/game.c @@ -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 diff --git a/src/phys.c b/src/phys.c index c8f7dc57..58b92c20 100644 --- a/src/phys.c +++ b/src/phys.c @@ -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; } } diff --git a/src/phys.h b/src/phys.h index 7cea432a..6e4f00c5 100644 --- a/src/phys.h +++ b/src/phys.h @@ -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