cyber_rider/src/bike/wheels.rs
2023-02-17 17:30:53 -08:00

125 lines
3.8 KiB
Rust

use bevy::prelude::{shape::UVSphere as Tire, *};
use bevy_rapier3d::prelude::{
Ccd, CoefficientCombineRule, Collider, ColliderMassProperties, CollisionGroups, Damping,
ExternalForce, Friction, MultibodyJoint, PrismaticJointBuilder, Restitution,
RevoluteJointBuilder, RigidBody, Sleeping, TransformInterpolation,
};
use super::{CyberSteering, CyberWheel, Meshterial, WheelConfig, BIKE_WHEEL_COLLISION_GROUP};
pub fn spawn_tires(
commands: &mut Commands,
_xform: &Transform,
bike: Entity,
conf: &WheelConfig,
meshterials: &mut Meshterial,
) {
let (membership, filter) = BIKE_WHEEL_COLLISION_GROUP;
let wheels_collision_group = CollisionGroups::new(membership, filter);
let wheel_y = conf.y;
let wheel_rad = conf.radius;
let stiffness = conf.stiffness;
let not_sleeping = Sleeping::disabled();
let ccd = Ccd { enabled: true };
let limits = conf.limits;
let (meshes, materials) = meshterials;
let tire = Tire {
radius: wheel_rad,
..Default::default()
};
let material = StandardMaterial {
base_color: Color::Rgba {
red: 0.01,
green: 0.01,
blue: 0.01,
alpha: 1.0,
},
alpha_mode: AlphaMode::Opaque,
perceptual_roughness: 0.5,
..Default::default()
};
let pbr_bundle = PbrBundle {
material: materials.add(material),
mesh: meshes.add(Mesh::from(tire)),
..Default::default()
};
let friction = Friction {
coefficient: 0.8,
combine_rule: CoefficientCombineRule::Min,
};
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 wheel_damping = Damping {
linear_damping: 0.8,
..Default::default()
};
let wheel_collider = Collider::ball(wheel_rad);
let mass_props = ColliderMassProperties::Density(0.1);
let damping = conf.damping;
let prismatic_builder = PrismaticJointBuilder::new(Vec3::Y)
.local_anchor1(offset)
.limits(limits)
.motor_position(limits[0], stiffness, damping);
let prismatic_joint = MultibodyJoint::new(bike, prismatic_builder);
let fork_rb_entity = commands
.spawn(RigidBody::Dynamic)
.insert(prismatic_joint)
.id();
let axel_parent = if let Some(steering) = steering {
let neck_builder = RevoluteJointBuilder::new(Vec3::Y);
let neck_joint = MultibodyJoint::new(fork_rb_entity, neck_builder);
let hub = commands
.spawn(RigidBody::Dynamic)
.insert(neck_joint)
.insert(steering)
.id();
dbg!(hub);
hub
} else {
fork_rb_entity
};
let revolute_builder = RevoluteJointBuilder::new(Vec3::X);
let axel_joint = MultibodyJoint::new(axel_parent, revolute_builder);
commands.spawn(pbr_bundle.clone()).insert((
wheel_collider,
mass_props,
wheel_damping,
ccd,
not_sleeping,
axel_joint,
wheels_collision_group,
friction,
CyberWheel,
ExternalForce::default(),
Restitution::new(0.2),
SpatialBundle::default(),
TransformInterpolation::default(),
RigidBody::Dynamic,
));
}
}