seems to be right?

This commit is contained in:
Joe Ardent 2025-04-05 20:30:10 -07:00
parent 884dc14c9f
commit cc519efdb6
2 changed files with 54 additions and 20 deletions

View file

@ -10,6 +10,7 @@ pub const SPRING_CONSTANT: Scalar = 50.0;
pub const DAMPING_CONSTANT: Scalar = 10.0;
pub const WHEEL_RADIUS: Scalar = 0.4;
pub const REST_DISTANCE: Scalar = 1.0 + WHEEL_RADIUS;
pub const FRICTION_COEFF: Scalar = 0.8;
pub const FRONT_ATTACH: Vec3 = Vec3::new(0.0, 0.0, -0.7);
pub const REAR_ATTACH: Vec3 = Vec3::new(0.0, 0.0, 0.7);
@ -141,7 +142,7 @@ fn spawn_wheels(
REST_DISTANCE,
SPRING_CONSTANT,
DAMPING_CONSTANT,
0.5,
FRICTION_COEFF,
WHEEL_RADIUS,
),
CyberWheel::Front,
@ -169,7 +170,7 @@ fn spawn_wheels(
REST_DISTANCE,
SPRING_CONSTANT,
DAMPING_CONSTANT,
0.5,
FRICTION_COEFF,
WHEEL_RADIUS,
),
CyberWheel::Rear,

View file

@ -219,7 +219,7 @@ mod systems {
let cdir = caster.direction.as_vec3();
xform.translation = config.attach + (cdir * (dist - WHEEL_RADIUS));
let force = hit.normal * mag;
let force = hit.normal * mag * dt * 100.0;
gizmos.arrow(
hit_point,
hit_point + force,
@ -252,32 +252,65 @@ mod systems {
return;
};
let max_thrust = 100.0;
let max_yaw = 50.0;
let thrust = input.throttle * max_thrust;
let yaw = input.yaw * max_yaw;
let dt = time.delta().as_secs_f32();
let max_thrust = 1000.0;
let thrust_force = input.throttle * max_thrust * dt;
let max_yaw = 500.0;
let yaw_force = input.yaw * max_yaw * dt;
for (mut state, config, wheel) in wheels.iter_mut() {
if let Some(contact_point) = state.contact_point {
let vel = bike_body.velocity_at_point(contact_point);
bevy::log::info_once!("vel: {vel:?}");
let friction = config.friction;
bevy::log::info_once!(friction);
// just to shut the linter up about state not needing to be mut
state.sliding = true;
// if contact_point is Some, we also have a normal.
let normal = state.contact_normal.unwrap().normalize();
let max_force_mag = state.force_normal * config.friction;
let normal = state.contact_normal.unwrap();
let steering = match wheel {
CyberWheel::Front => normal.cross(*bike_xform.back()) * yaw,
let yaw_dir = match wheel {
CyberWheel::Front => normal.cross(*bike_xform.back()).normalize_or_zero(),
CyberWheel::Rear => Vec3::ZERO,
};
let thrust = normal.cross(*bike_xform.right()) * thrust;
let total = (thrust + steering) * dt;
bike_force.apply_force_at_point(total, contact_point, bike_xform.translation);
let thrust_dir = normal.cross(*bike_xform.right());
let vel = bike_body.velocity_at_point(contact_point - bike_xform.translation);
let yaw = yaw_force * yaw_dir;
let thrust = thrust_force * thrust_dir;
let yust = yaw + thrust;
bevy::log::debug!("yust: {yust:?}");
bevy::log::debug!("{:?}", bike_xform.left());
let left = bike_xform.forward().cross(normal);
let friction_dir = match wheel {
CyberWheel::Front => {
if yaw_force + thrust_force > 0.1 {
normal.cross(yust.normalize()).normalize()
} else {
left
}
}
CyberWheel::Rear => left,
};
let friction_factor = -0.025 * vel.dot(friction_dir);
let friction = (friction_factor / dt) * friction_dir;
let mut force = yust + friction;
force *= dt * 50.0;
let force_mag = force.length();
if force_mag > max_force_mag {
state.sliding = true;
force = force.normalize_or_zero() * max_force_mag;
//bevy::log::info!("clamping {wheel:?} to {max_force_mag}: {friction_factor}");
} else {
state.sliding = false;
}
bike_force.apply_force_at_point(force, contact_point, bike_xform.translation);
gizmos.arrow(
contact_point,
contact_point + total,
contact_point + friction,
Color::linear_rgb(1., 1., 0.2),
);
}