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;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue