From 64958470950cd9832a669b1bd5d70a2aeb6a85ef Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Tue, 20 Oct 2020 15:57:54 +0200 Subject: Add rounded cylinder. --- src/geometry/collider.rs | 95 +++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 49 deletions(-) (limited to 'src/geometry/collider.rs') diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index f952b15..4b3b115 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -1,7 +1,7 @@ use crate::dynamics::{MassProperties, RigidBodyHandle, RigidBodySet}; use crate::geometry::{ Ball, Capsule, ColliderGraphIndex, Contact, Cuboid, HeightField, InteractionGraph, Polygon, - Proximity, Ray, RayIntersection, Shape, ShapeType, Triangle, Trimesh, + Proximity, Ray, RayIntersection, Rounded, Shape, ShapeType, Triangle, Trimesh, }; #[cfg(feature = "dim3")] use crate::geometry::{Cone, Cylinder, PolygonalFeatureMap}; @@ -40,6 +40,17 @@ impl ColliderShape { ColliderShape(Arc::new(Cylinder::new(half_height, radius))) } + /// Initialize a rounded cylindrical shape defined by its half-height + /// (along along the y axis), its radius, and its roundedness (the + /// radius of the sphere used for dilating the cylinder). + #[cfg(feature = "dim3")] + pub fn rounded_cylinder(half_height: f32, radius: f32, rounding_radius: f32) -> Self { + ColliderShape(Arc::new(Rounded::new( + Cylinder::new(half_height, radius), + rounding_radius, + ))) + } + /// Initialize a cone shape defined by its half-height /// (along along the y axis) and its basis radius. #[cfg(feature = "dim3")] @@ -127,13 +138,20 @@ impl<'de> serde::Deserialize<'de> for ColliderShape { .next_element()? .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; + fn deser<'de, A, S: Shape + serde::Deserialize<'de>>( + seq: &mut A, + ) -> Result, A::Error> + where + A: serde::de::SeqAccess<'de>, + { + let shape: S = seq.next_element()?.ok_or_else(|| { + serde::de::Error::custom("Failed to deserialize builtin shape.") + })?; + Ok(Arc::new(shape) as Arc) + } + let shape = match ShapeType::from_i32(tag) { - Some(ShapeType::Ball) => { - let shape: Ball = seq - .next_element()? - .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; - Arc::new(shape) as Arc - } + Some(ShapeType::Ball) => deser::(&mut seq)?, Some(ShapeType::Polygon) => { unimplemented!() // let shape: Polygon = seq @@ -141,50 +159,17 @@ impl<'de> serde::Deserialize<'de> for ColliderShape { // .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; // Arc::new(shape) as Arc } - Some(ShapeType::Cuboid) => { - let shape: Cuboid = seq - .next_element()? - .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; - Arc::new(shape) as Arc - } - Some(ShapeType::Capsule) => { - let shape: Capsule = seq - .next_element()? - .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; - Arc::new(shape) as Arc - } - Some(ShapeType::Triangle) => { - let shape: Triangle = seq - .next_element()? - .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; - Arc::new(shape) as Arc - } - Some(ShapeType::Trimesh) => { - let shape: Trimesh = seq - .next_element()? - .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; - Arc::new(shape) as Arc - } - Some(ShapeType::HeightField) => { - let shape: HeightField = seq - .next_element()? - .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; - Arc::new(shape) as Arc - } + Some(ShapeType::Cuboid) => deser::(&mut seq)?, + Some(ShapeType::Capsule) => deser::(&mut seq)?, + Some(ShapeType::Triangle) => deser::(&mut seq)?, + Some(ShapeType::Trimesh) => deser::(&mut seq)?, + Some(ShapeType::HeightField) => deser::(&mut seq)?, #[cfg(feature = "dim3")] - Some(ShapeType::Cylinder) => { - let shape: Cylinder = seq - .next_element()? - .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; - Arc::new(shape) as Arc - } + Some(ShapeType::Cylinder) => deser::(&mut seq)?, #[cfg(feature = "dim3")] - Some(ShapeType::Cone) => { - let shape: Cone = seq - .next_element()? - .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; - Arc::new(shape) as Arc - } + Some(ShapeType::Cone) => deser::(&mut seq)?, + #[cfg(feature = "dim3")] + Some(ShapeType::RoundedCylinder) => deser::>(&mut seq)?, None => { return Err(serde::de::Error::custom( "found invalid shape type to deserialize", @@ -342,6 +327,18 @@ impl ColliderBuilder { Self::new(ColliderShape::cylinder(half_height, radius)) } + /// Initialize a new collider builder with a rounded cylindrical shape defined by its half-height + /// (along along the y axis), its radius, and its roundedness (the + /// radius of the sphere used for dilating the cylinder). + #[cfg(feature = "dim3")] + pub fn rounded_cylinder(half_height: f32, radius: f32, rounding_radius: f32) -> Self { + Self::new(ColliderShape::rounded_cylinder( + half_height, + radius, + rounding_radius, + )) + } + /// Initialize a new collider builder with a cone shape defined by its half-height /// (along along the y axis) and its basis radius. #[cfg(feature = "dim3")] -- cgit