From a089f3da46588f3f1f59bfb47c80f1f86a455994 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Mon, 21 Feb 2022 15:42:44 -0800 Subject: [PATCH] Add proper collision shape for displaced geo. --- src/action.rs | 80 ++++++++++++++++++++++++++++++++++++------------- src/geometry.rs | 6 ++-- src/glamor.rs | 13 ++++++-- 3 files changed, 72 insertions(+), 27 deletions(-) diff --git a/src/action.rs b/src/action.rs index e6080db..ef29ece 100644 --- a/src/action.rs +++ b/src/action.rs @@ -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>, + meshes: Res>, + planet_query: Query<(Entity, &Handle), With>, bike_query: Query<(Entity, &Transform), With>, ) { - 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 = 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::>>(); + + 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::() .add_plugin(RapierPhysicsPlugin::::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")); diff --git a/src/geometry.rs b/src/geometry.rs index 5fc70fe..a5db388 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -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() }) diff --git a/src/glamor.rs b/src/glamor.rs index 904da4a..1f8eb0c 100644 --- a/src/glamor.rs +++ b/src/glamor.rs @@ -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>, + mut meshes: ResMut>, mut polylines: ResMut>, mut polymats: ResMut>, query: Query<&Handle, With>, ) { 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);