Move collider setup to separate file and plugin.
Just make more room in the actions file for fancier dynamic stuff.
This commit is contained in:
parent
b101d8bc15
commit
37e8e40c3f
5 changed files with 152 additions and 135 deletions
158
src/action.rs
158
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<Assets<Mesh>>,
|
||||
planet_query: Query<(Entity, &Handle<Mesh>), With<CyberSphere>>,
|
||||
bike_query: Query<(Entity, &Transform), With<CyberBike>>,
|
||||
fn gravity(
|
||||
xform: Query<&Transform, With<CyberBike>>,
|
||||
settings: Res<MovementSettings>,
|
||||
mut config: ResMut<RapierConfiguration>,
|
||||
) {
|
||||
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::<Vec<Point<_>>>();
|
||||
|
||||
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<CyberBike>>, mut config: ResMut<RapierConfiguration>) {
|
||||
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<CyberBike>>,
|
||||
) {
|
||||
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<MovementSettings>,
|
||||
input: Res<InputState>,
|
||||
mut query: Query<
|
||||
|
@ -171,29 +80,14 @@ fn update_forces(
|
|||
forces.torque += torque;
|
||||
}
|
||||
|
||||
fn drag(
|
||||
mut query: Query<(&RigidBodyVelocityComponent, &mut RigidBodyForcesComponent), With<CyberBike>>,
|
||||
) {
|
||||
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::<MovementSettings>()
|
||||
.add_plugin(RapierPhysicsPlugin::<NoUserData>::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"));
|
||||
}
|
||||
}
|
||||
|
|
119
src/colliders.rs
Normal file
119
src/colliders.rs
Normal file
|
@ -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<Assets<Mesh>>,
|
||||
planet_query: Query<(Entity, &Handle<Mesh>), With<CyberSphere>>,
|
||||
bike_query: Query<(Entity, &Transform), With<CyberBike>>,
|
||||
) {
|
||||
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::<Vec<Point<_>>>();
|
||||
|
||||
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"),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ fn spawn_giant_sphere(
|
|||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
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,
|
||||
|
|
|
@ -5,6 +5,7 @@ use bevy::{
|
|||
|
||||
pub mod action;
|
||||
pub mod camera;
|
||||
pub mod colliders;
|
||||
pub mod geometry;
|
||||
pub mod glamor;
|
||||
pub mod input;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue