cyber_rider/src/bike.rs
Joe Ardent 315f35e8e3 Adds "wheels" to cyberbike.
The `parallel` feature doesn't work with joints in Rapier.
2022-03-13 15:54:33 -07:00

129 lines
4.2 KiB
Rust

use bevy::prelude::*;
use bevy_rapier3d::prelude::*;
use crate::planet::PLANET_RADIUS;
pub(crate) const SPAWN_ALTITUDE: f32 = PLANET_RADIUS * 1.015 + 90.0;
#[derive(Component)]
pub struct CyberBikeBody;
#[derive(Component)]
pub struct CyberBikeCollider;
#[derive(Component, Debug)]
pub struct CyberBikeModel;
fn spawn_cyberbike(mut commands: Commands, asset_server: Res<AssetServer>) {
let xform = Transform::from_translation(Vec3::Y * SPAWN_ALTITUDE)
.with_rotation(Quat::from_axis_angle(Vec3::X, -80.0f32.to_radians()));
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.2,
ccd_max_dist: 2.7,
..Default::default()
}
.into();
let isometry = Isometry::from_parts(xform.translation.into(), xform.rotation.into());
bbody.position = isometry.into();
let shape = ColliderShape::capsule(
Vec3::new(0.0, 0.0, -2.7).into(),
Vec3::new(0.0, 0.0, 2.5).into(),
1.0,
);
let bcollide = ColliderBundle {
shape: shape.into(),
mass_properties: ColliderMassProps::Density(0.04).into(),
material: ColliderMaterial {
friction: 0.0,
restitution: 0.0,
..Default::default()
}
.into(),
..Default::default()
};
let bike = commands
.spawn_bundle(bbody)
.insert_bundle((xform, GlobalTransform::default()))
.insert(RigidBodyPositionSync::Interpolated { prev_pos: None })
.with_children(|child_builder| {
child_builder
.spawn_bundle(bcollide)
.insert(ColliderDebugRender {
color: Color::GREEN,
})
.insert(CyberBikeCollider)
.insert(ColliderPositionSync::Discrete);
})
.with_children(|rider| {
rider.spawn_scene(asset_server.load("cyber-bike_no_y_up.glb#Scene0"));
})
.insert(CyberBikeModel)
.insert(CyberBikeBody)
.id();
// seriously the cyberbike is so fucking huge what the heck
let wheel_positions = vec![-5.5, 4.7];
let wheel_rad = 0.7;
let wheel_y = -2.0;
for wheel_z in wheel_positions {
let offset = Vec3::new(0.0, wheel_y, wheel_z);
let trans = xform.translation + offset;
let wheel_pos_in_world = Isometry::from_parts(trans.into(), xform.rotation.into());
let _wheel_rb = commands
.spawn_bundle(RigidBodyBundle {
position: wheel_pos_in_world.into(),
activation: RigidBodyActivation::cannot_sleep().into(),
ccd: RigidBodyCcd {
ccd_enabled: true,
ccd_max_dist: wheel_rad,
ccd_thickness: 0.1,
..Default::default()
}
.into(),
..Default::default()
})
.insert_bundle(ColliderBundle {
material: ColliderMaterial::new(0.0, 0.0).into(),
shape: ColliderShape::ball(wheel_rad).into(),
mass_properties: ColliderMassProps::Density(0.01).into(),
..Default::default()
})
.insert(ColliderPositionSync::Discrete)
.insert(ColliderDebugRender::from(Color::YELLOW))
.id();
let (stiffness, damping) = (0.1, 0.4);
let prismatic = PrismaticJoint::new(Vector::y_axis())
.local_anchor1(offset.into())
.motor_position(-0.1, stiffness, damping);
commands.spawn_bundle(((JointBuilderComponent::new(prismatic, bike, _wheel_rb)),));
}
}
pub struct CyberBikePlugin;
impl Plugin for CyberBikePlugin {
#[cfg(feature = "debug_render")]
fn build(&self, app: &mut App) {
app.add_plugin(RapierRenderPlugin)
.add_startup_system_to_stage(StartupStage::PostStartup, spawn_cyberbike);
}
#[cfg(not(feature = "debug_render"))]
fn build(&self, app: &mut App) {
app.add_startup_system_to_stage(StartupStage::PostStartup, spawn_cyberbike);
}
}