From 4bfd8740fb15f40c83b5c64af475ed60ce2c40a2 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Sun, 16 Feb 2025 13:57:26 -0800 Subject: [PATCH] add input plugin, doesn't do anything yet --- src/input.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 3 +++ src/physics.rs | 24 +++++++++++++++--------- 3 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 src/input.rs diff --git a/src/input.rs b/src/input.rs new file mode 100644 index 0000000..3305a5a --- /dev/null +++ b/src/input.rs @@ -0,0 +1,51 @@ +use bevy::{ + input::gamepad::{GamepadAxisChangedEvent, GamepadButtonChangedEvent, GamepadEvent}, + prelude::*, +}; + +#[derive(Default, Debug, Resource)] +pub(crate) struct InputState { + pub yaw: f32, + pub throttle: f32, + pub brake: bool, + pub pitch: f32, +} + +fn update_input(mut events: EventReader, mut istate: ResMut) { + for pad_event in events.read() { + match pad_event { + GamepadEvent::Button(button_event) => { + let GamepadButtonChangedEvent { button, value, .. } = button_event; + match button { + GamepadButton::RightTrigger2 => istate.throttle = *value, + GamepadButton::LeftTrigger2 => istate.throttle = -value, + GamepadButton::East => { + istate.brake = value > &0.5; + } + _ => {} + } + } + GamepadEvent::Axis(axis_event) => { + let GamepadAxisChangedEvent { axis, value, .. } = axis_event; + match axis { + GamepadAxis::LeftStickX => { + istate.yaw = *value; + } + GamepadAxis::RightStickY => { + istate.pitch = *value; + } + _ => {} + } + } + GamepadEvent::Connection(_) => {} + } + } +} + +pub struct CyberInputPlugin; +impl Plugin for CyberInputPlugin { + fn build(&self, app: &mut App) { + app.init_resource::() + .add_systems(Update, (update_input)); + } +} diff --git a/src/main.rs b/src/main.rs index c3935aa..fe8e05b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,10 +15,12 @@ use bevy_inspector_egui::quick::WorldInspectorPlugin; mod bike; mod camera; +mod input; mod physics; use bike::CyberBikePlugin; use camera::CamPlug; +use input::CyberInputPlugin; use physics::CyberPhysicsPlugin; fn main() { @@ -27,6 +29,7 @@ fn main() { DefaultPlugins, CamPlug, CyberBikePlugin, + CyberInputPlugin, CyberPhysicsPlugin, WorldInspectorPlugin::new(), )) diff --git a/src/physics.rs b/src/physics.rs index 7faa30f..d3438e2 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -45,12 +45,6 @@ impl Default for CatControllerState { } impl CatControllerState { - pub fn decay(&mut self) { - if self.roll_integral.abs() > 0.001 { - self.roll_integral *= self.decay_factor; - } - } - pub fn update_roll(&mut self, error: f32, dt: f32) -> (f32, f32) { let lim = self.roll_limit; self.roll_integral = (self.roll_integral + (error * dt)).min(lim).max(-lim); @@ -65,13 +59,13 @@ impl CatControllerState { } mod systems { - use std::f32::consts::FRAC_PI_3; + use std::f32::consts::{FRAC_PI_3, FRAC_PI_4}; use avian3d::prelude::*; use bevy::prelude::*; use super::{CatControllerSettings, CatControllerState, CyberLean}; - use crate::bike::CyberBikeBody; + use crate::{bike::CyberBikeBody, input::InputState}; fn _yaw_to_angle(yaw: f32) -> f32 { let v = yaw.powi(5) * FRAC_PI_3; @@ -95,13 +89,15 @@ mod systems { pub(super) fn calculate_lean( bike_state: Query<(&LinearVelocity, &Transform), With>, + input: Res, mut lean: ResMut, ) { let (velocity, xform) = bike_state.single(); let vel = velocity.dot(*xform.forward()); let v_squared = vel.powi(2); + let steering_angle = yaw_to_angle(input.yaw); let wheel_base = 1.145f32; - let radius = wheel_base; + let radius = wheel_base / steering_angle.tan(); let gravity = -9.8f32; let v2_r = v_squared / radius; let tan_theta = (v2_r / gravity).clamp(-FRAC_PI_3, FRAC_PI_3); @@ -121,6 +117,7 @@ mod systems { mut gizmos: Gizmos, ) { let (xform, mut torque, mut control_vars) = bike_query.single_mut(); + let world_up = Vec3::Y; //xform.translation.normalize(); let rot = Quat::from_axis_angle(*xform.back(), lean.lean); let target_up = rotate_point(&world_up, &rot).normalize(); @@ -160,6 +157,15 @@ mod systems { } } } + + fn yaw_to_angle(yaw: f32) -> f32 { + let v = yaw.powi(5) * FRAC_PI_4; + if v.is_normal() { + v + } else { + 0.0 + } + } } use systems::{apply_lean, calculate_lean};