calculate constraint softness dynamically
This commit is contained in:
parent
3b19e1260e
commit
6c8017b97f
@ -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;
|
||||||
|
|||||||
@ -57,8 +57,13 @@
|
|||||||
#define SIM_SPAWN_TESTENT 0
|
#define SIM_SPAWN_TESTENT 0
|
||||||
#define SIM_PLAYER_AIM 1
|
#define SIM_PLAYER_AIM 1
|
||||||
|
|
||||||
#define SIM_MAX_LINEAR_VELOCITY 500
|
#if 0
|
||||||
#define SIM_MAX_ANGULAR_VELOCITY (TAU * 20)
|
# 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 0
|
||||||
#define COLLIDER_DEBUG_DETAILED 1
|
#define COLLIDER_DEBUG_DETAILED 1
|
||||||
|
|||||||
62
src/phys.c
62
src/phys.c
@ -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;
|
||||||
|
|||||||
20
src/phys.h
20
src/phys.h
@ -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);
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user