checkpoint, colliders are parented correctly

This commit is contained in:
Joe Ardent 2025-02-17 20:30:23 -08:00
parent 22701733d4
commit 6dd7277584
2 changed files with 97 additions and 97 deletions

View file

@ -5,36 +5,54 @@ use bevy::prelude::*;
use crate::physics::CatControllerState; use crate::physics::CatControllerState;
pub const REST_DISTANCE: f32 = 0.8;
#[derive(Component)] #[derive(Component)]
pub struct CyberBikeBody; pub struct CyberBikeBody;
#[derive(Component)] #[derive(Component)]
pub struct CyberWheel; pub enum CyberWheel {
Front,
Rear,
}
// marker for front suspension joint // marker for front suspension joint
#[derive(Component)] #[derive(Component)]
pub struct Steering; pub struct Steering;
#[derive(Component)]
pub struct FrontHub;
// marker for rear suspension joint // marker for rear suspension joint
#[derive(Component)] #[derive(Component)]
pub struct Rearing; pub struct Rearing;
#[derive(Component)]
pub struct RearHub; #[derive(Debug, Resource, Reflect)]
pub struct SuspensionConfig {
pub rest_dist: f32,
pub konstant: f32,
pub damping: f32,
}
impl Default for SuspensionConfig {
fn default() -> Self {
Self {
rest_dist: REST_DISTANCE,
konstant: 150.0,
damping: 50.0,
}
}
}
fn spawn_bike( fn spawn_bike(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
) { ) {
let pos = Vec3::new(0.0, 4.0, 0.0); let pos = Vec3::new(0.0, 24.0, 0.0);
let xform = Transform::from_translation(pos).with_rotation(Quat::from_rotation_z(0.0)); let xform = Transform::from_translation(pos); //.with_rotation(Quat::from_rotation_z(0.0));
let body_collider = let body_collider =
Collider::capsule_endpoints(0.5, Vec3::new(0.0, 0.0, -0.65), Vec3::new(0.0, 0.0, 0.8)); Collider::capsule_endpoints(0.5, Vec3::new(0.0, 0.0, -0.65), Vec3::new(0.0, 0.0, 0.8));
let bike = commands let _bike = commands
.spawn((xform, Visibility::default())) .spawn((xform, Visibility::default()))
.insert(( .insert((
Name::new("body"), Name::new("body"),
@ -45,8 +63,6 @@ fn spawn_bike(
CyberBikeBody, CyberBikeBody,
CatControllerState::default(), CatControllerState::default(),
ColliderDensity(20.0), ColliderDensity(20.0),
LinearDamping(0.1),
AngularDamping(2.0),
LinearVelocity::ZERO, LinearVelocity::ZERO,
AngularVelocity::ZERO, AngularVelocity::ZERO,
ExternalForce::ZERO.with_persistence(false), ExternalForce::ZERO.with_persistence(false),
@ -54,62 +70,89 @@ fn spawn_bike(
)) ))
.with_children(|builder| { .with_children(|builder| {
let color = Color::srgb(0.7, 0.05, 0.7); let color = Color::srgb(0.7, 0.05, 0.7);
let mut rotation = Transform::default(); // Transform::from_rotation(Quat::from_rotation_y(FRAC_PI_2)); let mut xform = Transform::default();
rotation.rotate_x(FRAC_PI_2); xform.rotate_x(FRAC_PI_2);
let pbr_bundle = ( let pbr_bundle = (
Mesh3d(meshes.add(Capsule3d::new(0.5, 1.45))), Mesh3d(meshes.add(Capsule3d::new(0.5, 1.45))),
rotation, xform,
MeshMaterial3d(materials.add(color)), MeshMaterial3d(materials.add(color)),
); );
builder.spawn(pbr_bundle); builder.spawn(pbr_bundle);
}) spawn_wheels(builder, meshes, materials, xform, builder.parent_entity());
.id(); });
spawn_wheels(commands, meshes, materials, xform, bike); //spawn_wheels(commands, meshes, materials, xform, bike);
}
fn spawn_caster(
commands: &mut ChildBuilder,
collider: Collider,
xform: Transform,
direction: Dir3,
parent: Entity,
is_front: bool,
) {
let caster = ShapeCaster::new(collider, xform.translation, Quat::IDENTITY, direction)
.with_query_filter(SpatialQueryFilter::from_excluded_entities([parent]));
let mut entity = commands.spawn((caster, Transform::default()));
if is_front {
entity.insert((Steering, Name::new("front wheel")));
} else {
entity.insert((Rearing, Name::new("rear wheel")));
}
} }
fn spawn_wheels( fn spawn_wheels(
mut commands: Commands, commands: &mut ChildBuilder,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
xform: Transform, xform: Transform,
body: Entity, body: Entity,
) { ) {
let front_rake = Vec3::new(0.0, -1.0, -0.57).normalize(); // about 30 degrees
let front_pos = xform.translation + front_rake;
let (mesh, collider) = gen_tire(); let (mesh, collider) = gen_tire();
let front_hub = wheels_helper( let front_rake = Vec3::new(0.0, -1.0, -0.57).normalize(); // about 30 degrees
&mut commands, let front_attach = xform.translation + xform.forward() * 0.7;
let front_wheel_pos = front_attach + (front_rake * REST_DISTANCE);
spawn_caster(
commands,
collider.clone(),
Transform::from_translation(front_attach),
Dir3::new_unchecked(front_rake),
body,
true,
);
wheel_mesh(
commands,
&mut meshes, &mut meshes,
&mut materials, &mut materials,
front_pos, front_wheel_pos,
mesh.clone(), mesh.clone(),
collider.clone(), CyberWheel::Front,
); );
commands.entity(front_hub).insert(FrontHub);
commands.spawn((
Steering,
FixedJoint::new(front_hub, body).with_local_anchor_2(*xform.forward() + front_rake),
));
let rear_rake = Vec3::new(0.0, -1.0, 0.57).normalize(); let rear_rake = Vec3::new(0.0, -1.0, 0.57).normalize();
let rear_pos = xform.translation + rear_rake; let rear_attach = xform.translation + xform.back() * 0.7;
let rear_wheel_pos = rear_attach + (rear_rake * REST_DISTANCE);
let rear_hub = wheels_helper( spawn_caster(
&mut commands, commands,
collider,
Transform::from_translation(rear_attach),
Dir3::new_unchecked(rear_rake),
body,
false,
);
wheel_mesh(
commands,
&mut meshes, &mut meshes,
&mut materials, &mut materials,
rear_pos, rear_wheel_pos,
mesh, mesh,
collider, CyberWheel::Rear,
); );
commands.entity(rear_hub).insert(RearHub);
commands.spawn((
Rearing,
FixedJoint::new(rear_hub, body).with_local_anchor_2(*xform.back() + rear_rake),
));
} }
//-************************************************************************ //-************************************************************************
@ -117,37 +160,20 @@ fn spawn_wheels(
//-************************************************************************ //-************************************************************************
fn gen_tire() -> (Mesh, Collider) { fn gen_tire() -> (Mesh, Collider) {
let mut tire_mesh: Mesh = Torus::new(0.25, 0.40).into(); let tire_mesh: Mesh = Sphere::new(0.4).into();
let tire_verts = tire_mesh let collider = Collider::sphere(0.4);
.attribute(Mesh::ATTRIBUTE_POSITION)
.unwrap()
.as_float3()
.unwrap()
.iter()
.map(|v| {
//
let v = Vec3::from_array(*v);
let m = Mat3::from_rotation_z(90.0f32.to_radians());
let p = m.mul_vec3(v);
p.to_array()
})
.collect::<Vec<[f32; 3]>>();
tire_mesh.remove_attribute(Mesh::ATTRIBUTE_POSITION);
tire_mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, tire_verts);
let collider = Collider::convex_hull_from_mesh(&tire_mesh).unwrap();
(tire_mesh, collider) (tire_mesh, collider)
} }
fn wheels_helper( fn wheel_mesh(
commands: &mut Commands, commands: &mut ChildBuilder,
meshes: &mut ResMut<Assets<Mesh>>, meshes: &mut ResMut<Assets<Mesh>>,
materials: &mut ResMut<Assets<StandardMaterial>>, materials: &mut ResMut<Assets<StandardMaterial>>,
position: Vec3, position: Vec3,
tire_mesh: Mesh, tire_mesh: Mesh,
collider: Collider, wheel: CyberWheel,
) -> Entity { ) {
let wheel_material = &StandardMaterial { let wheel_material = &StandardMaterial {
base_color: Color::srgb(0.01, 0.01, 0.01), base_color: Color::srgb(0.01, 0.01, 0.01),
alpha_mode: AlphaMode::Opaque, alpha_mode: AlphaMode::Opaque,
@ -156,47 +182,21 @@ fn wheels_helper(
}; };
let xform = Transform::from_translation(position); let xform = Transform::from_translation(position);
let hub_mesh: Mesh = Sphere::new(0.1).into();
let hub = commands commands.spawn((
.spawn(( Name::new("tire"),
Name::new("hub"), Mesh3d(meshes.add(tire_mesh)),
RigidBody::Dynamic, MeshMaterial3d(materials.add(wheel_material.clone())),
MassPropertiesBundle::from_shape(&Collider::sphere(0.1), 200.0), xform,
Mesh3d(meshes.add(hub_mesh)), wheel,
MeshMaterial3d(materials.add(wheel_material.clone())), ));
xform,
))
.id();
let tire = commands
.spawn((
Name::new("tire"),
Mesh3d(meshes.add(tire_mesh)),
MeshMaterial3d(materials.add(wheel_material.clone())),
xform,
CyberWheel,
RigidBody::Dynamic,
collider,
Friction::new(0.9).with_dynamic_coefficient(0.6),
Restitution::new(0.1),
ColliderDensity(30.0),
CollisionLayers::from_bits(2, 2),
ExternalTorque::ZERO.with_persistence(false),
CollisionMargin(0.05),
SweptCcd::NON_LINEAR,
))
.id();
// connect hubs and tires to make wheels
commands.spawn(RevoluteJoint::new(hub, tire).with_aligned_axis(Vec3::X));
hub
} }
pub struct CyberBikePlugin; pub struct CyberBikePlugin;
impl Plugin for CyberBikePlugin { impl Plugin for CyberBikePlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.init_resource::<SuspensionConfig>();
app.add_systems(Startup, spawn_bike); app.add_systems(Startup, spawn_bike);
} }
} }

View file

@ -16,7 +16,7 @@ impl Default for DebugCamOffset {
fn default() -> Self { fn default() -> Self {
DebugCamOffset { DebugCamOffset {
rot: 60.0, rot: 60.0,
dist: 10.0, dist: 30.0,
alt: 4.0, alt: 4.0,
} }
} }