From 8d925a02ef97844bc937584a9095c1396daeee35 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Sun, 27 Dec 2020 18:14:22 +0100 Subject: Add convex polygons support. --- src/geometry/collider.rs | 92 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index 71f0676..f2ba74b 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -3,13 +3,15 @@ use crate::geometry::InteractionGroups; use crate::math::{AngVector, Isometry, Point, Rotation, Vector}; use cdl::bounding_volume::AABB; use cdl::shape::{ - Ball, Capsule, Cuboid, HalfSpace, HeightField, RoundCuboid, RoundTriangle, Segment, Shape, - ShapeType, ShapeWithBorder, TriMesh, Triangle, + Ball, Capsule, Cuboid, HalfSpace, HeightField, RoundCuboid, RoundShape, RoundTriangle, Segment, + Shape, ShapeType, TriMesh, Triangle, }; #[cfg(feature = "dim3")] use cdl::shape::{ Cone, ConvexPolyhedron, Cylinder, RoundCone, RoundConvexPolyhedron, RoundCylinder, }; +#[cfg(feature = "dim2")] +use cdl::shape::{ConvexPolygon, RoundConvexPolygon}; use na::Point3; use std::ops::Deref; use std::sync::Arc; @@ -44,7 +46,7 @@ impl ColliderShape { /// radius of the sphere used for dilating the cylinder). #[cfg(feature = "dim3")] pub fn round_cylinder(half_height: f32, radius: f32, border_radius: f32) -> Self { - ColliderShape(Arc::new(ShapeWithBorder { + ColliderShape(Arc::new(RoundShape { base_shape: Cylinder::new(half_height, radius), border_radius, })) @@ -55,7 +57,7 @@ impl ColliderShape { /// radius of the sphere used for dilating the cylinder). #[cfg(feature = "dim3")] pub fn round_cone(half_height: f32, radius: f32, border_radius: f32) -> Self { - ColliderShape(Arc::new(ShapeWithBorder { + ColliderShape(Arc::new(RoundShape { base_shape: Cone::new(half_height, radius), border_radius, })) @@ -73,6 +75,14 @@ impl ColliderShape { ColliderShape(Arc::new(Cuboid::new(half_extents))) } + /// Initialize a round cuboid shape defined by its half-extents and border radius. + pub fn round_cuboid(half_extents: Vector, border_radius: f32) -> Self { + ColliderShape(Arc::new(RoundShape { + base_shape: Cuboid::new(half_extents), + border_radius, + })) + } + /// Initialize a capsule shape from its endpoints and radius. pub fn capsule(a: Point, b: Point, radius: f32) -> Self { ColliderShape(Arc::new(Capsule::new(a, b, radius))) @@ -93,9 +103,16 @@ impl ColliderShape { ColliderShape(Arc::new(TriMesh::new(vertices, indices))) } - #[cfg(feature = "dim3")] pub fn convex_hull(points: &[Point]) -> Option { - ConvexPolyhedron::from_convex_hull(points).map(|ch| ColliderShape(Arc::new(ch))) + #[cfg(feature = "dim2")] + return ConvexPolygon::from_convex_hull(points).map(|ch| ColliderShape(Arc::new(ch))); + #[cfg(feature = "dim3")] + return ConvexPolyhedron::from_convex_hull(points).map(|ch| ColliderShape(Arc::new(ch))); + } + + #[cfg(feature = "dim2")] + pub fn convex_polyline(points: Vec>) -> Option { + ConvexPolygon::from_convex_polyline(points).map(|ch| ColliderShape(Arc::new(ch))) } #[cfg(feature = "dim3")] @@ -103,10 +120,27 @@ impl ColliderShape { ConvexPolyhedron::from_convex_mesh(points, indices).map(|ch| ColliderShape(Arc::new(ch))) } - #[cfg(feature = "dim3")] pub fn round_convex_hull(points: &[Point], border_radius: f32) -> Option { - ConvexPolyhedron::from_convex_hull(points).map(|ch| { - ColliderShape(Arc::new(ShapeWithBorder { + #[cfg(feature = "dim2")] + return ConvexPolygon::from_convex_hull(points).map(|ch| { + ColliderShape(Arc::new(RoundShape { + base_shape: ch, + border_radius, + })) + }); + #[cfg(feature = "dim3")] + return ConvexPolyhedron::from_convex_hull(points).map(|ch| { + ColliderShape(Arc::new(RoundShape { + base_shape: ch, + border_radius, + })) + }); + } + + #[cfg(feature = "dim2")] + pub fn round_convex_polyline(points: Vec>, border_radius: f32) -> Option { + ConvexPolygon::from_convex_polyline(points).map(|ch| { + ColliderShape(Arc::new(RoundShape { base_shape: ch, border_radius, })) @@ -120,7 +154,7 @@ impl ColliderShape { border_radius: f32, ) -> Option { ConvexPolyhedron::from_convex_mesh(points, indices).map(|ch| { - ColliderShape(Arc::new(ShapeWithBorder { + ColliderShape(Arc::new(RoundShape { base_shape: ch, border_radius, })) @@ -217,6 +251,12 @@ impl<'de> serde::Deserialize<'de> for ColliderShape { Some(ShapeType::HalfSpace) => deser::(&mut seq)?, Some(ShapeType::RoundCuboid) => deser::(&mut seq)?, Some(ShapeType::RoundTriangle) => deser::(&mut seq)?, + #[cfg(feature = "dim2")] + Some(ShapeType::ConvexPolygon) => deser::(&mut seq)?, + #[cfg(feature = "dim2")] + Some(ShapeType::RoundConvexPolygon) => { + deser::(&mut seq)? + } #[cfg(feature = "dim3")] Some(ShapeType::Cylinder) => deser::(&mut seq)?, #[cfg(feature = "dim3")] @@ -439,6 +479,16 @@ impl ColliderBuilder { Self::new(ColliderShape::cuboid(Vector::new(hx, hy))) } + /// Initialize a new collider builder with a round cuboid shape defined by its half-extents + /// and border radius. + #[cfg(feature = "dim2")] + pub fn round_cuboid(hx: f32, hy: f32, border_radius: f32) -> Self { + Self::new(ColliderShape::round_cuboid( + Vector::new(hx, hy), + border_radius, + )) + } + /// Initialize a new collider builder with a capsule shape aligned with the `x` axis. pub fn capsule_x(half_height: f32, radius: f32) -> Self { let p = Point::from(Vector::x() * half_height); @@ -464,6 +514,16 @@ impl ColliderBuilder { Self::new(ColliderShape::cuboid(Vector::new(hx, hy, hz))) } + /// Initialize a new collider builder with a round cuboid shape defined by its half-extents + /// and border radius. + #[cfg(feature = "dim3")] + pub fn round_cuboid(hx: f32, hy: f32, hz: f32, border_radius: f32) -> Self { + Self::new(ColliderShape::round_cuboid( + Vector::new(hx, hy, hz), + border_radius, + )) + } + /// Initializes a collider builder with a segment shape. pub fn segment(a: Point, b: Point) -> Self { Self::new(ColliderShape::segment(a, b)) @@ -479,16 +539,24 @@ impl ColliderBuilder { Self::new(ColliderShape::trimesh(vertices, indices)) } - #[cfg(feature = "dim3")] pub fn convex_hull(points: &[Point]) -> Option { ColliderShape::convex_hull(points).map(|cp| Self::new(cp)) } - #[cfg(feature = "dim3")] pub fn round_convex_hull(points: &[Point], border_radius: f32) -> Option { ColliderShape::round_convex_hull(points, border_radius).map(|cp| Self::new(cp)) } + #[cfg(feature = "dim2")] + pub fn convex_polyline(points: Vec>) -> Option { + ColliderShape::convex_polyline(points).map(|cp| Self::new(cp)) + } + + #[cfg(feature = "dim2")] + pub fn round_convex_polyline(points: Vec>, border_radius: f32) -> Option { + ColliderShape::round_convex_polyline(points, border_radius).map(|cp| Self::new(cp)) + } + #[cfg(feature = "dim3")] pub fn convex_mesh(points: Vec>, indices: &[usize]) -> Option { ColliderShape::convex_mesh(points, indices).map(|cp| Self::new(cp)) -- cgit