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::{
|
use bevy::prelude::*;
|
||||||
prelude::*,
|
use bevy_rapier3d::{na::Vector3, prelude::*};
|
||||||
render::mesh::{Indices, VertexAttributeValues},
|
|
||||||
};
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use bevy_rapier3d::{na::Vector3, physics::PhysicsSystems::StepWorld, prelude::*};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{geometry::CyberBike, input::InputState};
|
||||||
geometry::{CyberBike, CyberSphere, PLANET_RADIUS, SPAWN_ALTITUDE},
|
|
||||||
input::InputState,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Mouse sensitivity and movement speed
|
|
||||||
pub struct MovementSettings {
|
pub struct MovementSettings {
|
||||||
pub sensitivity: f32,
|
pub sensitivity: f32,
|
||||||
pub accel: f32,
|
pub accel: f32,
|
||||||
|
pub gravity: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MovementSettings {
|
impl Default for MovementSettings {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
sensitivity: 1.0,
|
sensitivity: 10.0,
|
||||||
accel: 40.,
|
accel: 20.0,
|
||||||
|
gravity: 9.8,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_colliders(
|
fn gravity(
|
||||||
mut commands: Commands,
|
xform: Query<&Transform, With<CyberBike>>,
|
||||||
meshes: Res<Assets<Mesh>>,
|
settings: Res<MovementSettings>,
|
||||||
planet_query: Query<(Entity, &Handle<Mesh>), With<CyberSphere>>,
|
mut config: ResMut<RapierConfiguration>,
|
||||||
bike_query: Query<(Entity, &Transform), With<CyberBike>>,
|
|
||||||
) {
|
) {
|
||||||
let (planet, mesh_handle) = planet_query.single();
|
let gravity = xform.single().translation.normalize() * -settings.gravity;
|
||||||
|
|
||||||
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;
|
|
||||||
config.gravity = gravity.into();
|
config.gravity = gravity.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +43,18 @@ fn falling_cat(
|
||||||
forces.torque = torque.into();
|
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>,
|
settings: Res<MovementSettings>,
|
||||||
input: Res<InputState>,
|
input: Res<InputState>,
|
||||||
mut query: Query<
|
mut query: Query<
|
||||||
|
@ -171,29 +80,14 @@ fn update_forces(
|
||||||
forces.torque += torque;
|
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;
|
pub struct CyberActionPlugin;
|
||||||
impl Plugin for CyberActionPlugin {
|
impl Plugin for CyberActionPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_resource::<MovementSettings>()
|
app.init_resource::<MovementSettings>()
|
||||||
.add_plugin(RapierPhysicsPlugin::<NoUserData>::default())
|
.add_plugin(RapierPhysicsPlugin::<NoUserData>::default())
|
||||||
.add_startup_system_to_stage(
|
|
||||||
StartupStage::PostStartup,
|
|
||||||
setup_colliders.label("colliders"),
|
|
||||||
)
|
|
||||||
.add_system(gravity)
|
.add_system(gravity)
|
||||||
.add_system(falling_cat.label("cat"))
|
.add_system(falling_cat.label("cat"))
|
||||||
.add_system(drag.label("drag").after("uforces"))
|
.add_system(drag.label("drag").after("iforces"))
|
||||||
.add_system(update_forces.label("uforces").after("cat"));
|
.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 meshes: ResMut<Assets<Mesh>>,
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
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 {
|
let isphere = shape::Icosphere {
|
||||||
radius: PLANET_RADIUS,
|
radius: PLANET_RADIUS,
|
||||||
subdivisions: 79,
|
subdivisions: 79,
|
||||||
|
|
|
@ -5,6 +5,7 @@ use bevy::{
|
||||||
|
|
||||||
pub mod action;
|
pub mod action;
|
||||||
pub mod camera;
|
pub mod camera;
|
||||||
|
pub mod colliders;
|
||||||
pub mod geometry;
|
pub mod geometry;
|
||||||
pub mod glamor;
|
pub mod glamor;
|
||||||
pub mod input;
|
pub mod input;
|
||||||
|
|
|
@ -2,6 +2,7 @@ use bevy::prelude::*;
|
||||||
use cyber_rider::{
|
use cyber_rider::{
|
||||||
action::{CyberActionPlugin, MovementSettings},
|
action::{CyberActionPlugin, MovementSettings},
|
||||||
camera::CyberCamPlugin,
|
camera::CyberCamPlugin,
|
||||||
|
colliders::CyberCollidersPlugin,
|
||||||
disable_mouse_trap,
|
disable_mouse_trap,
|
||||||
geometry::CyberGeomPlugin,
|
geometry::CyberGeomPlugin,
|
||||||
glamor::CyberGlamorPlugin,
|
glamor::CyberGlamorPlugin,
|
||||||
|
@ -11,8 +12,9 @@ use cyber_rider::{
|
||||||
};
|
};
|
||||||
|
|
||||||
const MOVEMENT_SETTINGS: MovementSettings = MovementSettings {
|
const MOVEMENT_SETTINGS: MovementSettings = MovementSettings {
|
||||||
sensitivity: 10.0, // default: 1.0
|
sensitivity: 10.0, // steering
|
||||||
accel: 30.0, // default: 40.0
|
accel: 30.0, // thrust
|
||||||
|
gravity: 8.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -33,6 +35,7 @@ fn main() {
|
||||||
.add_plugin(CyberCamPlugin)
|
.add_plugin(CyberCamPlugin)
|
||||||
.add_plugin(CyberSpaceLightsPlugin)
|
.add_plugin(CyberSpaceLightsPlugin)
|
||||||
.add_plugin(CyberUIPlugin)
|
.add_plugin(CyberUIPlugin)
|
||||||
|
.add_plugin(CyberCollidersPlugin)
|
||||||
.add_startup_system(disable_mouse_trap)
|
.add_startup_system(disable_mouse_trap)
|
||||||
.add_system(bevy::input::system::exit_on_esc_system);
|
.add_system(bevy::input::system::exit_on_esc_system);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue