actually kinda works, but needs simulated friction.
This commit is contained in:
parent
0fae893508
commit
c3e955c1cd
3 changed files with 58 additions and 43 deletions
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue