From 3498fcc5aa9ae7552ce07ce3e29611d08d3447c6 Mon Sep 17 00:00:00 2001
From: Joe Ardent <code@ardent.nebcorp.com>
Date: Sat, 29 Mar 2025 16:51:13 -0700
Subject: [PATCH] working ray-casting, no jitter

---
 src/bike.rs    | 12 ++++--------
 src/physics.rs | 18 +++++++++++++-----
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/src/bike.rs b/src/bike.rs
index 3e03068..e3c0340 100644
--- a/src/bike.rs
+++ b/src/bike.rs
@@ -6,10 +6,10 @@ use bevy::prelude::*;
 
 use crate::physics::CatControllerState;
 
-pub const REST_DISTANCE: Scalar = 1.0;
 pub const SPRING_CONSTANT: Scalar = 50.0;
-pub const DAMPING_CONSTANT: Scalar = 3.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 FRONT_ATTACH: Vec3 = Vec3::new(0.0, 0.0, -0.7);
 pub const REAR_ATTACH: Vec3 = Vec3::new(0.0, 0.0, 0.7);
 
@@ -113,18 +113,16 @@ fn spawn_wheels(
     body: Entity,
 ) {
     let mesh: Mesh = Sphere::new(WHEEL_RADIUS).into();
-    let collider = Collider::sphere(WHEEL_RADIUS);
 
     let front_rake = Vec3::new(0.0, -1.0, -0.57).normalize(); // about 30 degrees
     let front_wheel_pos = FRONT_ATTACH + (front_rake * REST_DISTANCE);
 
     wheel_caster(
         commands,
-        collider.clone(),
         FRONT_ATTACH,
         Dir3::new_unchecked(front_rake),
         body,
-        REST_DISTANCE,
+        REST_DISTANCE + WHEEL_RADIUS,
         CyberWheel::Front,
     );
     wheel_mesh(
@@ -149,11 +147,10 @@ fn spawn_wheels(
 
     wheel_caster(
         commands,
-        collider,
         REAR_ATTACH,
         Dir3::new_unchecked(rear_rake),
         body,
-        REST_DISTANCE,
+        REST_DISTANCE + WHEEL_RADIUS,
         CyberWheel::Rear,
     );
     wheel_mesh(
@@ -180,7 +177,6 @@ fn spawn_wheels(
 
 fn wheel_caster(
     commands: &mut ChildBuilder,
-    collider: Collider,
     origin: Vec3,
     direction: Dir3,
     parent: Entity,
diff --git a/src/physics.rs b/src/physics.rs
index e9c2f72..88d670e 100644
--- a/src/physics.rs
+++ b/src/physics.rs
@@ -57,12 +57,12 @@ impl CatControllerState {
 mod systems {
     use std::f32::consts::{FRAC_PI_3, FRAC_PI_4};
 
-    use avian3d::{math::Scalar, prelude::*};
+    use avian3d::prelude::*;
     use bevy::prelude::*;
 
     use super::{CatControllerSettings, CatControllerState, CyberLean};
     use crate::{
-        bike::{CyberBikeBody, CyberWheel, WheelConfig, WheelState},
+        bike::{CyberBikeBody, CyberWheel, WheelConfig, WheelState, WHEEL_RADIUS},
         input::InputState,
     };
 
@@ -163,7 +163,15 @@ mod systems {
     }
 
     pub(super) fn suspension(
-        mut bike_body_query: Query<(&Transform, &mut ExternalForce), With<CyberBikeBody>>,
+        mut bike_body_query: Query<
+            (
+                &Transform,
+                &LinearVelocity,
+                &AngularVelocity,
+                &mut ExternalForce,
+            ),
+            With<CyberBikeBody>,
+        >,
         mut wheel_mesh_query: Query<
             (
                 &mut Transform,
@@ -206,7 +214,7 @@ mod systems {
                 }
             }
         }
-        let (bike_xform, mut bike_forces) = bike_body_query.single_mut();
+        let (bike_xform, lin_vel, ang_vel, mut bike_forces) = bike_body_query.single_mut();
         for (mut xform, mut state, global_xform, config, wheel) in wheel_mesh_query.iter_mut() {
             let (caster, hits) = match wheel {
                 CyberWheel::Front => (front_caster, front_hits),
@@ -216,7 +224,7 @@ mod systems {
             if let Some(hit) = hits.iter().next() {
                 let dist = hit.distance;
                 let cdir = caster.direction.as_vec3();
-                xform.translation = config.attach + (cdir * dist);
+                xform.translation = config.attach + (cdir * (dist - WHEEL_RADIUS));
 
                 let displacement = config.rest_dist - dist;
                 let damper_vel = (state.displacement - displacement) / dt;