checkpoint; wheel_forces skeleton fn
This commit is contained in:
parent
59f0ed89e9
commit
ff9b1671b1
2 changed files with 55 additions and 85 deletions
|
@ -129,52 +129,16 @@ pub(super) fn falling_cat(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply forces to the cyberbike as a result of input.
|
|
||||||
pub(super) fn input_forces(
|
|
||||||
settings: Res<MovementSettings>,
|
|
||||||
input: Res<InputState>,
|
|
||||||
mut braking_query: Query<&mut MultibodyJoint, (Without<CyberSteering>, With<CyberWheel>)>,
|
|
||||||
mut body_query: Query<(&Transform, &mut ExternalForce), With<CyberBikeBody>>,
|
|
||||||
mut steering_query: Query<&mut MultibodyJoint, With<CyberSteering>>,
|
|
||||||
) {
|
|
||||||
let (xform, mut forces) = body_query.single_mut();
|
|
||||||
|
|
||||||
// thrust
|
|
||||||
let thrust = xform.forward() * input.throttle * settings.accel;
|
|
||||||
let point = xform.translation + *xform.back();
|
|
||||||
let force = ExternalForce::at_point(thrust, point, xform.translation);
|
|
||||||
*forces += force;
|
|
||||||
|
|
||||||
// brake + thrust
|
|
||||||
// for mut motor in braking_query.iter_mut() {
|
|
||||||
// let factor = if input.brake {
|
|
||||||
// 500.00
|
|
||||||
// } else {
|
|
||||||
// input.throttle * settings.accel
|
|
||||||
// };
|
|
||||||
// let speed = if input.brake { 0.0 } else { -70.0 };
|
|
||||||
// motor.data = (*motor
|
|
||||||
// .data
|
|
||||||
// .as_revolute_mut()
|
|
||||||
// .unwrap()
|
|
||||||
// .set_motor_max_force(factor)
|
|
||||||
// .set_motor_velocity(speed, factor))
|
|
||||||
// .into();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// steering
|
|
||||||
let angle = yaw_to_angle(input.yaw);
|
|
||||||
let mut steering = steering_query.single_mut();
|
|
||||||
steering.data = (*steering
|
|
||||||
.data
|
|
||||||
.as_revolute_mut()
|
|
||||||
.unwrap()
|
|
||||||
.set_motor_position(-angle, 100.0, 0.5))
|
|
||||||
.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn wheel_forces(
|
pub(super) fn wheel_forces(
|
||||||
mut wheels_query: Query<(&Transform, &Velocity, &mut PreviousVelocity), With<CyberWheel>>,
|
mut wheels_query: Query<
|
||||||
|
(
|
||||||
|
&Transform,
|
||||||
|
&Velocity,
|
||||||
|
&mut PreviousVelocity,
|
||||||
|
Option<&CyberSteering>,
|
||||||
|
),
|
||||||
|
With<CyberWheel>,
|
||||||
|
>,
|
||||||
mut body_query: Query<
|
mut body_query: Query<
|
||||||
(
|
(
|
||||||
&Transform,
|
&Transform,
|
||||||
|
@ -184,47 +148,58 @@ pub(super) fn wheel_forces(
|
||||||
),
|
),
|
||||||
With<CyberBikeBody>,
|
With<CyberBikeBody>,
|
||||||
>,
|
>,
|
||||||
config: Res<WheelConfig>,
|
wheel_config: Res<WheelConfig>,
|
||||||
|
rapier_config: Res<RapierConfiguration>,
|
||||||
context: Res<RapierContext>,
|
context: Res<RapierContext>,
|
||||||
|
settings: Res<MovementSettings>,
|
||||||
|
input: Res<InputState>,
|
||||||
) {
|
) {
|
||||||
let (body_xform, body_vel, mut body_pvel, body_mass) = body_query.single_mut();
|
let (body_xform, body_vel, mut body_pvel, body_mass) = body_query.single_mut();
|
||||||
|
|
||||||
for (xform, vel, mut pvel) in wheels_query.iter_mut() {
|
let gvec = rapier_config.gravity;
|
||||||
//
|
|
||||||
|
// body kinematics
|
||||||
|
let body_lin_accel = body_vel.linvel - body_pvel.0.linvel;
|
||||||
|
let body_ang_accel = body_vel.angvel - body_pvel.0.angvel;
|
||||||
|
let mut body_forward = body_vel
|
||||||
|
.linvel
|
||||||
|
.try_normalize()
|
||||||
|
.unwrap_or_else(|| body_xform.forward().normalize());
|
||||||
|
// we're just projecting onto the ground, so nuke the Y.
|
||||||
|
body_forward.y = 0.0;
|
||||||
|
let body_half_mass = body_mass.mass * 0.5;
|
||||||
|
let g = gvec * settings.gravity * body_half_mass;
|
||||||
|
|
||||||
|
// inputs
|
||||||
|
let steering_angle = yaw_to_angle(input.yaw);
|
||||||
|
let throttle = input.throttle * settings.accel;
|
||||||
|
|
||||||
|
for (xform, vel, mut pvel, steering) in wheels_query.iter_mut() {
|
||||||
|
if let Some((_, projected)) =
|
||||||
|
context.project_point(xform.translation, true, QueryFilter::only_fixed())
|
||||||
|
{
|
||||||
|
let normal = -(projected.point - xform.translation);
|
||||||
|
let len = normal.length();
|
||||||
|
let normal = normal.normalize();
|
||||||
|
if len < wheel_config.radius {
|
||||||
|
// we're in contact
|
||||||
|
|
||||||
|
// do gravity's share
|
||||||
|
|
||||||
|
// do linear acceleration's share
|
||||||
|
|
||||||
|
// do friction's share
|
||||||
|
|
||||||
|
// do thrust's share
|
||||||
|
|
||||||
|
// do steering's share
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body_pvel.0 = *body_vel;
|
body_pvel.0 = *body_vel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Don't let the wheels get stuck underneat the planet
|
|
||||||
pub(super) fn surface_fix(
|
|
||||||
mut wheel_query: Query<(Entity, &Transform, &mut CollisionGroups), With<CyberWheel>>,
|
|
||||||
span_query: Query<&Transform, With<CyberWheel>>,
|
|
||||||
config: Res<WheelConfig>,
|
|
||||||
context: Res<RapierContext>,
|
|
||||||
) {
|
|
||||||
let mut wheels = Vec::new();
|
|
||||||
for xform in span_query.iter() {
|
|
||||||
wheels.push(xform);
|
|
||||||
}
|
|
||||||
let span = (wheels[1].translation - wheels[0].translation).normalize();
|
|
||||||
|
|
||||||
for (entity, xform, mut cgroups) in wheel_query.iter_mut() {
|
|
||||||
//let ray_dir = xform.translation.normalize();
|
|
||||||
let ray_dir = Vec3::NEG_Y; //xform.right().cross(span).normalize();
|
|
||||||
if let Some(hit) = context.cast_ray_and_get_normal(
|
|
||||||
xform.translation,
|
|
||||||
ray_dir,
|
|
||||||
config.radius,
|
|
||||||
false,
|
|
||||||
QueryFilter::only_fixed(),
|
|
||||||
) {
|
|
||||||
//cgroups.memberships = Group::NONE;
|
|
||||||
//cgroups.filters = Group::NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// General velocity-based drag-force calculation; does not take orientation
|
/// General velocity-based drag-force calculation; does not take orientation
|
||||||
/// into account.
|
/// into account.
|
||||||
pub(super) fn drag(mut query: Query<(&Velocity, &mut ExternalForce), With<CyberBikeBody>>) {
|
pub(super) fn drag(mut query: Query<(&Velocity, &mut ExternalForce), With<CyberBikeBody>>) {
|
||||||
|
|
|
@ -87,8 +87,7 @@ pub(crate) fn spawn_wheels(
|
||||||
.id();
|
.id();
|
||||||
|
|
||||||
let axel_parent_entity = if let Some(steering) = steering {
|
let axel_parent_entity = if let Some(steering) = steering {
|
||||||
let neck_builder =
|
let neck_builder = FixedJointBuilder::new().local_anchor1(Vec3::new(0.0, 0.0, 0.1)); // this adds another 0.1m of trail
|
||||||
RevoluteJointBuilder::new(rake_vec).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_joint = MultibodyJoint::new(fork_rb_entity, neck_builder);
|
||||||
let neck = commands
|
let neck = commands
|
||||||
.spawn(RigidBody::Dynamic)
|
.spawn(RigidBody::Dynamic)
|
||||||
|
@ -101,17 +100,13 @@ pub(crate) fn spawn_wheels(
|
||||||
fork_rb_entity
|
fork_rb_entity
|
||||||
};
|
};
|
||||||
|
|
||||||
let axel_builder = FixedJointBuilder::new(); //RevoluteJointBuilder::new(Vec3::X);
|
let axel_builder = FixedJointBuilder::new();
|
||||||
let axel_joint = MultibodyJoint::new(axel_parent_entity, axel_builder);
|
let axel_joint = MultibodyJoint::new(axel_parent_entity, axel_builder);
|
||||||
let wheel_damping = Damping {
|
|
||||||
//linear_damping: 0.8,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
commands.spawn(pbr_bundle).insert((
|
commands.spawn(pbr_bundle).insert((
|
||||||
collider,
|
collider,
|
||||||
mass_props,
|
mass_props,
|
||||||
wheel_damping,
|
//wheel_damping,
|
||||||
ccd,
|
ccd,
|
||||||
not_sleeping,
|
not_sleeping,
|
||||||
axel_joint,
|
axel_joint,
|
||||||
|
|
Loading…
Reference in a new issue