calculate constraint softness dynamically

This commit is contained in:
jacob 2025-05-19 13:53:36 -05:00
parent 3b19e1260e
commit 6c8017b97f
8 changed files with 51 additions and 58 deletions

View File

@ -335,9 +335,8 @@ void app_entry_point(struct string args_str)
struct mixer_startup_receipt mixer_sr = mixer_startup(); struct mixer_startup_receipt mixer_sr = mixer_startup();
struct sound_startup_receipt sound_sr = sound_startup(&work_sr, &asset_cache_sr, &resource_sr); 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 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 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); struct playback_startup_receipt playback_sr = playback_startup(&mixer_sr);
(UNUSED)user_sr; (UNUSED)user_sr;

View File

@ -57,8 +57,13 @@
#define SIM_SPAWN_TESTENT 0 #define SIM_SPAWN_TESTENT 0
#define SIM_PLAYER_AIM 1 #define SIM_PLAYER_AIM 1
#if 0
# define SIM_MAX_LINEAR_VELOCITY 500 # define SIM_MAX_LINEAR_VELOCITY 500
# define SIM_MAX_ANGULAR_VELOCITY (TAU * 20) # 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 0
#define COLLIDER_DEBUG_DETAILED 1 #define COLLIDER_DEBUG_DETAILED 1

View File

