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;
pub const REST_DISTANCE: f32 = 0.8;
#[derive(Component)]
pub struct CyberBikeBody;
#[derive(Component)]
pub struct CyberWheel;
pub enum CyberWheel {
Front,
Rear,
}
// marker for front suspension joint
#[derive(Component)]
pub struct Steering;
#[derive(Component)]
pub struct FrontHub;
// marker for rear suspension joint
#[derive(Component)]
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(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
let pos = Vec3::new(0.0, 4.0, 0.0);
let xform = Transform::from_translation(pos).with_rotation(Quat::from_rotation_z(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 body_collider =
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()))
.insert((
Name::new("body"),
@ -45,8 +63,6 @@ fn spawn_bike(
CyberBikeBody,
CatControllerState::default(),
ColliderDensity(20.0),
LinearDamping(0.1),
AngularDamping(2.0),
LinearVelocity::ZERO,
AngularVelocity::ZERO,
ExternalForce::ZERO.with_persistence(false),
@ -54,62 +70,89 @@ fn spawn_bike(
))
.with_children(|builder| {
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));
rotation.rotate_x(FRAC_PI_2);
let mut xform = Transform::default();
xform.rotate_x(FRAC_PI_2);
let pbr_bundle = (
Mesh3d(meshes.add(Capsule3d::new(0.5, 1.45))),
rotation,
xform,
MeshMaterial3d(materials.add(color)),
);
builder.spawn(pbr_bundle);
})
.id();
spawn_wheels(builder, meshes, materials, xform, builder.parent_entity());
});
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(
mut commands: Commands,
commands: &mut ChildBuilder,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
xform: Transform,
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 front_hub = wheels_helper(
&mut commands,
let front_rake = Vec3::new(0.0, -1.0, -0.57).normalize(); // about 30 degrees
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 materials,
front_pos,
front_wheel_pos,
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_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(
&mut commands,
spawn_caster(
commands,
collider,
Transform::from_translation(rear_attach),
Dir3::new_unchecked(rear_rake),
body,
false,
);
wheel_mesh(
commands,
&mut meshes,
&mut materials,
rear_pos,
rear_wheel_pos,
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) {
let mut tire_mesh: Mesh = Torus::new(0.25, 0.40).into();
let tire_verts = tire_mesh
.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();
let tire_mesh: Mesh = Sphere::new(0.4).into();
let collider = Collider::sphere(0.4);
(tire_mesh, collider)
}
fn wheels_helper(
commands: &mut Commands,
fn wheel_mesh(
commands: &mut ChildBuilder,
meshes: &mut ResMut<Assets<Mesh>>,
materials: &mut ResMut<Assets<StandardMaterial>>,
position: Vec3,
tire_mesh: Mesh,
collider: Collider,
) -> Entity {
wheel: CyberWheel,
) {
let wheel_material = &StandardMaterial {
base_color: Color::srgb(0.01, 0.01, 0.01),
alpha_mode: AlphaMode::Opaque,
@ -156,47 +182,21 @@ fn wheels_helper(
};
let xform = Transform::from_translation(position);
let hub_mesh: Mesh = Sphere::new(0.1).into();
let hub = commands
.spawn((
Name::new("hub"),
RigidBody::Dynamic,
MassPropertiesBundle::from_shape(&Collider::sphere(0.1), 200.0),
Mesh3d(meshes.add(hub_mesh)),
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
commands.spawn((
Name::new("tire"),
Mesh3d(meshes.add(tire_mesh)),
MeshMaterial3d(materials.add(wheel_material.clone())),
xform,
wheel,
));
}
pub struct CyberBikePlugin;
impl Plugin for CyberBikePlugin {
fn build(&self, app: &mut App) {
app.init_resource::<SuspensionConfig>();
app.add_systems(Startup, spawn_bike);
}
}

View file

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