From 6c8017b97f97dd8e5dc5248ccaa7f4f2eda7433c Mon Sep 17 00:00:00 2001 From: jacob Date: Mon, 19 May 2025 13:53:36 -0500 Subject: [PATCH] calculate constraint softness dynamically --- src/app.c | 3 +-- src/config.h | 9 +++++-- src/phys.c | 62 +++++++++++++++++++------------------------- src/phys.h | 20 +++++++------- src/renderer_d3d11.c | 1 + src/sim_step.c | 10 ++++--- src/user.c | 2 -- src/user.h | 2 -- 8 files changed, 51 insertions(+), 58 deletions(-) diff --git a/src/app.c b/src/app.c index 7d4dc4bd..97a19427 100644 --- a/src/app.c +++ b/src/app.c @@ -335,9 +335,8 @@ void app_entry_point(struct string args_str) struct mixer_startup_receipt mixer_sr = mixer_startup(); struct sound_startup_receipt sound_sr = sound_startup(&work_sr, &asset_cache_sr, &resource_sr); struct draw_startup_receipt draw_sr = draw_startup(&renderer_sr, &font_sr); - struct phys_startup_receipt phys_sr = phys_startup(); struct sim_startup_receipt sim_sr = sim_startup(); - struct user_startup_receipt user_sr = user_startup(&work_sr, &renderer_sr, &font_sr, &sprite_sr, &draw_sr, &asset_cache_sr, &sound_sr, &mixer_sr, &phys_sr, &host_sr, &sim_sr, connect_address, &window); + struct user_startup_receipt user_sr = user_startup(&work_sr, &renderer_sr, &font_sr, &sprite_sr, &draw_sr, &asset_cache_sr, &sound_sr, &mixer_sr, &host_sr, &sim_sr, connect_address, &window); struct playback_startup_receipt playback_sr = playback_startup(&mixer_sr); (UNUSED)user_sr; diff --git a/src/config.h b/src/config.h index 2cdac61b..b7ac6444 100644 --- a/src/config.h +++ b/src/config.h @@ -57,8 +57,13 @@ #define SIM_SPAWN_TESTENT 0 #define SIM_PLAYER_AIM 1 -#define SIM_MAX_LINEAR_VELOCITY 500 -#define SIM_MAX_ANGULAR_VELOCITY (TAU * 20) +#if 0 +# define SIM_MAX_LINEAR_VELOCITY 500 +# define SIM_MAX_ANGULAR_VELOCITY (TAU * 20) +#else +# define SIM_MAX_LINEAR_VELOCITY F32_INFINITY +# define SIM_MAX_ANGULAR_VELOCITY F32_INFINITY +#endif #define COLLIDER_DEBUG 0 #define COLLIDER_DEBUG_DETAILED 1 diff --git a/src/phys.c b/src/phys.c index 08e85000..e5c12644 100644 --- a/src/phys.c +++ b/src/phys.c @@ -6,36 +6,6 @@ #include "space.h" #include "uid.h" -GLOBAL struct { - /* Constants */ - struct math_spring_result contact_softness; - struct math_spring_result mouse_joint_linear_softness; - struct math_spring_result mouse_joint_angular_softness; -} G = ZI, DEBUG_ALIAS(G, G_phys); - -/* ========================== * - * Startup - * ========================== */ - -struct phys_startup_receipt phys_startup(void) -{ - /* Initialize constants */ - const f32 substep_dt = (1.f / ((f32)SIM_TICKS_PER_SECOND * (f32)SIM_PHYSICS_SUBSTEPS)); - - const f32 contact_frequency = (1.f / substep_dt) / 8.f; - const f32 contact_damping_ratio = 10; - G.contact_softness = math_spring(contact_frequency, contact_damping_ratio, substep_dt); - - const f32 mouse_joint_linear_frequency = 5.0f; - const f32 mouse_joint_linear_damping_ratio = 0.7f; - const f32 mouse_joint_angular_frequency = 0.5f; - const f32 mouse_joint_angular_damping_ratio = 0.1f; - G.mouse_joint_linear_softness = math_spring(mouse_joint_linear_frequency, mouse_joint_linear_damping_ratio, substep_dt); - G.mouse_joint_angular_softness = math_spring(mouse_joint_angular_frequency, mouse_joint_angular_damping_ratio, substep_dt); - - return (struct phys_startup_receipt) { 0 }; -} - /* ========================== * * Contact * ========================== */ @@ -173,7 +143,6 @@ void phys_create_and_update_contacts(struct phys_step_ctx *ctx, f32 elapsed_dt, contact = &constraint->points[constraint->num_points++]; MEMZERO_STRUCT(contact); contact->id = id; - constraint->softness = G.contact_softness; constraint->pushout_velocity = 3.0f; } @@ -491,7 +460,9 @@ void phys_solve_contacts(struct phys_step_ctx *ctx, f32 dt, b32 apply_bias) velocity_bias = separation / dt; } else if (apply_bias) { /* Soft constraint */ - struct math_spring_result softness = constraint->softness; + const f32 spring_hz = 25; + const f32 spring_damp = 10; + struct math_spring_result softness = math_spring(spring_hz, spring_damp, dt); f32 pushout_velocity = constraint->pushout_velocity; mass_scale = softness.mass_scale; impulse_scale = softness.impulse_scale; @@ -562,6 +533,12 @@ void phys_solve_contacts(struct phys_step_ctx *ctx, f32 dt, b32 apply_bias) * Motor joint * ========================== */ +struct phys_motor_joint_def phys_motor_joint_def_init(void) +{ + struct phys_motor_joint_def def = ZI; + return def; +} + struct phys_motor_joint phys_motor_joint_from_def(struct phys_motor_joint_def def) { struct phys_motor_joint res = ZI; @@ -750,14 +727,27 @@ void phys_solve_motor_joints(struct phys_step_ctx *ctx, f32 dt) * Mouse joint * ========================== */ +struct phys_mouse_joint_def phys_mouse_joint_def_init(void) +{ + struct phys_mouse_joint_def def = ZI; + def.linear_spring_hz = 5.0f; + def.linear_spring_damp = 0.7f; + def.angular_spring_hz = 5.0f; + def.angular_spring_damp = 0.1f; + def.max_force = 1000.0f; + return def; +} + struct phys_mouse_joint phys_mouse_joint_from_def(struct phys_mouse_joint_def def) { struct phys_mouse_joint res = ZI; res.target = def.target; res.point_local_start = def.point_local_start; res.point_local_end = def.point_local_end; - res.linear_softness = G.mouse_joint_linear_softness; - res.angular_softness = G.mouse_joint_angular_softness; + res.linear_spring_hz = def.linear_spring_hz; + res.linear_spring_damp = def.linear_spring_damp; + res.angular_spring_hz = def.linear_spring_hz; + res.angular_spring_damp = def.angular_spring_damp; res.max_force = def.max_force; return res; } @@ -851,7 +841,7 @@ void phys_solve_mouse_joints(struct phys_step_ctx *ctx, f32 dt) /* Angular impulse */ { - struct math_spring_result softness = joint->angular_softness; + struct math_spring_result softness = math_spring(joint->angular_spring_hz, joint->angular_spring_damp, dt); f32 mass_scale = softness.mass_scale; f32 impulse_scale = softness.impulse_scale; f32 impulse = mass_scale * (-w / inv_i) - impulse_scale * joint->angular_impulse; @@ -871,7 +861,7 @@ void phys_solve_mouse_joints(struct phys_step_ctx *ctx, f32 dt) struct v2 vcp = v2_sub(point_start, xf.og); struct v2 separation = v2_sub(point_start, point_end); - struct math_spring_result softness = joint->linear_softness; + struct math_spring_result softness = math_spring(joint->linear_spring_hz, joint->linear_spring_damp, dt); struct v2 bias = v2_mul(separation, softness.bias_rate); f32 mass_scale = softness.mass_scale; f32 impulse_scale = softness.impulse_scale; diff --git a/src/phys.h b/src/phys.h index adbc554a..e65a8606 100644 --- a/src/phys.h +++ b/src/phys.h @@ -29,13 +29,6 @@ struct phys_step_ctx { phys_collision_callback_func *collision_callback; }; -/* ========================== * - * Startup - * ========================== */ - -struct phys_startup_receipt { i32 _; }; -struct phys_startup_receipt phys_startup(void); - /* ========================== * * Contact * ========================== */ @@ -76,7 +69,6 @@ struct phys_contact_constraint { f32 friction; - struct math_spring_result softness; f32 pushout_velocity; }; @@ -134,6 +126,7 @@ struct phys_motor_joint { f32 angular_mass; }; +struct phys_motor_joint_def phys_motor_joint_def_init(void); struct phys_motor_joint phys_motor_joint_from_def(struct phys_motor_joint_def def); void phys_prepare_motor_joints(struct phys_step_ctx *ctx); void phys_warm_start_motor_joints(struct phys_step_ctx *ctx); @@ -147,6 +140,10 @@ struct phys_mouse_joint_def { struct sim_ent_id target; struct v2 point_local_start; struct v2 point_local_end; + f32 linear_spring_hz; + f32 linear_spring_damp; + f32 angular_spring_hz; + f32 angular_spring_damp; f32 max_force; }; @@ -154,8 +151,10 @@ struct phys_mouse_joint { struct sim_ent_id target; struct v2 point_local_start; struct v2 point_local_end; - struct math_spring_result linear_softness; - struct math_spring_result angular_softness; + f32 linear_spring_hz; + f32 linear_spring_damp; + f32 angular_spring_hz; + f32 angular_spring_damp; f32 max_force; f32 inv_m; @@ -167,6 +166,7 @@ struct phys_mouse_joint { struct xform linear_mass_xf; }; +struct phys_mouse_joint_def phys_mouse_joint_def_init(void); struct phys_mouse_joint phys_mouse_joint_from_def(struct phys_mouse_joint_def def); void phys_prepare_mouse_joints(struct phys_step_ctx *ctx); void phys_warm_start_mouse_joints(struct phys_step_ctx *ctx); diff --git a/src/renderer_d3d11.c b/src/renderer_d3d11.c index 3a885347..3c67063f 100644 --- a/src/renderer_d3d11.c +++ b/src/renderer_d3d11.c @@ -480,6 +480,7 @@ struct renderer_startup_receipt renderer_startup(struct sys_window *window) .BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT, .BufferCount = 2, .Scaling = DXGI_SCALING_NONE, + .Flags = 0, /* More efficient FLIP presentation model. * Windows 10 allows to use DXGI_SWAP_EFFECT_FLIP_DISCARD diff --git a/src/sim_step.c b/src/sim_step.c index 833e4d46..3f89c533 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -250,8 +250,10 @@ INTERNAL void spawn_test_entities2(struct sim_ent *parent, struct v2 pos) sim_ent_enable_prop(e, SEPROP_DYNAMIC); e->mass_unscaled = 100; e->inertia_unscaled = 50; +#if 0 e->linear_ground_friction = 100; e->angular_ground_friction = 50; +#endif } #endif @@ -1058,7 +1060,7 @@ void sim_step(struct sim_step_ctx *ctx) sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE); ent->move_joint = joint_ent->id; - struct phys_motor_joint_def def = ZI; + struct phys_motor_joint_def def = phys_motor_joint_def_init(); def.e0 = joint_ent->id; /* Re-using joint entity as e0 */ def.e1 = ent->id; def.correction_rate = 0; @@ -1099,7 +1101,7 @@ void sim_step(struct sim_step_ctx *ctx) sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE); ent->aim_joint = joint_ent->id; - struct phys_motor_joint_def def = ZI; + struct phys_motor_joint_def def = phys_motor_joint_def_init(); def.e0 = joint_ent->id; /* Re-using joint entity as e0 */ def.e1 = ent->id; def.max_force = 0; @@ -1184,7 +1186,7 @@ void sim_step(struct sim_step_ctx *ctx) struct sim_ent *joint_ent = sim_ent_from_id(world, ent->ground_friction_joint); - struct phys_motor_joint_def def = ZI; + struct phys_motor_joint_def def = phys_motor_joint_def_init(); def.e0 = root->id; def.e1 = ent->id; def.correction_rate = 0; @@ -1239,7 +1241,7 @@ void sim_step(struct sim_step_ctx *ctx) struct xform xf = sim_ent_get_xform(target_ent); f32 mass = target_ent->mass_unscaled * math_fabs(xform_get_determinant(xf)); - struct phys_mouse_joint_def def = ZI; + struct phys_mouse_joint_def def = phys_mouse_joint_def_init(); def.target = target_ent->id; if (sim_ent_id_eq(joint_ent->mouse_joint_data.target, target_ent->id)) { def.point_local_start = joint_ent->mouse_joint_data.point_local_start; diff --git a/src/user.c b/src/user.c index 7e03669d..e3b99cbe 100644 --- a/src/user.c +++ b/src/user.c @@ -188,7 +188,6 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, struct asset_cache_startup_receipt *asset_cache_sr, struct sound_startup_receipt *sound_sr, struct mixer_startup_receipt *mixer_sr, - struct phys_startup_receipt *phys_sr, struct host_startup_receipt *host_sr, struct sim_startup_receipt *sim_sr, struct string connect_address_str, @@ -202,7 +201,6 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, (UNUSED)asset_cache_sr; (UNUSED)sound_sr; (UNUSED)mixer_sr; - (UNUSED)phys_sr; (UNUSED)host_sr; (UNUSED)sim_sr; diff --git a/src/user.h b/src/user.h index 41046e91..eeabb1ee 100644 --- a/src/user.h +++ b/src/user.h @@ -10,7 +10,6 @@ struct draw_startup_receipt; struct asset_cache_startup_receipt; struct sound_startup_receipt; struct mixer_startup_receipt; -struct phys_startup_receipt; struct host_startup_receipt; struct sim_startup_receipt; @@ -66,7 +65,6 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, struct asset_cache_startup_receipt *asset_cache_sr, struct sound_startup_receipt *sound_sr, struct mixer_startup_receipt *mixer_sr, - struct phys_startup_receipt *phys_sr, struct host_startup_receipt *host_sr, struct sim_startup_receipt *sim_sr, struct string connect_address_str,