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(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
(
|
(
|
||||||
reset_body_force,
|
reset_external_forces,
|
||||||
reset_wheel_forces,
|
|
||||||
cyber_lean,
|
cyber_lean,
|
||||||
falling_cat,
|
falling_cat,
|
||||||
wheel_forces,
|
wheel_forces,
|
||||||
|
|
|
@ -6,9 +6,12 @@ use bevy::{
|
||||||
},
|
},
|
||||||
render::color::Color,
|
render::color::Color,
|
||||||
};
|
};
|
||||||
use bevy_rapier3d::prelude::{
|
use bevy_rapier3d::{
|
||||||
ExternalForce, QueryFilter, RapierConfiguration, RapierContext, ReadMassProperties,
|
geometry::Friction,
|
||||||
TimestepMode, Velocity,
|
prelude::{
|
||||||
|
ExternalForce, QueryFilter, RapierConfiguration, RapierContext, ReadMassProperties,
|
||||||
|
TimestepMode, Velocity,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "inspector")]
|
#[cfg(feature = "inspector")]
|
||||||
|
@ -34,29 +37,23 @@ pub(super) fn physics_init(
|
||||||
config.gravity = Vec3::NEG_Y * settings.gravity;
|
config.gravity = Vec3::NEG_Y * settings.gravity;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn reset_body_force(
|
pub(super) fn reset_external_forces(
|
||||||
mut query: Query<&mut ExternalForce, With<CyberBikeBody>>,
|
mut query: Query<&mut ExternalForce>,
|
||||||
#[cfg(feature = "inspector")] mut debug_instant: ResMut<ActionDebugInstant>,
|
#[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() {
|
for mut force in query.iter_mut() {
|
||||||
|
#[cfg(feature = "inspector")]
|
||||||
|
if debug_instant.elapsed().as_millis() > 1000 {
|
||||||
|
info!("{force:?}");
|
||||||
|
}
|
||||||
|
|
||||||
force.force = Vec3::ZERO;
|
force.force = Vec3::ZERO;
|
||||||
force.torque = 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.
|
/// The desired lean angle, given steering input and speed.
|
||||||
|
@ -135,6 +132,7 @@ pub(super) fn wheel_forces(
|
||||||
&Transform,
|
&Transform,
|
||||||
&Velocity,
|
&Velocity,
|
||||||
&mut ExternalForce,
|
&mut ExternalForce,
|
||||||
|
&mut Friction,
|
||||||
Option<&CyberSteering>,
|
Option<&CyberSteering>,
|
||||||
),
|
),
|
||||||
With<CyberWheel>,
|
With<CyberWheel>,
|
||||||
|
@ -149,32 +147,51 @@ pub(super) fn wheel_forces(
|
||||||
let radius = wheel_config.radius;
|
let radius = wheel_config.radius;
|
||||||
|
|
||||||
// inputs
|
// inputs
|
||||||
let steering = input.yaw;
|
let yaw = input.yaw;
|
||||||
let throttle = input.throttle * settings.accel;
|
let throttle = input.throttle * settings.accel;
|
||||||
|
|
||||||
for (xform, velocity, mut external_force, steering) in wheels_query.iter_mut() {
|
for (xform, velocity, mut external_force, mut friction, steering) in wheels_query.iter_mut() {
|
||||||
if let Some((_, projected)) =
|
let pos = xform.translation;
|
||||||
context.project_point(xform.translation, false, QueryFilter::only_fixed())
|
if let Some((_, projected)) = context.project_point(pos, false, QueryFilter::only_fixed()) {
|
||||||
{
|
let mut force = Vec3::ZERO;
|
||||||
let normal = (projected.point - xform.translation);
|
|
||||||
let len = normal.length();
|
gizmos.sphere(projected.point, Quat::IDENTITY, radius, Color::RED);
|
||||||
if len < radius {
|
|
||||||
let mut force = Vec3::ZERO;
|
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
|
// do thrust's share
|
||||||
let thrust = normal.cross(xform.left().into()) * throttle;
|
let thrust = norm.cross(xform.right().into()) * throttle;
|
||||||
force += thrust;
|
force += thrust;
|
||||||
|
|
||||||
// do steering's share
|
// do steering's share
|
||||||
|
if steering.is_some() {
|
||||||
|
let thrust = norm.cross(xform.back().into());
|
||||||
|
force += yaw * thrust;
|
||||||
|
}
|
||||||
|
|
||||||
// do the friction's share
|
// do the friction's share
|
||||||
|
if input.brake {
|
||||||
|
friction.coefficient = 2.0;
|
||||||
|
} else {
|
||||||
|
friction.coefficient = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
// show the force
|
// show the force
|
||||||
#[cfg(feature = "inspector")]
|
#[cfg(feature = "inspector")]
|
||||||
gizmos.arrow(xform.translation, force, Color::RED);
|
gizmos.arrow(pos, pos + force, Color::RED);
|
||||||
|
|
||||||
// ok apply the force
|
// ok apply the force
|
||||||
let ef = ExternalForce::at_point(force, projected.point, xform.translation);
|
*external_force = ExternalForce::at_point(force, point, pos);
|
||||||
*external_force = ef;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,14 +83,10 @@ pub(crate) fn spawn_wheels(
|
||||||
.insert(not_sleeping)
|
.insert(not_sleeping)
|
||||||
.id();
|
.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_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_joint = MultibodyJoint::new(fork_rb_entity, neck_builder);
|
||||||
let neck = commands
|
let neck = commands.spawn(RigidBody::Dynamic).insert(neck_joint).id();
|
||||||
.spawn(RigidBody::Dynamic)
|
|
||||||
.insert(neck_joint)
|
|
||||||
.insert(steering)
|
|
||||||
.id();
|
|
||||||
neck
|
neck
|
||||||
} else {
|
} else {
|
||||||
fork_rb_entity
|
fork_rb_entity
|
||||||
|
@ -99,9 +95,9 @@ pub(crate) fn spawn_wheels(
|
||||||
let axel_builder = FixedJointBuilder::new();
|
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);
|
||||||
|
|
||||||
commands.spawn(pbr_bundle).insert((
|
let c = &mut commands.spawn(pbr_bundle);
|
||||||
|
c.insert((
|
||||||
mass_props,
|
mass_props,
|
||||||
//wheel_damping,
|
|
||||||
axel_joint,
|
axel_joint,
|
||||||
CyberWheel,
|
CyberWheel,
|
||||||
not_sleeping,
|
not_sleeping,
|
||||||
|
@ -119,6 +115,9 @@ pub(crate) fn spawn_wheels(
|
||||||
wheels_collision_group,
|
wheels_collision_group,
|
||||||
Collider::ball(conf.radius),
|
Collider::ball(conf.radius),
|
||||||
));
|
));
|
||||||
|
if steering.is_some() {
|
||||||
|
c.insert(CyberSteering);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue