diff --git a/src/action/systems.rs b/src/action/systems.rs index 8a4d766..dcb941b 100644 --- a/src/action/systems.rs +++ b/src/action/systems.rs @@ -2,17 +2,13 @@ use std::f32::consts::{FRAC_PI_3, FRAC_PI_4}; use bevy::{ prelude::{ - info, Commands, Entity, Gizmos, Local, Quat, Query, Res, ResMut, Time, Transform, Vec3, - With, Without, + info, Gizmos, Local, Quat, Query, Res, ResMut, Time, Transform, Vec3, With, Without, }, render::color::Color, }; -use bevy_rapier3d::{ - dynamics::MassProperties, - prelude::{ - CollisionGroups, ExternalForce, Group, MultibodyJoint, QueryFilter, RapierConfiguration, - RapierContext, ReadMassProperties, TimestepMode, Velocity, - }, +use bevy_rapier3d::prelude::{ + ExternalForce, QueryFilter, RapierConfiguration, RapierContext, ReadMassProperties, + TimestepMode, Velocity, }; #[cfg(feature = "inspector")] @@ -21,7 +17,7 @@ use super::{ CatControllerSettings, CatControllerState, CyberLean, MovementSettings, PreviousVelocity, }; use crate::{ - bike::{CyberBikeBody, CyberSteering, CyberWheel, WheelConfig, BIKE_WHEEL_COLLISION_GROUP}, + bike::{CyberBikeBody, CyberSteering, CyberWheel, WheelConfig}, input::InputState, }; @@ -138,93 +134,42 @@ pub(super) fn wheel_forces( ( &Transform, &Velocity, - &mut PreviousVelocity, &mut ExternalForce, Option<&CyberSteering>, ), - (With, Without), - >, - mut body_query: Query< - ( - &Transform, - &Velocity, - &mut PreviousVelocity, - &ReadMassProperties, - ), - (With, Without), + With, >, wheel_config: Res, - rapier_config: Res, context: Res, settings: Res, input: Res, mut gizmos: Gizmos, ) { - let (body_xform, body_vel, mut body_pvel, body_mass) = body_query.single_mut(); - - let gvec = rapier_config.gravity; - - // body kinematics - let body_lin_accel = body_vel.linvel - body_pvel.0.linvel; - let body_ang_accel = body_vel.angvel - body_pvel.0.angvel; - let mut body_forward = body_vel - .linvel - .try_normalize() - .unwrap_or_else(|| body_xform.forward().normalize()); - // we're just projecting onto the ground, so nuke the Y. - body_forward.y = 0.0; - let body_half_mass = body_mass.mass * 0.5; - let half_weight = settings.gravity * body_half_mass; - // wheel stuff let radius = wheel_config.radius; - let squish_radius = 1.5 * radius; // inputs let steering = input.yaw; let throttle = input.throttle * settings.accel; - for (xform, vel, mut pvel, mut external_force, steering) in wheels_query.iter_mut() { + for (xform, velocity, mut external_force, steering) in wheels_query.iter_mut() { if let Some((_, projected)) = context.project_point(xform.translation, false, QueryFilter::only_fixed()) { - //info!("projected point: {:?}", projected); - //dbg!("{:?}", projected); let normal = (projected.point - xform.translation); let len = normal.length(); - let normal = normal.normalize(); - if len < squish_radius { - let squish = if len > radius { - 1.0 - ((len - radius) / (squish_radius - radius)).powi(2) - } else { - 1.0 - }; - info!("squish: {squish}"); - let grav_norm = gvec.normalize().dot(normal); - // we're in contact, first gravity - let normal = if projected.is_inside { Vec3::Y } else { normal }; - let mut force = -1.1 * grav_norm * half_weight * normal; + if len < radius { + let mut force = Vec3::ZERO; + // do thrust's share + let thrust = normal.cross(xform.left().into()) * throttle; + force += thrust; - // do linear acceleration's share - // f = ma - let lin_accel_norm = normal.dot(body_lin_accel.normalize()); - force += body_mass.mass * lin_accel_norm * body_lin_accel; + // do steering's share - // do angular accelerations's share? - - // do friction's share (depends on previous three) - - // do thrust's share (depends on friction): - // - // let ef = ExternalForce::at_point(force, point, - // center_of_mass); - - // do steering's share (also depends on friction) - - // apply the squish factor - force *= squish; + // do the friction's share // show the force + #[cfg(feature = "inspector")] gizmos.arrow(xform.translation, force, Color::RED); // ok apply the force @@ -233,8 +178,6 @@ pub(super) fn wheel_forces( } } } - - body_pvel.0 = *body_vel; } /// General velocity-based drag-force calculation; does not take orientation diff --git a/src/bike/wheels.rs b/src/bike/wheels.rs index d5fb23f..00524a1 100644 --- a/src/bike/wheels.rs +++ b/src/bike/wheels.rs @@ -1,13 +1,14 @@ use bevy::prelude::*; use bevy_rapier3d::{ - dynamics::{FixedJointBuilder, Velocity}, + dynamics::{Ccd, FixedJointBuilder, Velocity}, + geometry::{Collider, CollisionGroups, Friction}, prelude::{ ColliderMassProperties, ExternalForce, MultibodyJoint, PrismaticJointBuilder, RigidBody, Sleeping, TransformInterpolation, }, }; -use super::{CyberSteering, CyberWheel, Meshterial, WheelConfig}; +use super::{CyberSteering, CyberWheel, Meshterial, WheelConfig, BIKE_WHEEL_COLLISION_GROUP}; use crate::action::PreviousVelocity; pub(crate) fn spawn_wheels( @@ -21,10 +22,14 @@ pub(crate) fn spawn_wheels( let not_sleeping = Sleeping::disabled(); let limits = conf.limits; let (meshes, materials) = meshterials; - let rake_vec: Vec3 = Vec3::new(0.0, 1.0, 0.57).normalize(); // about 30 degrees of rake + //let rake_vec: Vec3 = Vec3::new(0.0, 1.0, 0.57).normalize(); // about 30 + // degrees of rake let mut wheel_poses = Vec::with_capacity(2); + let (membership, filter) = BIKE_WHEEL_COLLISION_GROUP; + let wheels_collision_group = CollisionGroups::new(membership, filter); + // front { let wheel_x = 0.0; @@ -106,6 +111,13 @@ pub(crate) fn spawn_wheels( SpatialBundle::default(), TransformInterpolation::default(), RigidBody::Dynamic, + Ccd { enabled: true }, + Friction { + coefficient: 0.0, + combine_rule: bevy_rapier3d::dynamics::CoefficientCombineRule::Min, + }, + wheels_collision_group, + Collider::ball(conf.radius), )); } } diff --git a/src/planet.rs b/src/planet.rs index 7d5c9ea..4db530f 100644 --- a/src/planet.rs +++ b/src/planet.rs @@ -18,11 +18,7 @@ fn spawn_planet( let (mesh, shape) = gen_planet(2999.9); - let pbody = ( - RigidBody::Fixed, - Ccd { enabled: true }, - Transform::from_xyz(0.0, 0.1, 0.0), - ); + let pbody = (RigidBody::Fixed, Transform::from_xyz(0.0, 0.1, 0.0)); let pcollide = ( shape, @@ -32,8 +28,8 @@ fn spawn_planet( }, Restitution::new(0.8), Transform::from_xyz(0.0, 1.0, 0.0), - // same as the bike body - CollisionGroups::new(Group::GROUP_1, Group::GROUP_1), + CollisionGroups::default(), // all colliders + Ccd { enabled: true }, ); commands