checkpoint, colliders are parented correctly
This commit is contained in:
parent
22701733d4
commit
6dd7277584
2 changed files with 97 additions and 97 deletions
192
src/bike.rs
192
src/bike.rs
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ impl Default for DebugCamOffset {
|
|||
fn default() -> Self {
|
||||
DebugCamOffset {
|
||||
rot: 60.0,
|
||||
dist: 10.0,
|
||||
dist: 30.0,
|
||||
alt: 4.0,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue