From cc519efdb61456b1a17a9d1b3ce6cce10006d826 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Sat, 5 Apr 2025 20:30:10 -0700 Subject: [PATCH] seems to be right? --- src/bike.rs | 5 ++-- src/physics.rs | 69 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/bike.rs b/src/bike.rs index 9a6cd6a..558a514 100644 --- a/src/bike.rs +++ b/src/bike.rs @@ -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, diff --git a/src/physics.rs b/src/physics.rs index 1b961b9..a952522 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -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), ); }