diff --git a/src/action.rs b/src/action.rs index 41b936c..b0acb3a 100644 --- a/src/action.rs +++ b/src/action.rs @@ -1,132 +1,30 @@ -use bevy::{ - prelude::*, - render::mesh::{Indices, VertexAttributeValues}, -}; -#[allow(unused_imports)] -use bevy_rapier3d::{na::Vector3, physics::PhysicsSystems::StepWorld, prelude::*}; +use bevy::prelude::*; +use bevy_rapier3d::{na::Vector3, prelude::*}; -use crate::{ - geometry::{CyberBike, CyberSphere, PLANET_RADIUS, SPAWN_ALTITUDE}, - input::InputState, -}; +use crate::{geometry::CyberBike, input::InputState}; -/// Mouse sensitivity and movement speed pub struct MovementSettings { pub sensitivity: f32, pub accel: f32, + pub gravity: f32, } impl Default for MovementSettings { fn default() -> Self { Self { - sensitivity: 1.0, - accel: 40., + sensitivity: 10.0, + accel: 20.0, + gravity: 9.8, } } } -fn setup_colliders( - mut commands: Commands, - meshes: Res>, - planet_query: Query<(Entity, &Handle), With>, - bike_query: Query<(Entity, &Transform), With>, +fn gravity( + xform: Query<&Transform, With>, + settings: Res, + mut config: ResMut, ) { - let (planet, mesh_handle) = planet_query.single(); - - let mesh = meshes.get(mesh_handle).unwrap(); - - let mut shape = ColliderShape::ball(PLANET_RADIUS); - - let vertices = mesh.attribute(Mesh::ATTRIBUTE_POSITION).unwrap(); - if let VertexAttributeValues::Float32x3(verts) = vertices { - if let Some(Indices::U32(indices)) = mesh.indices() { - let mut idxs = Vec::new(); - for idx in indices.chunks_exact(3) { - idxs.push([idx[0], idx[1], idx[2]]); - } - let vertices = verts - .iter() - .map(|p| Point::from_slice(p)) - .collect::>>(); - - shape = ColliderShape::trimesh(vertices, idxs); - } - } - - let pbody = RigidBodyBundle { - body_type: RigidBodyType::Static.into(), - ccd: RigidBodyCcd { - ccd_enabled: true, - ccd_thickness: 2.0, - ccd_max_dist: SPAWN_ALTITUDE, - ..Default::default() - } - .into(), - ..Default::default() - }; - let pcollide = ColliderBundle { - shape: shape.into(), - material: ColliderMaterial { - friction: 0.05, - restitution: 0.00, - ..Default::default() - } - .into(), - ..Default::default() - }; - - commands - .entity(planet) - .insert_bundle(pbody) - .insert_bundle(pcollide); - - // bike is the easy part - let (bike, xform) = bike_query.single(); - setup_bike_collider(bike, xform, &mut commands); -} - -fn setup_bike_collider(bike: Entity, xform: &Transform, commands: &mut Commands) { - let mut bbody = RigidBodyBundle::default(); - - bbody.damping.angular_damping = 0.8; - bbody.damping.linear_damping = 0.1; - - bbody.ccd = RigidBodyCcd { - ccd_enabled: true, - ccd_thickness: 0.7, - ccd_max_dist: 1.5, - ..Default::default() - } - .into(); - - let isometry = Isometry::from_parts(xform.translation.into(), xform.rotation.into()); - bbody.position = isometry.into(); - // collider - let shape = ColliderShape::capsule( - Vec3::new(0.0, 0.0, -1.25).into(), - Vec3::new(0.0, 0.0, 1.25).into(), - 0.4, - ); - let bcollide = ColliderBundle { - shape: shape.into(), - mass_properties: ColliderMassProps::Density(0.6).into(), - material: ColliderMaterial { - friction: 0.0, - restitution: 0.0, - ..Default::default() - } - .into(), - ..Default::default() - }; - commands - .entity(bike) - .insert_bundle(bbody) - .insert_bundle(bcollide) - .insert(ColliderPositionSync::Discrete); -} - -fn gravity(xform: Query<&Transform, With>, mut config: ResMut) { - let gravity = xform.single().translation.normalize() * -7.80; + let gravity = xform.single().translation.normalize() * -settings.gravity; config.gravity = gravity.into(); } @@ -145,7 +43,18 @@ fn falling_cat( forces.torque = torque.into(); } -fn update_forces( +fn drag( + mut query: Query<(&RigidBodyVelocityComponent, &mut RigidBodyForcesComponent), With>, +) { + let (vels, mut forces) = query.single_mut(); + + if let Some(vel) = vels.linvel.try_normalize(0.001) { + let v2 = vels.linvel.magnitude_squared(); + forces.force -= vel * v2 * 0.002; + } +} + +fn input_forces( settings: Res, input: Res, mut query: Query< @@ -171,29 +80,14 @@ fn update_forces( forces.torque += torque; } -fn drag( - mut query: Query<(&RigidBodyVelocityComponent, &mut RigidBodyForcesComponent), With>, -) { - let (vels, mut forces) = query.single_mut(); - - if let Some(vel) = vels.linvel.try_normalize(0.001) { - let v2 = vels.linvel.magnitude_squared(); - forces.force -= vel * v2 * 0.002; - } -} - pub struct CyberActionPlugin; impl Plugin for CyberActionPlugin { fn build(&self, app: &mut App) { app.init_resource::() .add_plugin(RapierPhysicsPlugin::::default()) - .add_startup_system_to_stage( - StartupStage::PostStartup, - setup_colliders.label("colliders"), - ) .add_system(gravity) .add_system(falling_cat.label("cat")) - .add_system(drag.label("drag").after("uforces")) - .add_system(update_forces.label("uforces").after("cat")); + .add_system(drag.label("drag").after("iforces")) + .add_system(input_forces.label("iforces").after("cat")); } } diff --git a/src/colliders.rs b/src/colliders.rs new file mode 100644 index 0000000..086c1db --- /dev/null +++ b/src/colliders.rs @@ -0,0 +1,119 @@ +use bevy::{ + prelude::*, + render::mesh::{Indices, VertexAttributeValues}, +}; +use bevy_rapier3d::prelude::*; + +use crate::geometry::{CyberBike, CyberSphere, PLANET_RADIUS, SPAWN_ALTITUDE}; + +fn setup_colliders( + mut commands: Commands, + meshes: Res>, + planet_query: Query<(Entity, &Handle), With>, + bike_query: Query<(Entity, &Transform), With>, +) { + let (planet, mesh_handle) = planet_query.single(); + + let mesh = meshes.get(mesh_handle).unwrap(); + + let mut shape = ColliderShape::ball(PLANET_RADIUS); + + let vertices = mesh.attribute(Mesh::ATTRIBUTE_POSITION).unwrap(); + if let VertexAttributeValues::Float32x3(verts) = vertices { + if let Some(Indices::U32(indices)) = mesh.indices() { + let mut idxs = Vec::new(); + for idx in indices.chunks_exact(3) { + idxs.push([idx[0], idx[1], idx[2]]); + } + let vertices = verts + .iter() + .map(|p| Point::from_slice(p)) + .collect::>>(); + + shape = ColliderShape::trimesh(vertices, idxs); + } + } + + let pbody = RigidBodyBundle { + body_type: RigidBodyType::Static.into(), + ccd: RigidBodyCcd { + ccd_enabled: true, + ccd_thickness: 2.0, + ccd_max_dist: SPAWN_ALTITUDE, + ..Default::default() + } + .into(), + ..Default::default() + }; + let pcollide = ColliderBundle { + shape: shape.into(), + material: ColliderMaterial { + friction: 0.05, + restitution: 0.00, + ..Default::default() + } + .into(), + ..Default::default() + }; + + commands + .entity(planet) + .insert_bundle(pbody) + .insert_bundle(pcollide); + + // bike is the easy part + let (bike, xform) = bike_query.single(); + setup_bike_collider(bike, xform, &mut commands); +} + +fn setup_bike_collider(bike: Entity, xform: &Transform, commands: &mut Commands) { + let mut bbody = RigidBodyBundle::default(); + + bbody.damping.angular_damping = 0.8; + bbody.damping.linear_damping = 0.1; + bbody.activation = RigidBodyActivation::cannot_sleep().into(); + + bbody.ccd = RigidBodyCcd { + ccd_enabled: true, + ccd_thickness: 0.7, + ccd_max_dist: 1.5, + ..Default::default() + } + .into(); + + let isometry = Isometry::from_parts(xform.translation.into(), xform.rotation.into()); + bbody.position = isometry.into(); + // collider + let shape = ColliderShape::capsule( + Vec3::new(0.0, 0.0, -1.25).into(), + Vec3::new(0.0, 0.0, 1.25).into(), + 0.4, + ); + let bcollide = ColliderBundle { + shape: shape.into(), + mass_properties: ColliderMassProps::Density(0.6).into(), + material: ColliderMaterial { + friction: 0.0, + restitution: 0.0, + ..Default::default() + } + .into(), + ..Default::default() + }; + commands + .entity(bike) + .insert_bundle(bbody) + .insert_bundle(bcollide) + .insert(ColliderPositionSync::Discrete); +} + +pub struct CyberCollidersPlugin; +impl Plugin for CyberCollidersPlugin { + fn build(&self, app: &mut App) { + // + app.add_startup_system_to_stage( + StartupStage::PostStartup, + setup_colliders.label("colliders"), + ); + } +} diff --git a/src/geometry.rs b/src/geometry.rs index 87b0eb8..62a2142 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -22,7 +22,7 @@ fn spawn_giant_sphere( mut meshes: ResMut>, mut materials: ResMut>, ) { - let color = Color::rgb(0.2, 0.17, 0.2); + let color = Color::rgb(0.2, 0.1, 0.2); let isphere = shape::Icosphere { radius: PLANET_RADIUS, subdivisions: 79, diff --git a/src/lib.rs b/src/lib.rs index 13e9be9..a218813 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ use bevy::{ pub mod action; pub mod camera; +pub mod colliders; pub mod geometry; pub mod glamor; pub mod input; diff --git a/src/main.rs b/src/main.rs index 892da6d..2a96bbe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use bevy::prelude::*; use cyber_rider::{ action::{CyberActionPlugin, MovementSettings}, camera::CyberCamPlugin, + colliders::CyberCollidersPlugin, disable_mouse_trap, geometry::CyberGeomPlugin, glamor::CyberGlamorPlugin, @@ -11,8 +12,9 @@ use cyber_rider::{ }; const MOVEMENT_SETTINGS: MovementSettings = MovementSettings { - sensitivity: 10.0, // default: 1.0 - accel: 30.0, // default: 40.0 + sensitivity: 10.0, // steering + accel: 30.0, // thrust + gravity: 8.0, }; fn main() { @@ -33,6 +35,7 @@ fn main() { .add_plugin(CyberCamPlugin) .add_plugin(CyberSpaceLightsPlugin) .add_plugin(CyberUIPlugin) + .add_plugin(CyberCollidersPlugin) .add_startup_system(disable_mouse_trap) .add_system(bevy::input::system::exit_on_esc_system);