actually kinda works, but needs simulated friction.

This commit is contained in:
Joe Ardent 2024-06-19 16:37:40 -07:00
parent 0fae893508
commit c3e955c1cd
3 changed files with 58 additions and 43 deletions

View File

@ -34,8 +34,7 @@ impl Plugin for CyberActionPlugin {
.add_systems(
Update,
(
reset_body_force,
reset_wheel_forces,
reset_external_forces,
cyber_lean,
falling_cat,
wheel_forces,

View File

@ -6,9 +6,12 @@ use bevy::{
},
render::color::Color,
};
use bevy_rapier3d::prelude::{
ExternalForce, QueryFilter, RapierConfiguration, RapierContext, ReadMassProperties,
TimestepMode, Velocity,
use bevy_rapier3d::{
geometry::Friction,
prelude::{
ExternalForce, QueryFilter, RapierConfiguration, RapierContext, ReadMassProperties,
TimestepMode, Velocity,
},
};
#[cfg(feature = "inspector")]
@ -34,29 +37,23 @@ pub(super) fn physics_init(
config.gravity = Vec3::NEG_Y * settings.gravity;
}
pub(super) fn reset_body_force(
mut query: Query<&mut ExternalForce, With<CyberBikeBody>>,
pub(super) fn reset_external_forces(
mut query: Query<&mut ExternalForce>,
#[cfg(feature = "inspector")] mut debug_instant: ResMut<ActionDebugInstant>,
) {
let mut body_force = query.single_mut();
#[cfg(feature = "inspector")]
{
if debug_instant.elapsed().as_millis() > 1000 {
//dbg!(&body_force);
debug_instant.reset();
}
}
body_force.force = Vec3::ZERO;
body_force.torque = Vec3::ZERO;
}
pub(super) fn reset_wheel_forces(mut query: Query<&mut ExternalForce, With<CyberWheel>>) {
for mut force in query.iter_mut() {
#[cfg(feature = "inspector")]
if debug_instant.elapsed().as_millis() > 1000 {
info!("{force:?}");
}
force.force = Vec3::ZERO;
force.torque = Vec3::ZERO;
}
#[cfg(feature = "inspector")]
if debug_instant.elapsed().as_millis() > 1000 {
debug_instant.reset();
}
}
/// The desired lean angle, given steering input and speed.
@ -135,6 +132,7 @@ pub(super) fn wheel_forces(
&Transform,
&Velocity,
&mut ExternalForce,
&mut Friction,
Option<&CyberSteering>,
),
With<CyberWheel>,
@ -149,32 +147,51 @@ pub(super) fn wheel_forces(
let radius = wheel_config.radius;
// inputs
let steering = input.yaw;
let yaw = input.yaw;
let throttle = input.throttle * settings.accel;
for (xform, velocity, mut external_force, steering) in wheels_query.iter_mut() {
if let Some((_, projected)) =
context.project_point(xform.translation, false, QueryFilter::only_fixed())
{
let normal = (projected.point - xform.translation);
let len = normal.length();
if len < radius {
let mut force = Vec3::ZERO;
for (xform, velocity, mut external_force, mut friction, steering) in wheels_query.iter_mut() {
let pos = xform.translation;
if let Some((_, projected)) = context.project_point(pos, false, QueryFilter::only_fixed()) {
let mut force = Vec3::ZERO;
gizmos.sphere(projected.point, Quat::IDENTITY, radius, Color::RED);
let dir = (projected.point - pos).normalize();
if let Some((_, intersection)) = context.cast_ray_and_get_normal(
pos,
dir,
radius * 1.05,
false,
QueryFilter::only_fixed(),
) {
let norm = intersection.normal;
let point = intersection.point;
// do thrust's share
let thrust = normal.cross(xform.left().into()) * throttle;
let thrust = norm.cross(xform.right().into()) * throttle;
force += thrust;
// do steering's share
if steering.is_some() {
let thrust = norm.cross(xform.back().into());
force += yaw * thrust;
}
// do the friction's share
if input.brake {
friction.coefficient = 2.0;
} else {
friction.coefficient = 0.0;
}
// show the force
#[cfg(feature = "inspector")]
gizmos.arrow(xform.translation, force, Color::RED);
gizmos.arrow(pos, pos + force, Color::RED);
// ok apply the force
let ef = ExternalForce::at_point(force, projected.point, xform.translation);
*external_force = ef;
*external_force = ExternalForce::at_point(force, point, pos);
}
}
}

View File

@ -83,14 +83,10 @@ pub(crate) fn spawn_wheels(
.insert(not_sleeping)
.id();
let axel_parent_entity = if let Some(steering) = steering {
let axel_parent_entity = if steering.is_some() {
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();
let neck = commands.spawn(RigidBody::Dynamic).insert(neck_joint).id();
neck
} else {
fork_rb_entity
@ -99,9 +95,9 @@ pub(crate) fn spawn_wheels(
let axel_builder = FixedJointBuilder::new();
let axel_joint = MultibodyJoint::new(axel_parent_entity, axel_builder);
commands.spawn(pbr_bundle).insert((
let c = &mut commands.spawn(pbr_bundle);
c.insert((
mass_props,
//wheel_damping,
axel_joint,
CyberWheel,
not_sleeping,
@ -119,6 +115,9 @@ pub(crate) fn spawn_wheels(
wheels_collision_group,
Collider::ball(conf.radius),
));
if steering.is_some() {
c.insert(CyberSteering);
}
}
}