From 59f0ed89e9c848b0984dd7e32aafbe3788ae5810 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Sat, 15 Jun 2024 14:18:17 -0700 Subject: [PATCH] checkpoint, frictionless wheels --- src/action/components.rs | 17 +--- src/action/mod.rs | 9 +- src/action/systems.rs | 199 +++++++++++++++++++-------------------- src/bike/components.rs | 6 +- src/bike/mod.rs | 3 +- src/bike/wheels.rs | 36 +++---- src/lights.rs | 2 +- src/main.rs | 4 +- src/planet.rs | 20 ++-- src/ui.rs | 6 +- 10 files changed, 141 insertions(+), 161 deletions(-) diff --git a/src/action/components.rs b/src/action/components.rs index a844fa2..c6d5aa3 100644 --- a/src/action/components.rs +++ b/src/action/components.rs @@ -4,6 +4,7 @@ use bevy::{ prelude::{Component, ReflectResource, Resource, Vec3}, reflect::Reflect, }; +use bevy_rapier3d::dynamics::Velocity; #[derive(Debug, Resource)] pub(crate) struct ActionDebugInstant(pub Instant); @@ -26,20 +27,8 @@ impl ActionDebugInstant { } } -#[derive(Debug, Component)] -pub(super) struct Tunneling { - pub frames: usize, - pub dir: Vec3, -} - -impl Default for Tunneling { - fn default() -> Self { - Tunneling { - frames: 15, - dir: Vec3::Y, - } - } -} +#[derive(Debug, Component, Default)] +pub struct PreviousVelocity(pub Velocity); #[derive(Debug, Resource, Reflect)] #[reflect(Resource)] diff --git a/src/action/mod.rs b/src/action/mod.rs index 904e397..879123b 100644 --- a/src/action/mod.rs +++ b/src/action/mod.rs @@ -29,18 +29,17 @@ impl Plugin for CyberActionPlugin { .register_type::() .register_type::() .add_plugins(RapierPhysicsPlugin::::default()) - .add_systems(Startup, timestep_setup) - .add_plugins(FrameTimeDiagnosticsPlugin::default()) + .add_systems(Startup, physics_init) + .add_plugins(FrameTimeDiagnosticsPlugin) .add_systems( Update, ( - gravity, + reset_body_force, + reset_wheel_forces, cyber_lean, falling_cat, input_forces, drag, - //tunnel_out, - //surface_fix, ) .chain(), ); diff --git a/src/action/systems.rs b/src/action/systems.rs index 7c808ab..c2baef3 100644 --- a/src/action/systems.rs +++ b/src/action/systems.rs @@ -3,67 +3,60 @@ use std::f32::consts::{FRAC_PI_3, FRAC_PI_4}; use bevy::prelude::{ Commands, Entity, Local, Quat, Query, Res, ResMut, Time, Transform, Vec3, With, Without, }; -use bevy_rapier3d::prelude::{ - CollisionGroups, ExternalForce, Group, MultibodyJoint, QueryFilter, RapierConfiguration, - RapierContext, ReadMassProperties, TimestepMode, Velocity, +use bevy_rapier3d::{ + dynamics::MassProperties, + prelude::{ + CollisionGroups, ExternalForce, Group, MultibodyJoint, QueryFilter, RapierConfiguration, + RapierContext, ReadMassProperties, TimestepMode, Velocity, + }, }; #[cfg(feature = "inspector")] use super::ActionDebugInstant; -use super::{CatControllerSettings, CatControllerState, CyberLean, MovementSettings, Tunneling}; +use super::{ + CatControllerSettings, CatControllerState, CyberLean, MovementSettings, PreviousVelocity, +}; use crate::{ bike::{CyberBikeBody, CyberSteering, CyberWheel, WheelConfig, BIKE_WHEEL_COLLISION_GROUP}, input::InputState, }; -fn yaw_to_angle(yaw: f32) -> f32 { - let v = yaw.powi(5) * FRAC_PI_4; - if v.is_normal() { - v - } else { - 0.0 - } -} - -fn rotate_point(pt: &Vec3, rot: &Quat) -> Vec3 { - // thanks to https://danceswithcode.net/engineeringnotes/quaternions/quaternions.html - let [x, y, z] = pt.normalize().to_array(); - let qpt = Quat::from_xyzw(x, y, z, 0.0); - // p' = rot^-1 * qpt * rot - let rot_qpt = rot.inverse() * qpt * *rot; - - // why does this need to be inverted??? - -Vec3::from_array([rot_qpt.x, rot_qpt.y, rot_qpt.z]) -} - -pub(super) fn timestep_setup(mut config: ResMut) { - let ts = TimestepMode::Fixed { - dt: 1.0 / 60.0, - substeps: 2, - }; - config.timestep_mode = ts; -} - -/// The gravity vector points from the cyberbike to the center of the planet. -pub(super) fn gravity( - mut query: Query<(&Transform, &mut ExternalForce), With>, +pub(super) fn physics_init( + mut config: ResMut, settings: Res, - mut rapier_config: ResMut, +) { + config.timestep_mode = TimestepMode::Variable { + max_dt: 1.0 / 60.0, + time_scale: 1.0, + substeps: 3, + }; + + config.gravity = Vec3::NEG_Y * settings.gravity; +} + +pub(super) fn reset_body_force( + mut query: Query<&mut ExternalForce, With>, #[cfg(feature = "inspector")] mut debug_instant: ResMut, ) { - let (xform, mut forces) = query.single_mut(); + let mut body_force = query.single_mut(); #[cfg(feature = "inspector")] { - if debug_instant.elapsed().as_millis() > 6000 { - dbg!(&forces); + if debug_instant.elapsed().as_millis() > 1000 { + //dbg!(&body_force); debug_instant.reset(); } } - rapier_config.gravity = Vec3::Y * -settings.gravity; - forces.force = Vec3::ZERO; - forces.torque = Vec3::ZERO; + body_force.force = Vec3::ZERO; + body_force.torque = Vec3::ZERO; +} + +pub(super) fn reset_wheel_forces(mut query: Query<&mut ExternalForce, With>) { + for mut force in query.iter_mut() { + force.force = Vec3::ZERO; + force.torque = Vec3::ZERO; + } } /// The desired lean angle, given steering input and speed. @@ -117,8 +110,8 @@ pub(super) fn falling_cat( if *count < 30 { if *count == 0 { - dbg!(&xform.translation); - dbg!(&vel.linvel); + //dbg!(&xform.translation); + //dbg!(&vel.linvel); } *count += 1; } else { @@ -141,10 +134,7 @@ pub(super) fn input_forces( settings: Res, input: Res, mut braking_query: Query<&mut MultibodyJoint, (Without, With)>, - mut body_query: Query< - (&Transform, &mut ExternalForce), - (With, Without), - >, + mut body_query: Query<(&Transform, &mut ExternalForce), With>, mut steering_query: Query<&mut MultibodyJoint, With>, ) { let (xform, mut forces) = body_query.single_mut(); @@ -156,21 +146,21 @@ pub(super) fn input_forces( *forces += force; // brake + thrust - for mut motor in braking_query.iter_mut() { - let factor = if input.brake { - 500.00 - } else { - input.throttle * settings.accel - }; - let speed = if input.brake { 0.0 } else { -70.0 }; - motor.data = (*motor - .data - .as_revolute_mut() - .unwrap() - .set_motor_max_force(factor) - .set_motor_velocity(speed, factor)) - .into(); - } + // for mut motor in braking_query.iter_mut() { + // let factor = if input.brake { + // 500.00 + // } else { + // input.throttle * settings.accel + // }; + // let speed = if input.brake { 0.0 } else { -70.0 }; + // motor.data = (*motor + // .data + // .as_revolute_mut() + // .unwrap() + // .set_motor_max_force(factor) + // .set_motor_velocity(speed, factor)) + // .into(); + // } // steering let angle = yaw_to_angle(input.yaw); @@ -183,13 +173,32 @@ pub(super) fn input_forces( .into(); } +pub(super) fn wheel_forces( + mut wheels_query: Query<(&Transform, &Velocity, &mut PreviousVelocity), With>, + mut body_query: Query< + ( + &Transform, + &Velocity, + &mut PreviousVelocity, + &ReadMassProperties, + ), + With, + >, + config: Res, + context: Res, +) { + let (body_xform, body_vel, mut body_pvel, body_mass) = body_query.single_mut(); + + for (xform, vel, mut pvel) in wheels_query.iter_mut() { + // + } + + body_pvel.0 = *body_vel; +} + /// Don't let the wheels get stuck underneat the planet pub(super) fn surface_fix( - mut commands: Commands, - mut wheel_query: Query< - (Entity, &Transform, &mut CollisionGroups), - (With, Without), - >, + mut wheel_query: Query<(Entity, &Transform, &mut CollisionGroups), With>, span_query: Query<&Transform, With>, config: Res, context: Res, @@ -212,43 +221,10 @@ pub(super) fn surface_fix( ) { //cgroups.memberships = Group::NONE; //cgroups.filters = Group::NONE; - commands.entity(entity).insert(Tunneling { - frames: 2, - dir: hit.1.normal, - }); } } } -pub(super) fn tunnel_out( - mut commands: Commands, - mut wheel_query: Query< - ( - Entity, - &mut Tunneling, - &mut ExternalForce, - &mut CollisionGroups, - ), - With, - >, - mprops: Query<&ReadMassProperties, With>, - settings: Res, -) { - let mprops = mprops.single(); - for (entity, mut tunneling, mut force, mut cgroups) in wheel_query.iter_mut() { - if tunneling.frames == 0 { - commands.entity(entity).remove::(); - force.force = Vec3::ZERO; - (cgroups.memberships, cgroups.filters) = BIKE_WHEEL_COLLISION_GROUP; - continue; - } - tunneling.frames -= 1; - force.force = tunneling.dir * settings.gravity * 1.1 * mprops.get().mass; - #[cfg(feature = "inspector")] - dbg!(&tunneling); - } -} - /// General velocity-based drag-force calculation; does not take orientation /// into account. pub(super) fn drag(mut query: Query<(&Velocity, &mut ExternalForce), With>) { @@ -259,3 +235,24 @@ pub(super) fn drag(mut query: Query<(&Velocity, &mut ExternalForce), With f32 { + let v = yaw.powi(5) * FRAC_PI_4; + if v.is_normal() { + v + } else { + 0.0 + } +} + +fn rotate_point(pt: &Vec3, rot: &Quat) -> Vec3 { + // thanks to https://danceswithcode.net/engineeringnotes/quaternions/quaternions.html + let [x, y, z] = pt.normalize().to_array(); + let qpt = Quat::from_xyzw(x, y, z, 0.0); + // p' = rot^-1 * qpt * rot + let rot_qpt = rot.inverse() * qpt * *rot; + + // why does this need to be inverted??? + -Vec3::from_array([rot_qpt.x, rot_qpt.y, rot_qpt.z]) +} diff --git a/src/bike/components.rs b/src/bike/components.rs index 8057f5e..7d7688d 100644 --- a/src/bike/components.rs +++ b/src/bike/components.rs @@ -22,7 +22,6 @@ pub struct WheelConfig { pub stiffness: f32, pub damping: f32, pub radius: f32, - pub thickness: f32, pub friction: f32, pub restitution: f32, pub density: f32, @@ -37,9 +36,8 @@ impl Default for WheelConfig { limits: [-0.5, 0.1], stiffness: 30.0, damping: 8.0, - radius: 0.35, - thickness: 0.11, - friction: 1.2, + radius: 0.3, + friction: 0.0, restitution: 0.95, density: 0.05, } diff --git a/src/bike/mod.rs b/src/bike/mod.rs index 0c0af2e..6d413cb 100644 --- a/src/bike/mod.rs +++ b/src/bike/mod.rs @@ -1,5 +1,6 @@ mod body; mod components; +//mod controller; mod wheels; use bevy::prelude::{App, Assets, Mesh, Plugin, PostStartup, ResMut, StandardMaterial}; @@ -9,7 +10,7 @@ pub(crate) use self::components::*; use self::{body::spawn_cyberbike, wheels::spawn_wheels}; pub const BIKE_BODY_COLLISION_GROUP: (Group, Group) = (Group::GROUP_1, Group::GROUP_1); -pub const BIKE_WHEEL_COLLISION_GROUP: (Group, Group) = (Group::GROUP_10, Group::GROUP_10); +pub const BIKE_WHEEL_COLLISION_GROUP: (Group, Group) = (Group::GROUP_2, Group::GROUP_2); type Meshterial<'a> = ( ResMut<'a, Assets>, diff --git a/src/bike/wheels.rs b/src/bike/wheels.rs index c0118e1..d39758e 100644 --- a/src/bike/wheels.rs +++ b/src/bike/wheels.rs @@ -1,13 +1,17 @@ -use bevy::prelude::{shape::Torus as Tire, *}; -use bevy_rapier3d::prelude::{ - Ccd, CoefficientCombineRule, Collider, ColliderMassProperties, CollisionGroups, Damping, - ExternalForce, Friction, MultibodyJoint, PrismaticJointBuilder, Restitution, - RevoluteJointBuilder, RigidBody, Sleeping, TransformInterpolation, +use bevy::prelude::*; +use bevy_rapier3d::{ + dynamics::{FixedJointBuilder, Velocity}, + prelude::{ + Ccd, CoefficientCombineRule, Collider, ColliderMassProperties, CollisionGroups, Damping, + ExternalForce, Friction, MultibodyJoint, PrismaticJointBuilder, Restitution, + RevoluteJointBuilder, RigidBody, Sleeping, TransformInterpolation, + }, }; use super::{CyberSteering, CyberWheel, Meshterial, WheelConfig, BIKE_WHEEL_COLLISION_GROUP}; +use crate::action::PreviousVelocity; -pub fn spawn_wheels( +pub(crate) fn spawn_wheels( commands: &mut Commands, bike: Entity, conf: &WheelConfig, @@ -25,7 +29,7 @@ pub fn spawn_wheels( let friction = Friction { coefficient: conf.friction, - combine_rule: CoefficientCombineRule::Average, + combine_rule: CoefficientCombineRule::Min, }; let mut wheel_poses = Vec::with_capacity(2); @@ -50,14 +54,9 @@ pub fn spawn_wheels( let (mesh, collider) = gen_tires(conf); let material = StandardMaterial { - base_color: Color::Rgba { - red: 0.99, - green: 0.99, - blue: 0.05, - alpha: 1.0, - }, + base_color: Color::YELLOW, alpha_mode: AlphaMode::Opaque, - perceptual_roughness: 0.5, + perceptual_roughness: 0.1, ..Default::default() }; @@ -102,10 +101,10 @@ pub fn spawn_wheels( fork_rb_entity }; - let axel_builder = RevoluteJointBuilder::new(Vec3::X); + let axel_builder = FixedJointBuilder::new(); //RevoluteJointBuilder::new(Vec3::X); let axel_joint = MultibodyJoint::new(axel_parent_entity, axel_builder); let wheel_damping = Damping { - linear_damping: 0.8, + //linear_damping: 0.8, ..Default::default() }; @@ -119,8 +118,9 @@ pub fn spawn_wheels( wheels_collision_group, friction, CyberWheel, + Velocity::default(), + PreviousVelocity::default(), ExternalForce::default(), - Restitution::new(conf.restitution), SpatialBundle::default(), TransformInterpolation::default(), RigidBody::Dynamic, @@ -132,7 +132,7 @@ pub fn spawn_wheels( fn gen_tires(conf: &WheelConfig) -> (Mesh, Collider) { let wheel_rad = conf.radius; let tire = Sphere::new(wheel_rad); - let mut mesh = Mesh::from(tire); + let mesh = Mesh::from(tire); let wheel_collider = Collider::ball(wheel_rad); (mesh, wheel_collider) diff --git a/src/lights.rs b/src/lights.rs index 515efa1..7898ccc 100644 --- a/src/lights.rs +++ b/src/lights.rs @@ -10,7 +10,7 @@ fn spawn_static_lights( mut materials: ResMut>, ) { let pink_light = PointLight { - //intensity: 1_00.0, + intensity: 10_00.0, range: LIGHT_RANGE, color: Color::WHITE, radius: 10.0, diff --git a/src/main.rs b/src/main.rs index b8fbe25..4154b40 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use bevy::prelude::*; -//#[cfg(feature = "inspector")] +#[cfg(feature = "inspector")] use cyber_rider::glamor::CyberGlamorPlugin; use cyber_rider::{ action::CyberActionPlugin, bike::CyberBikePlugin, camera::CyberCamPlugin, disable_mouse_trap, @@ -33,7 +33,7 @@ fn main() { .add_systems(Startup, disable_mouse_trap) .add_systems(Update, bevy::window::close_on_esc); - //#[cfg(feature = "inspector")] + #[cfg(feature = "inspector")] app.add_plugins(CyberGlamorPlugin); app.run(); diff --git a/src/planet.rs b/src/planet.rs index db3c947..7d5c9ea 100644 --- a/src/planet.rs +++ b/src/planet.rs @@ -1,12 +1,6 @@ -use bevy::{ - prelude::{shape::Icosphere, *}, - render::{color::Color, mesh::Indices, render_asset::RenderAssetUsages}, -}; +use bevy::{prelude::*, render::color::Color}; use bevy_rapier3d::prelude::*; -use hexasphere::shapes::IcoSphere; -use noise::{HybridMulti, NoiseFn, SuperSimplex}; -use rand::{Rng, SeedableRng}; -use wgpu::PrimitiveTopology; +// use noise::{HybridMulti, NoiseFn, SuperSimplex}; pub const PLANET_RADIUS: f32 = 2_000.0; pub const PLANET_HUE: f32 = 31.0; @@ -22,7 +16,7 @@ fn spawn_planet( ) { //let color = Color::rgb(0.74, 0.5334, 0.176); - let (mesh, shape) = gen_planet(999.9); + let (mesh, shape) = gen_planet(2999.9); let pbody = ( RigidBody::Fixed, @@ -37,7 +31,9 @@ fn spawn_planet( ..Default::default() }, Restitution::new(0.8), - Transform::from_xyz(0.0, 0.1, 0.0), + Transform::from_xyz(0.0, 1.0, 0.0), + // same as the bike body + CollisionGroups::new(Group::GROUP_1, Group::GROUP_1), ); commands @@ -67,9 +63,9 @@ impl Plugin for CyberPlanetPlugin { //--------------------------------------------------------------------- fn gen_planet(span: f32) -> (Mesh, Collider) { - let mesh = Cuboid::new(span, 0.1, span); + let mut mesh = Cuboid::new(span, 1.0, span); - let collider = Collider::cuboid(span / 2.0, 0.05, span / 2.0); + let collider = Collider::cuboid(span / 2.0, 0.5, span / 2.0); (mesh.mesh(), collider) } diff --git a/src/ui.rs b/src/ui.rs index 27a9336..2386817 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -5,8 +5,8 @@ use bevy::{ TextBundle, TextSection, TextStyle, Transform, With, }, }; -#[cfg(feature = "inspector")] -use bevy_inspector_egui::quick::WorldInspectorPlugin; +//#[cfg(feature = "inspector")] +//use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_rapier3d::prelude::Velocity; use crate::bike::CyberBikeBody; @@ -54,7 +54,7 @@ pub struct CyberUIPlugin; impl Plugin for CyberUIPlugin { fn build(&self, app: &mut App) { #[cfg(feature = "inspector")] - //app.add_plugins(WorldInspectorPlugin); + //app.add_plugins(WorldInspectorPlugin::new()); // app.add_systems(Startup, setup_ui)