Add proper collision shape for displaced geo.

This commit is contained in:
Joe Ardent 2022-02-21 15:42:44 -08:00
parent 373fc30d56
commit a089f3da46
3 changed files with 72 additions and 27 deletions

View file

@ -1,4 +1,7 @@
use bevy::prelude::*;
use bevy::{
prelude::*,
render::mesh::{Indices, VertexAttributeValues},
};
use bevy_rapier3d::{na::Vector3, prelude::*};
use crate::{
@ -23,38 +26,71 @@ impl Default for MovementSettings {
fn setup_colliders(
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>>,
) {
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 {
body_type: RigidBodyType::Static.into(),
..Default::default()
};
let pcollide = ColliderBundle {
shape: ColliderShape::ball(PLANET_RADIUS).into(),
material: ColliderMaterial {
friction: 0.05,
restitution: 0.01,
ccd: RigidBodyCcd {
ccd_enabled: true,
ccd_max_dist: PLANET_RADIUS * 1.1,
ccd_thickness: 0.4,
..Default::default()
}
.into(),
mass_properties: ColliderMassProps::Density(0.0).into(),
..Default::default()
};
let pcollide = ColliderBundle {
shape: shape.into(),
material: ColliderMaterial {
friction: 0.05,
restitution: 0.00,
..Default::default()
}
.into(),
..Default::default()
};
commands
.entity(planet)
.insert_bundle(pbody)
.insert_bundle(pcollide);
// bike is the easy part
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();
bbody.damping.angular_damping = 0.7;
bbody.damping.linear_damping = 0.3;
bbody.damping.angular_damping = 0.8;
bbody.damping.linear_damping = 0.5;
bbody.forces = RigidBodyForces {
torque: Vec3::ZERO.into(),
..Default::default()
@ -62,25 +98,24 @@ fn setup_bike(bike: Entity, xform: &Transform, commands: &mut Commands) {
.into();
bbody.ccd = RigidBodyCcd {
ccd_enabled: true,
ccd_max_dist: 2.4,
..Default::default()
}
.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());
bbody.position = isometry.into();
// collider
let shape = ColliderShape::capsule(
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,
);
let bcollide = ColliderBundle {
shape: shape.into(),
mass_properties: ColliderMassProps::Density(0.2).into(),
mass_properties: ColliderMassProps::Density(0.4).into(),
material: ColliderMaterial {
friction: 0.0,
restitution: 0.05,
restitution: 0.01,
..Default::default()
}
.into(),
@ -144,7 +179,10 @@ impl Plugin for CyberActionPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<MovementSettings>()
.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(falling_cat.label("cat"))
.add_system(update_forces.after("cat"));

View file

@ -8,8 +8,8 @@ use wgpu::PrimitiveTopology;
use crate::Label;
pub const PLANET_RADIUS: f32 = 860.0;
pub(crate) const SPAWN_ALTITUDE: f32 = PLANET_RADIUS + 2.0;
pub const PLANET_RADIUS: f32 = 1200.0;
pub(crate) const SPAWN_ALTITUDE: f32 = PLANET_RADIUS * 1.095;
#[derive(Component, Debug)]
pub struct CyberBike;
@ -95,7 +95,7 @@ fn gen_planet(sphere: Icosphere) -> Mesh {
.raw_points()
.iter()
.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;
pt.into()
})

View file

@ -16,13 +16,13 @@ pub const BISEXY_COLOR: Color = Color::hsla(292.0, 0.9, 0.60, 1.1);
fn wireframe_planet(
mut commands: Commands,
meshes: Res<Assets<Mesh>>,
mut meshes: ResMut<Assets<Mesh>>,
mut polylines: ResMut<Assets<Polyline>>,
mut polymats: ResMut<Assets<PolylineMaterial>>,
query: Query<&Handle<Mesh>, With<CyberSphere>>,
) {
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 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 {
polyline: polylines.add(Polyline { vertices: verts }),
material: polymats.add(PolylineMaterial {
@ -86,7 +90,10 @@ impl Plugin for CyberGlamorPlugin {
..Default::default()
})
.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_plugin(PolylinePlugin)
.add_plugin(WireframePlugin);