@ -6,36 +6,6 @@
#include "space.h" #include "space.h"
#include "uid.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 * 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++]; contact = &constraint->points[constraint->num_points++];
MEMZERO_STRUCT(contact); MEMZERO_STRUCT(contact);
contact->id = id; contact->id = id;
constraint->softness = G.contact_softness;
constraint->pushout_velocity = 3.0f; 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; velocity_bias = separation / dt;
} else if (apply_bias) { } else if (apply_bias) {
/* Soft constraint */ /* 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; f32 pushout_velocity = constraint->pushout_velocity;
mass_scale = softness.mass_scale; mass_scale = softness.mass_scale;
impulse_scale = softness.impulse_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 * 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 phys_motor_joint_from_def(struct phys_motor_joint_def def)
{ {
struct phys_motor_joint res = ZI; struct phys_motor_joint res = ZI;
@ -750,14 +727,27 @@ void phys_solve_motor_joints(struct phys_step_ctx *ctx, f32 dt)
* Mouse joint * 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 phys_mouse_joint_from_def(struct phys_mouse_joint_def def)
{ {
struct phys_mouse_joint res = ZI; struct phys_mouse_joint res = ZI;
res.target = def.target; res.target = def.target;
res.point_local_start = def.point_local_start; res.point_local_start = def.point_local_start;
res.point_local_end = def.point_local_end; res.point_local_end = def.point_local_end;
res.linear_softness = G.mouse_joint_linear_softness; res.linear_spring_hz = def.linear_spring_hz;
res.angular_softness = G.mouse_joint_angular_softness; 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; res.max_force = def.max_force;
return res; return res;
} }
@ -851,7 +841,7 @@ void phys_solve_mouse_joints(struct phys_step_ctx *ctx, f32 dt)
/* Angular impulse */ /* 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 mass_scale = softness.mass_scale;
f32 impulse_scale = softness.impulse_scale; f32 impulse_scale = softness.impulse_scale;
f32 impulse = mass_scale * (-w / inv_i) - impulse_scale * joint->angular_impulse; 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 vcp = v2_sub(point_start, xf.og);
struct v2 separation = v2_sub(point_start, point_end); 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); struct v2 bias = v2_mul(separation, softness.bias_rate);
f32 mass_scale = softness.mass_scale; f32 mass_scale = softness.mass_scale;
f32 impulse_scale = softness.impulse_scale; f32 impulse_scale = softness.impulse_scale;

View File

@ -29,13 +29,6 @@ struct phys_step_ctx {
phys_collision_callback_func *collision_callback; phys_collision_callback_func *collision_callback;
}; };
/* ========================== *
* Startup
* ========================== */
struct phys_startup_receipt { i32 _; };
struct phys_startup_receipt phys_startup(void);
/* ========================== * /* ========================== *
* Contact * Contact
* ========================== */ * ========================== */
@ -76,7 +69,6 @@ struct phys_contact_constraint {
f32 friction; f32 friction;
struct math_spring_result softness;
f32 pushout_velocity; f32 pushout_velocity;
}; };
@ -134,6 +126,7 @@ struct phys_motor_joint {
f32 angular_mass; 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); 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_prepare_motor_joints(struct phys_step_ctx *ctx);
void phys_warm_start_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 sim_ent_id target;
struct v2 point_local_start; struct v2 point_local_start;
struct v2 point_local_end; struct v2 point_local_end;
f32 linear_spring_hz;
f32 linear_spring_damp;
f32 angular_spring_hz;
f32 angular_spring_damp;
f32 max_force; f32 max_force;
}; };
@ -154,8 +151,10 @@ struct phys_mouse_joint {
struct sim_ent_id target; struct sim_ent_id target;
struct v2 point_local_start; struct v2 point_local_start;
struct v2 point_local_end; struct v2 point_local_end;
struct math_spring_result linear_softness; f32 linear_spring_hz;
struct math_spring_result angular_softness; f32 linear_spring_damp;
f32 angular_spring_hz;
f32 angular_spring_damp;
f32 max_force; f32 max_force;
f32 inv_m; f32 inv_m;
@ -167,6 +166,7 @@ struct phys_mouse_joint {
struct xform linear_mass_xf; 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); 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_prepare_mouse_joints(struct phys_step_ctx *ctx);
void phys_warm_start_mouse_joints(struct phys_step_ctx *ctx); void phys_warm_start_mouse_joints(struct phys_step_ctx *ctx);

View File

@ -480,6 +480,7 @@ struct renderer_startup_receipt renderer_startup(struct sys_window *window)
.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT, .BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
.BufferCount = 2, .BufferCount = 2,
.Scaling = DXGI_SCALING_NONE, .Scaling = DXGI_SCALING_NONE,
.Flags = 0,
/* More efficient FLIP presentation model. /* More efficient FLIP presentation model.
* Windows 10 allows to use DXGI_SWAP_EFFECT_FLIP_DISCARD * Windows 10 allows to use DXGI_SWAP_EFFECT_FLIP_DISCARD

View File

@ -250,8 +250,10 @@ INTERNAL void spawn_test_entities2(struct sim_ent *parent, struct v2 pos)
sim_ent_enable_prop(e, SEPROP_DYNAMIC); sim_ent_enable_prop(e, SEPROP_DYNAMIC);
e->mass_unscaled = 100; e->mass_unscaled = 100;
e->inertia_unscaled = 50; e->inertia_unscaled = 50;
#if 0
e->linear_ground_friction = 100; e->linear_ground_friction = 100;
e->angular_ground_friction = 50; e->angular_ground_friction = 50;
#endif
} }
#endif #endif
@ -1058,7 +1060,7 @@ void sim_step(struct sim_step_ctx *ctx)
sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE); sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE);
ent->move_joint = joint_ent->id; 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.e0 = joint_ent->id; /* Re-using joint entity as e0 */
def.e1 = ent->id; def.e1 = ent->id;
def.correction_rate = 0; def.correction_rate = 0;
@ -1099,7 +1101,7 @@ void sim_step(struct sim_step_ctx *ctx)
sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE); sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE);
ent->aim_joint = joint_ent->id; 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.e0 = joint_ent->id; /* Re-using joint entity as e0 */
def.e1 = ent->id; def.e1 = ent->id;
def.max_force = 0; 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 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.e0 = root->id;
def.e1 = ent->id; def.e1 = ent->id;
def.correction_rate = 0; 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); struct xform xf = sim_ent_get_xform(target_ent);
f32 mass = target_ent->mass_unscaled * math_fabs(xform_get_determinant(xf)); 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; def.target = target_ent->id;
if (sim_ent_id_eq(joint_ent->mouse_joint_data.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; def.point_local_start = joint_ent->mouse_joint_data.point_local_start;

View File

@ -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 asset_cache_startup_receipt *asset_cache_sr,
struct sound_startup_receipt *sound_sr, struct sound_startup_receipt *sound_sr,
struct mixer_startup_receipt *mixer_sr, struct mixer_startup_receipt *mixer_sr,
struct phys_startup_receipt *phys_sr,
struct host_startup_receipt *host_sr, struct host_startup_receipt *host_sr,
struct sim_startup_receipt *sim_sr, struct sim_startup_receipt *sim_sr,
struct string connect_address_str, 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)asset_cache_sr;
(UNUSED)sound_sr; (UNUSED)sound_sr;
(UNUSED)mixer_sr; (UNUSED)mixer_sr;
(UNUSED)phys_sr;
(UNUSED)host_sr; (UNUSED)host_sr;
(UNUSED)sim_sr; (UNUSED)sim_sr;

View File

@ -10,7 +10,6 @@ struct draw_startup_receipt;
struct asset_cache_startup_receipt; struct asset_cache_startup_receipt;
struct sound_startup_receipt; struct sound_startup_receipt;
struct mixer_startup_receipt; struct mixer_startup_receipt;
struct phys_startup_receipt;
struct host_startup_receipt; struct host_startup_receipt;
struct sim_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 asset_cache_startup_receipt *asset_cache_sr,
struct sound_startup_receipt *sound_sr, struct sound_startup_receipt *sound_sr,
struct mixer_startup_receipt *mixer_sr, struct mixer_startup_receipt *mixer_sr,
struct phys_startup_receipt *phys_sr,
struct host_startup_receipt *host_sr, struct host_startup_receipt *host_sr,
struct sim_startup_receipt *sim_sr, struct sim_startup_receipt *sim_sr,
struct string connect_address_str, struct string connect_address_str,