Add proper collision shape for displaced geo.
This commit is contained in:
parent
373fc30d56
commit
a089f3da46
3 changed files with 72 additions and 27 deletions
|
@ -1,4 +1,7 @@
|
||||||
use bevy::prelude::*;
|
use bevy::{
|
||||||
|
prelude::*,
|
||||||
|
render::mesh::{Indices, VertexAttributeValues},
|
||||||
|
};
|
||||||
use bevy_rapier3d::{na::Vector3, prelude::*};
|
use bevy_rapier3d::{na::Vector3, prelude::*};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -23,38 +26,71 @@ impl Default for MovementSettings {
|
||||||
|
|
||||||
fn setup_colliders(
|
fn setup_colliders(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
planet_query: Query<Entity, With<CyberSphere>>,
|
meshes: Res<Assets<Mesh>>,
|
||||||
|
planet_query: Query<(Entity, &Handle<Mesh>), With<CyberSphere>>,
|
||||||
bike_query: Query<(Entity, &Transform), With<CyberBike>>,
|
bike_query: Query<(Entity, &Transform), With<CyberBike>>,
|
||||||
) {
|
) {
|
||||||
let planet = planet_query.single();
|
let (planet, mesh_handle) = planet_query.single();
|
||||||
|
|
||||||
|
let mesh = meshes.get(mesh_handle).unwrap();
|
||||||
|
|
||||||
|
let mut shape = ColliderShape::ball(PLANET_RADIUS);
|
||||||
|
|
||||||
|
let vertices = mesh.attribute(Mesh::ATTRIBUTE_POSITION).unwrap();
|
||||||
|
if let VertexAttributeValues::Float32x3(verts) = vertices {
|
||||||
|
if let Some(Indices::U32(indices)) = mesh.indices() {
|
||||||
|
//let vertices: Vec<Vec3> = verts.iter().map(|v|
|
||||||
|
// Vec3::from_slice(v)).collect();
|
||||||
|
let mut idxs = Vec::new();
|
||||||
|
for idx in indices.chunks_exact(3) {
|
||||||
|
idxs.push([idx[0], idx[1], idx[2]]);
|
||||||
|
}
|
||||||
|
let vertices = verts
|
||||||
|
.iter()
|
||||||
|
.map(|p| Point::from_slice(p))
|
||||||
|
.collect::<Vec<Point<_>>>();
|
||||||
|
|
||||||
|
shape = ColliderShape::convex_decomposition(&vertices, &idxs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ok, now attach shit
|
||||||
let pbody = RigidBodyBundle {
|
let pbody = RigidBodyBundle {
|
||||||
body_type: RigidBodyType::Static.into(),
|
body_type: RigidBodyType::Static.into(),
|
||||||
..Default::default()
|
ccd: RigidBodyCcd {
|
||||||
};
|
ccd_enabled: true,
|
||||||
let pcollide = ColliderBundle {
|
ccd_max_dist: PLANET_RADIUS * 1.1,
|
||||||
shape: ColliderShape::ball(PLANET_RADIUS).into(),
|
ccd_thickness: 0.4,
|
||||||
material: ColliderMaterial {
|
|
||||||
friction: 0.05,
|
|
||||||
restitution: 0.01,
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
mass_properties: ColliderMassProps::Density(0.0).into(),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
let pcollide = ColliderBundle {
|
||||||
|
shape: shape.into(),
|
||||||
|
material: ColliderMaterial {
|
||||||
|
friction: 0.05,
|
||||||
|
restitution: 0.00,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.entity(planet)
|
.entity(planet)
|
||||||
.insert_bundle(pbody)
|
.insert_bundle(pbody)
|
||||||
.insert_bundle(pcollide);
|
.insert_bundle(pcollide);
|
||||||
|
|
||||||
|
// bike is the easy part
|
||||||
let (bike, xform) = bike_query.single();
|
let (bike, xform) = bike_query.single();
|
||||||
setup_bike(bike, xform, &mut commands);
|
setup_bike_collider(bike, xform, &mut commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_bike(bike: Entity, xform: &Transform, commands: &mut Commands) {
|
fn setup_bike_collider(bike: Entity, xform: &Transform, commands: &mut Commands) {
|
||||||
let mut bbody = RigidBodyBundle::default();
|
let mut bbody = RigidBodyBundle::default();
|
||||||
bbody.damping.angular_damping = 0.7;
|
bbody.damping.angular_damping = 0.8;
|
||||||
bbody.damping.linear_damping = 0.3;
|
bbody.damping.linear_damping = 0.5;
|
||||||
bbody.forces = RigidBodyForces {
|
bbody.forces = RigidBodyForces {
|
||||||
torque: Vec3::ZERO.into(),
|
torque: Vec3::ZERO.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -62,25 +98,24 @@ fn setup_bike(bike: Entity, xform: &Transform, commands: &mut Commands) {
|
||||||
.into();
|
.into();
|
||||||
bbody.ccd = RigidBodyCcd {
|
bbody.ccd = RigidBodyCcd {
|
||||||
ccd_enabled: true,
|
ccd_enabled: true,
|
||||||
|
ccd_max_dist: 2.4,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.into();
|
.into();
|
||||||
// bbody.mass_properties = MassProperties::new(Vec3::ZERO.into(), 0.5,
|
|
||||||
// Vec3::new(0.0, 0.01, 0.0).into()).into();
|
|
||||||
let isometry = Isometry::from_parts(xform.translation.into(), xform.rotation.into());
|
let isometry = Isometry::from_parts(xform.translation.into(), xform.rotation.into());
|
||||||
bbody.position = isometry.into();
|
bbody.position = isometry.into();
|
||||||
// collider
|
// collider
|
||||||
let shape = ColliderShape::capsule(
|
let shape = ColliderShape::capsule(
|
||||||
Vec3::new(0.0, 0.0, -1.25).into(),
|
Vec3::new(0.0, 0.0, -1.25).into(),
|
||||||
Vec3::new(0.0, 0.0, 1.2).into(),
|
Vec3::new(0.0, 0.0, 1.25).into(),
|
||||||
0.4,
|
0.4,
|
||||||
);
|
);
|
||||||
let bcollide = ColliderBundle {
|
let bcollide = ColliderBundle {
|
||||||
shape: shape.into(),
|
shape: shape.into(),
|
||||||
mass_properties: ColliderMassProps::Density(0.2).into(),
|
mass_properties: ColliderMassProps::Density(0.4).into(),
|
||||||
material: ColliderMaterial {
|
material: ColliderMaterial {
|
||||||
friction: 0.0,
|
friction: 0.0,
|
||||||
restitution: 0.05,
|
restitution: 0.01,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -144,7 +179,10 @@ impl Plugin for CyberActionPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_resource::<MovementSettings>()
|
app.init_resource::<MovementSettings>()
|
||||||
.add_plugin(RapierPhysicsPlugin::<NoUserData>::default())
|
.add_plugin(RapierPhysicsPlugin::<NoUserData>::default())
|
||||||
.add_startup_system_to_stage(StartupStage::PostStartup, setup_colliders)
|
.add_startup_system_to_stage(
|
||||||
|
StartupStage::PostStartup,
|
||||||
|
setup_colliders.label("colliders"),
|
||||||
|
)
|
||||||
.add_system(gravity)
|
.add_system(gravity)
|
||||||
.add_system(falling_cat.label("cat"))
|
.add_system(falling_cat.label("cat"))
|
||||||
.add_system(update_forces.after("cat"));
|
.add_system(update_forces.after("cat"));
|
||||||
|
|
|
@ -8,8 +8,8 @@ use wgpu::PrimitiveTopology;
|
||||||
|
|
||||||
use crate::Label;
|
use crate::Label;
|
||||||
|
|
||||||
pub const PLANET_RADIUS: f32 = 860.0;
|
pub const PLANET_RADIUS: f32 = 1200.0;
|
||||||
pub(crate) const SPAWN_ALTITUDE: f32 = PLANET_RADIUS + 2.0;
|
pub(crate) const SPAWN_ALTITUDE: f32 = PLANET_RADIUS * 1.095;
|
||||||
|
|
||||||
#[derive(Component, Debug)]
|
#[derive(Component, Debug)]
|
||||||
pub struct CyberBike;
|
pub struct CyberBike;
|
||||||
|
@ -95,7 +95,7 @@ fn gen_planet(sphere: Icosphere) -> Mesh {
|
||||||
.raw_points()
|
.raw_points()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&p| {
|
.map(|&p| {
|
||||||
let disp = noise.get(p.as_dvec3().into()) as f32 * 0.07;
|
let disp = noise.get(p.as_dvec3().into()) as f32 * 0.09;
|
||||||
let pt = p + disp;
|
let pt = p + disp;
|
||||||
pt.into()
|
pt.into()
|
||||||
})
|
})
|
||||||
|
|
|
@ -16,13 +16,13 @@ pub const BISEXY_COLOR: Color = Color::hsla(292.0, 0.9, 0.60, 1.1);
|
||||||
|
|
||||||
fn wireframe_planet(
|
fn wireframe_planet(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
meshes: Res<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
mut polylines: ResMut<Assets<Polyline>>,
|
mut polylines: ResMut<Assets<Polyline>>,
|
||||||
mut polymats: ResMut<Assets<PolylineMaterial>>,
|
mut polymats: ResMut<Assets<PolylineMaterial>>,
|
||||||
query: Query<&Handle<Mesh>, With<CyberSphere>>,
|
query: Query<&Handle<Mesh>, With<CyberSphere>>,
|
||||||
) {
|
) {
|
||||||
let handle = query.single();
|
let handle = query.single();
|
||||||
let mesh = meshes.get(handle).unwrap();
|
let mesh = meshes.get_mut(handle).unwrap();
|
||||||
let vertices = mesh.attribute(Mesh::ATTRIBUTE_POSITION).unwrap();
|
let vertices = mesh.attribute(Mesh::ATTRIBUTE_POSITION).unwrap();
|
||||||
|
|
||||||
let mut pts = Vec::with_capacity(vertices.len());
|
let mut pts = Vec::with_capacity(vertices.len());
|
||||||
|
@ -46,6 +46,10 @@ fn wireframe_planet(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// don't need the indices anymore
|
||||||
|
mesh.duplicate_vertices();
|
||||||
|
mesh.compute_flat_normals();
|
||||||
|
|
||||||
commands.spawn_bundle(PolylineBundle {
|
commands.spawn_bundle(PolylineBundle {
|
||||||
polyline: polylines.add(Polyline { vertices: verts }),
|
polyline: polylines.add(Polyline { vertices: verts }),
|
||||||
material: polymats.add(PolylineMaterial {
|
material: polymats.add(PolylineMaterial {
|
||||||
|
@ -86,7 +90,10 @@ impl Plugin for CyberGlamorPlugin {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.insert_resource(WireframeConfig { global: false })
|
.insert_resource(WireframeConfig { global: false })
|
||||||
.add_startup_system_to_stage(StartupStage::PostStartup, wireframe_planet)
|
.add_startup_system_to_stage(
|
||||||
|
StartupStage::PostStartup,
|
||||||
|
wireframe_planet.after("colliders"),
|
||||||
|
)
|
||||||
.add_system(wireframify_lights)
|
.add_system(wireframify_lights)
|
||||||
.add_plugin(PolylinePlugin)
|
.add_plugin(PolylinePlugin)
|
||||||
.add_plugin(WireframePlugin);
|
.add_plugin(WireframePlugin);
|
||||||
|
|
Loading…
Reference in a new issue