cyber_rider/src/bike/wheels.rs
2024-06-17 13:09:41 -07:00

118 lines
3.6 KiB
Rust

use bevy::prelude::*;
use bevy_rapier3d::{
dynamics::{FixedJointBuilder, Velocity},
prelude::{
ColliderMassProperties, ExternalForce, MultibodyJoint, PrismaticJointBuilder, RigidBody,
Sleeping, TransformInterpolation,
},
};
use super::{CyberSteering, CyberWheel, Meshterial, WheelConfig};
use crate::action::PreviousVelocity;
pub(crate) fn spawn_wheels(
commands: &mut Commands,
bike: Entity,
conf: &WheelConfig,
meshterials: &mut Meshterial,
) {
let wheel_y = conf.y;
let stiffness = conf.stiffness;
let not_sleeping = Sleeping::disabled();
let limits = conf.limits;
let (meshes, materials) = meshterials;
let rake_vec: Vec3 = Vec3::new(0.0, 1.0, 0.57).normalize(); // about 30 degrees of rake
let mut wheel_poses = Vec::with_capacity(2);
// front
{
let wheel_x = 0.0;
let wheel_z = -conf.front_forward;
let offset = Vec3::new(wheel_x, wheel_y, wheel_z);
wheel_poses.push((offset, Some(CyberSteering)));
}
// rear
{
let wheel_x = 0.0;
let wheel_z = conf.rear_back;
let offset = Vec3::new(wheel_x, wheel_y, wheel_z);
wheel_poses.push((offset, None));
}
for (offset, steering) in wheel_poses {
let mesh = gen_tires(conf);
let material = StandardMaterial {
base_color: Color::YELLOW,
alpha_mode: AlphaMode::Opaque,
perceptual_roughness: 0.1,
..Default::default()
};
let pbr_bundle = PbrBundle {
material: materials.add(material),
mesh: meshes.add(mesh),
..Default::default()
};
let mass_props = ColliderMassProperties::Density(conf.density);
let suspension_damping = conf.damping;
let suspension_axis = if steering.is_some() {
// rake_vec
Vec3::Y
} else {
Vec3::Y
};
let suspension_joint_builder = PrismaticJointBuilder::new(suspension_axis)
.local_anchor1(offset)
.limits(limits)
.motor_position(limits[0], stiffness, suspension_damping);
let suspension_joint = MultibodyJoint::new(bike, suspension_joint_builder);
let fork_rb_entity = commands
.spawn(RigidBody::Dynamic)
.insert(suspension_joint)
.insert(not_sleeping)
.id();
let axel_parent_entity = if let Some(steering) = steering {
let neck_builder = FixedJointBuilder::new().local_anchor1(Vec3::new(0.0, 0.0, 0.1)); // this adds another 0.1m of trail
let neck_joint = MultibodyJoint::new(fork_rb_entity, neck_builder);
let neck = commands
.spawn(RigidBody::Dynamic)
.insert(neck_joint)
.insert(steering)
.id();
neck
} else {
fork_rb_entity
};
let axel_builder = FixedJointBuilder::new();
let axel_joint = MultibodyJoint::new(axel_parent_entity, axel_builder);
commands.spawn(pbr_bundle).insert((
mass_props,
//wheel_damping,
axel_joint,
CyberWheel,
not_sleeping,
Velocity::default(),
PreviousVelocity::default(),
ExternalForce::default(),
SpatialBundle::default(),
TransformInterpolation::default(),
RigidBody::Dynamic,
));
}
}
// do mesh shit
fn gen_tires(conf: &WheelConfig) -> Mesh {
let wheel_rad = conf.radius;
let tire = Sphere::new(wheel_rad);
Mesh::from(tire)
}