From 9bf1321f8f1d2e116f44c2461a53f302c4ef4171 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Tue, 8 Dec 2020 17:31:49 +0100 Subject: Outsource the contact manifold, SAT, and some shapes. --- src/geometry/collider.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/geometry/collider.rs') diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index c04be35..8154554 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -6,8 +6,8 @@ use crate::geometry::{ #[cfg(feature = "dim3")] use crate::geometry::{Cone, Cylinder, RoundCylinder}; use crate::math::{AngVector, Isometry, Point, Rotation, Vector}; +use buckler::bounding_volume::AABB; use na::Point3; -use ncollide::bounding_volume::AABB; use std::ops::Deref; use std::sync::Arc; @@ -270,11 +270,11 @@ impl Collider { } /// Compute the axis-aligned bounding box of this collider. - pub fn compute_aabb(&self) -> AABB { + pub fn compute_aabb(&self) -> AABB { self.shape.compute_aabb(&self.position) } - // pub(crate) fn compute_aabb_with_prediction(&self) -> AABB { + // pub(crate) fn compute_aabb_with_prediction(&self) -> AABB { // let aabb1 = self.shape.compute_aabb(&self.position); // let aabb2 = self.shape.compute_aabb(&self.predicted_position); // aabb1.merged(&aabb2) -- cgit From cc6d1b973002b4d366bc81ec6bf9e8240ad7b404 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Mon, 14 Dec 2020 15:51:43 +0100 Subject: Outsource the Shape trait, wquadtree, and shape types. --- src/geometry/collider.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src/geometry/collider.rs') diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index 8154554..1275358 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -1,12 +1,13 @@ +use crate::buckler::shape::HalfSpace; use crate::dynamics::{MassProperties, RigidBodyHandle, RigidBodySet}; -use crate::geometry::{ - Ball, Capsule, Cuboid, HeightField, InteractionGroups, Segment, Shape, ShapeType, Triangle, - Trimesh, -}; -#[cfg(feature = "dim3")] -use crate::geometry::{Cone, Cylinder, RoundCylinder}; +use crate::geometry::InteractionGroups; use crate::math::{AngVector, Isometry, Point, Rotation, Vector}; use buckler::bounding_volume::AABB; +use buckler::shape::{ + Ball, Capsule, Cuboid, HeightField, Segment, Shape, ShapeType, TriMesh, Triangle, +}; +#[cfg(feature = "dim3")] +use buckler::shape::{Cone, Cylinder, RoundCylinder}; use na::Point3; use std::ops::Deref; use std::sync::Arc; @@ -77,7 +78,7 @@ impl ColliderShape { /// Initializes a triangle mesh shape defined by its vertex and index buffers. pub fn trimesh(vertices: Vec>, indices: Vec>) -> Self { - ColliderShape(Arc::new(Trimesh::new(vertices, indices))) + ColliderShape(Arc::new(TriMesh::new(vertices, indices))) } /// Initializes an heightfield shape defined by its set of height and a scale @@ -165,8 +166,9 @@ impl<'de> serde::Deserialize<'de> for ColliderShape { Some(ShapeType::Capsule) => deser::(&mut seq)?, Some(ShapeType::Triangle) => deser::(&mut seq)?, Some(ShapeType::Segment) => deser::(&mut seq)?, - Some(ShapeType::Trimesh) => deser::(&mut seq)?, + Some(ShapeType::TriMesh) => deser::(&mut seq)?, Some(ShapeType::HeightField) => deser::(&mut seq)?, + Some(ShapeType::HalfSpace) => deser::(&mut seq)?, #[cfg(feature = "dim3")] Some(ShapeType::Cylinder) => deser::(&mut seq)?, #[cfg(feature = "dim3")] -- cgit From e231bacec608fa5efd24f7a876572927dbd6c9c4 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Thu, 17 Dec 2020 10:24:36 +0100 Subject: Move all the contact manifold computations out of Rapier. --- src/geometry/collider.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/geometry/collider.rs') diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index 1275358..db418a3 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -1,13 +1,13 @@ -use crate::buckler::shape::HalfSpace; use crate::dynamics::{MassProperties, RigidBodyHandle, RigidBodySet}; +use crate::eagl::shape::HalfSpace; use crate::geometry::InteractionGroups; use crate::math::{AngVector, Isometry, Point, Rotation, Vector}; -use buckler::bounding_volume::AABB; -use buckler::shape::{ +use eagl::bounding_volume::AABB; +use eagl::shape::{ Ball, Capsule, Cuboid, HeightField, Segment, Shape, ShapeType, TriMesh, Triangle, }; #[cfg(feature = "dim3")] -use buckler::shape::{Cone, Cylinder, RoundCylinder}; +use eagl::shape::{Cone, Cylinder, RoundCylinder}; use na::Point3; use std::ops::Deref; use std::sync::Arc; -- cgit From 8fe2df126a279a435cc544b150aadf8f7b757868 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Thu, 17 Dec 2020 18:37:16 +0100 Subject: Remove some irrelevant code. --- src/geometry/collider.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/geometry/collider.rs') diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index db418a3..46153ac 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -1,13 +1,13 @@ +use crate::cdl::shape::HalfSpace; use crate::dynamics::{MassProperties, RigidBodyHandle, RigidBodySet}; -use crate::eagl::shape::HalfSpace; use crate::geometry::InteractionGroups; use crate::math::{AngVector, Isometry, Point, Rotation, Vector}; -use eagl::bounding_volume::AABB; -use eagl::shape::{ +use cdl::bounding_volume::AABB; +use cdl::shape::{ Ball, Capsule, Cuboid, HeightField, Segment, Shape, ShapeType, TriMesh, Triangle, }; #[cfg(feature = "dim3")] -use eagl::shape::{Cone, Cylinder, RoundCylinder}; +use cdl::shape::{Cone, Cylinder, RoundCylinder}; use na::Point3; use std::ops::Deref; use std::sync::Arc; -- cgit From 486fbd972f7951edf2d576c7c6bcbd02dcc28011 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Mon, 21 Dec 2020 16:01:22 +0100 Subject: Add example for 3D convex polyhedron. --- src/geometry/collider.rs | 106 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 7 deletions(-) (limited to 'src/geometry/collider.rs') diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index 46153ac..71f0676 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -1,13 +1,15 @@ -use crate::cdl::shape::HalfSpace; use crate::dynamics::{MassProperties, RigidBodyHandle, RigidBodySet}; use crate::geometry::InteractionGroups; use crate::math::{AngVector, Isometry, Point, Rotation, Vector}; use cdl::bounding_volume::AABB; use cdl::shape::{ - Ball, Capsule, Cuboid, HeightField, Segment, Shape, ShapeType, TriMesh, Triangle, + Ball, Capsule, Cuboid, HalfSpace, HeightField, RoundCuboid, RoundTriangle, Segment, Shape, + ShapeType, ShapeWithBorder, TriMesh, Triangle, }; #[cfg(feature = "dim3")] -use cdl::shape::{Cone, Cylinder, RoundCylinder}; +use cdl::shape::{ + Cone, ConvexPolyhedron, Cylinder, RoundCone, RoundConvexPolyhedron, RoundCylinder, +}; use na::Point3; use std::ops::Deref; use std::sync::Arc; @@ -42,11 +44,21 @@ 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(RoundCylinder::new( - half_height, - radius, + ColliderShape(Arc::new(ShapeWithBorder { + base_shape: Cylinder::new(half_height, radius), + border_radius, + })) + } + + /// Initialize a rounded cone 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 round_cone(half_height: f32, radius: f32, border_radius: f32) -> Self { + ColliderShape(Arc::new(ShapeWithBorder { + base_shape: Cone::new(half_height, radius), border_radius, - ))) + })) } /// Initialize a cone shape defined by its half-height @@ -81,6 +93,40 @@ 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 = "dim3")] + pub fn convex_mesh(points: Vec>, indices: &[usize]) -> Option { + 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 { + base_shape: ch, + border_radius, + })) + }) + } + + #[cfg(feature = "dim3")] + pub fn round_convex_mesh( + points: Vec>, + indices: &[usize], + border_radius: f32, + ) -> Option { + ConvexPolyhedron::from_convex_mesh(points, indices).map(|ch| { + ColliderShape(Arc::new(ShapeWithBorder { + base_shape: ch, + border_radius, + })) + }) + } + /// Initializes an heightfield shape defined by its set of height and a scale /// factor along each coordinate axis. #[cfg(feature = "dim2")] @@ -169,12 +215,22 @@ impl<'de> serde::Deserialize<'de> for ColliderShape { Some(ShapeType::TriMesh) => deser::(&mut seq)?, Some(ShapeType::HeightField) => deser::(&mut seq)?, Some(ShapeType::HalfSpace) => deser::(&mut seq)?, + Some(ShapeType::RoundCuboid) => deser::(&mut seq)?, + Some(ShapeType::RoundTriangle) => deser::(&mut seq)?, #[cfg(feature = "dim3")] Some(ShapeType::Cylinder) => deser::(&mut seq)?, #[cfg(feature = "dim3")] + Some(ShapeType::ConvexPolyhedron) => deser::(&mut seq)?, + #[cfg(feature = "dim3")] Some(ShapeType::Cone) => deser::(&mut seq)?, #[cfg(feature = "dim3")] Some(ShapeType::RoundCylinder) => deser::(&mut seq)?, + #[cfg(feature = "dim3")] + Some(ShapeType::RoundCone) => deser::(&mut seq)?, + #[cfg(feature = "dim3")] + Some(ShapeType::RoundConvexPolyhedron) => { + deser::(&mut seq)? + } None => { return Err(serde::de::Error::custom( "found invalid shape type to deserialize", @@ -365,6 +421,18 @@ impl ColliderBuilder { Self::new(ColliderShape::cone(half_height, radius)) } + /// Initialize a new collider builder with a rounded cone 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 round_cone(half_height: f32, radius: f32, border_radius: f32) -> Self { + Self::new(ColliderShape::round_cone( + half_height, + radius, + border_radius, + )) + } + /// Initialize a new collider builder with a cuboid shape defined by its half-extents. #[cfg(feature = "dim2")] pub fn cuboid(hx: f32, hy: f32) -> Self { @@ -411,6 +479,30 @@ 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 = "dim3")] + pub fn convex_mesh(points: Vec>, indices: &[usize]) -> Option { + ColliderShape::convex_mesh(points, indices).map(|cp| Self::new(cp)) + } + + #[cfg(feature = "dim3")] + pub fn round_convex_mesh( + points: Vec>, + indices: &[usize], + border_radius: f32, + ) -> Option { + ColliderShape::round_convex_mesh(points, indices, border_radius).map(|cp| Self::new(cp)) + } + /// Initializes a collider builder with a heightfield shape defined by its set of height and a scale /// factor along each coordinate axis. #[cfg(feature = "dim2")] -- cgit 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/geometry/collider.rs') 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 From 94c67a0c31e9da373c3aca3560dc9accc3308a7a Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Mon, 28 Dec 2020 18:12:33 +0100 Subject: Support compound shapes. --- src/geometry/collider.rs | 202 ++++++++++++++++++++++++++--------------------- 1 file changed, 111 insertions(+), 91 deletions(-) (limited to 'src/geometry/collider.rs') diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index f2ba74b..edf4dbb 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -1,10 +1,10 @@ use crate::dynamics::{MassProperties, RigidBodyHandle, RigidBodySet}; use crate::geometry::InteractionGroups; -use crate::math::{AngVector, Isometry, Point, Rotation, Vector}; +use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector}; use cdl::bounding_volume::AABB; use cdl::shape::{ - Ball, Capsule, Cuboid, HalfSpace, HeightField, RoundCuboid, RoundShape, RoundTriangle, Segment, - Shape, ShapeType, TriMesh, Triangle, + Ball, Capsule, Compound, Cuboid, HalfSpace, HeightField, RoundCuboid, RoundShape, + RoundTriangle, Segment, Shape, ShapeType, TriMesh, Triangle, }; #[cfg(feature = "dim3")] use cdl::shape::{ @@ -29,15 +29,22 @@ impl Deref for ColliderShape { } impl ColliderShape { + /// Initialize a compound shape defined by its subshapes. + pub fn compound(shapes: Vec<(Isometry, ColliderShape)>) -> Self { + let raw_shapes = shapes.into_iter().map(|s| (s.0, s.1 .0)).collect(); + let compound = Compound::new(raw_shapes); + ColliderShape(Arc::new(compound)) + } + /// Initialize a ball shape defined by its radius. - pub fn ball(radius: f32) -> Self { + pub fn ball(radius: Real) -> Self { ColliderShape(Arc::new(Ball::new(radius))) } /// Initialize a cylindrical shape defined by its half-height /// (along along the y axis) and its radius. #[cfg(feature = "dim3")] - pub fn cylinder(half_height: f32, radius: f32) -> Self { + pub fn cylinder(half_height: Real, radius: Real) -> Self { ColliderShape(Arc::new(Cylinder::new(half_height, radius))) } @@ -45,7 +52,7 @@ impl ColliderShape { /// (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 round_cylinder(half_height: f32, radius: f32, border_radius: f32) -> Self { + pub fn round_cylinder(half_height: Real, radius: Real, border_radius: Real) -> Self { ColliderShape(Arc::new(RoundShape { base_shape: Cylinder::new(half_height, radius), border_radius, @@ -56,7 +63,7 @@ impl ColliderShape { /// (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 round_cone(half_height: f32, radius: f32, border_radius: f32) -> Self { + pub fn round_cone(half_height: Real, radius: Real, border_radius: Real) -> Self { ColliderShape(Arc::new(RoundShape { base_shape: Cone::new(half_height, radius), border_radius, @@ -66,44 +73,61 @@ impl ColliderShape { /// Initialize a cone shape defined by its half-height /// (along along the y axis) and its basis radius. #[cfg(feature = "dim3")] - pub fn cone(half_height: f32, radius: f32) -> Self { + pub fn cone(half_height: Real, radius: Real) -> Self { ColliderShape(Arc::new(Cone::new(half_height, radius))) } /// Initialize a cuboid shape defined by its half-extents. - pub fn cuboid(half_extents: Vector) -> Self { - ColliderShape(Arc::new(Cuboid::new(half_extents))) + #[cfg(feature = "dim2")] + pub fn cuboid(hx: Real, hy: Real) -> Self { + ColliderShape(Arc::new(Cuboid::new(Vector::new(hx, hy)))) + } + + /// Initialize a round cuboid shape defined by its half-extents and border radius. + #[cfg(feature = "dim2")] + pub fn round_cuboid(hx: Real, hy: Real, border_radius: Real) -> Self { + ColliderShape(Arc::new(RoundShape { + base_shape: Cuboid::new(Vector::new(hx, hy)), + border_radius, + })) + } + + /// Initialize a cuboid shape defined by its half-extents. + #[cfg(feature = "dim3")] + pub fn cuboid(hx: Real, hy: Real, hz: Real) -> Self { + ColliderShape(Arc::new(Cuboid::new(Vector::new(hx, hy, hz)))) } /// Initialize a round cuboid shape defined by its half-extents and border radius. - pub fn round_cuboid(half_extents: Vector, border_radius: f32) -> Self { + #[cfg(feature = "dim3")] + pub fn round_cuboid(hx: Real, hy: Real, hz: Real, border_radius: Real) -> Self { ColliderShape(Arc::new(RoundShape { - base_shape: Cuboid::new(half_extents), + base_shape: Cuboid::new(Vector::new(hx, hy, hz)), border_radius, })) } /// Initialize a capsule shape from its endpoints and radius. - pub fn capsule(a: Point, b: Point, radius: f32) -> Self { + pub fn capsule(a: Point, b: Point, radius: Real) -> Self { ColliderShape(Arc::new(Capsule::new(a, b, radius))) } /// Initialize a segment shape from its endpoints. - pub fn segment(a: Point, b: Point) -> Self { + pub fn segment(a: Point, b: Point) -> Self { ColliderShape(Arc::new(Segment::new(a, b))) } /// Initializes a triangle shape. - pub fn triangle(a: Point, b: Point, c: Point) -> Self { + pub fn triangle(a: Point, b: Point, c: Point) -> Self { ColliderShape(Arc::new(Triangle::new(a, b, c))) } /// Initializes a triangle mesh shape defined by its vertex and index buffers. - pub fn trimesh(vertices: Vec>, indices: Vec>) -> Self { + pub fn trimesh(vertices: Vec>, indices: Vec>) -> Self { ColliderShape(Arc::new(TriMesh::new(vertices, indices))) } - pub fn convex_hull(points: &[Point]) -> Option { + pub fn convex_hull(points: &[Point]) -> Option { #[cfg(feature = "dim2")] return ConvexPolygon::from_convex_hull(points).map(|ch| ColliderShape(Arc::new(ch))); #[cfg(feature = "dim3")] @@ -111,16 +135,16 @@ impl ColliderShape { } #[cfg(feature = "dim2")] - pub fn convex_polyline(points: Vec>) -> Option { + pub fn convex_polyline(points: Vec>) -> Option { ConvexPolygon::from_convex_polyline(points).map(|ch| ColliderShape(Arc::new(ch))) } #[cfg(feature = "dim3")] - pub fn convex_mesh(points: Vec>, indices: &[usize]) -> Option { + pub fn convex_mesh(points: Vec>, indices: &[usize]) -> Option { ConvexPolyhedron::from_convex_mesh(points, indices).map(|ch| ColliderShape(Arc::new(ch))) } - pub fn round_convex_hull(points: &[Point], border_radius: f32) -> Option { + pub fn round_convex_hull(points: &[Point], border_radius: Real) -> Option { #[cfg(feature = "dim2")] return ConvexPolygon::from_convex_hull(points).map(|ch| { ColliderShape(Arc::new(RoundShape { @@ -138,7 +162,7 @@ impl ColliderShape { } #[cfg(feature = "dim2")] - pub fn round_convex_polyline(points: Vec>, border_radius: f32) -> Option { + pub fn round_convex_polyline(points: Vec>, border_radius: Real) -> Option { ConvexPolygon::from_convex_polyline(points).map(|ch| { ColliderShape(Arc::new(RoundShape { base_shape: ch, @@ -149,9 +173,9 @@ impl ColliderShape { #[cfg(feature = "dim3")] pub fn round_convex_mesh( - points: Vec>, + points: Vec>, indices: &[usize], - border_radius: f32, + border_radius: Real, ) -> Option { ConvexPolyhedron::from_convex_mesh(points, indices).map(|ch| { ColliderShape(Arc::new(RoundShape { @@ -164,14 +188,14 @@ impl ColliderShape { /// Initializes an heightfield shape defined by its set of height and a scale /// factor along each coordinate axis. #[cfg(feature = "dim2")] - pub fn heightfield(heights: na::DVector, scale: Vector) -> Self { + pub fn heightfield(heights: na::DVector, scale: Vector) -> Self { ColliderShape(Arc::new(HeightField::new(heights, scale))) } /// Initializes an heightfield shape on the x-z plane defined by its set of height and a scale /// factor along each coordinate axis. #[cfg(feature = "dim3")] - pub fn heightfield(heights: na::DMatrix, scale: Vector) -> Self { + pub fn heightfield(heights: na::DMatrix, scale: Vector) -> Self { ColliderShape(Arc::new(HeightField::new(heights, scale))) } } @@ -235,13 +259,6 @@ impl<'de> serde::Deserialize<'de> for ColliderShape { let shape = match ShapeType::from_i32(tag) { Some(ShapeType::Ball) => deser::(&mut seq)?, - Some(ShapeType::Polygon) => { - unimplemented!() - // let shape: Polygon = 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)?, @@ -271,6 +288,11 @@ impl<'de> serde::Deserialize<'de> for ColliderShape { Some(ShapeType::RoundConvexPolyhedron) => { deser::(&mut seq)? } + Some(ShapeType::Compound) => { + return Err(serde::de::Error::custom( + "found invalid shape type to deserialize", + )) + } None => { return Err(serde::de::Error::custom( "found invalid shape type to deserialize", @@ -293,16 +315,16 @@ impl<'de> serde::Deserialize<'de> for ColliderShape { /// To build a new collider, use the `ColliderBuilder` structure. pub struct Collider { shape: ColliderShape, - density: f32, + density: Real, is_sensor: bool, pub(crate) parent: RigidBodyHandle, - pub(crate) delta: Isometry, - pub(crate) position: Isometry, - pub(crate) predicted_position: Isometry, + pub(crate) delta: Isometry, + pub(crate) position: Isometry, + pub(crate) predicted_position: Isometry, /// The friction coefficient of this collider. - pub friction: f32, + pub friction: Real, /// The restitution coefficient of this collider. - pub restitution: f32, + pub restitution: Real, pub(crate) collision_groups: InteractionGroups, pub(crate) solver_groups: InteractionGroups, pub(crate) proxy_index: usize, @@ -327,23 +349,23 @@ impl Collider { } #[doc(hidden)] - pub fn set_position_debug(&mut self, position: Isometry) { + pub fn set_position_debug(&mut self, position: Isometry) { self.position = position; } /// The position of this collider expressed in the local-space of the rigid-body it is attached to. #[deprecated(note = "use `.position_wrt_parent()` instead.")] - pub fn delta(&self) -> &Isometry { + pub fn delta(&self) -> &Isometry { &self.delta } /// The world-space position of this collider. - pub fn position(&self) -> &Isometry { + pub fn position(&self) -> &Isometry { &self.position } /// The position of this collider wrt the body it is attached to. - pub fn position_wrt_parent(&self) -> &Isometry { + pub fn position_wrt_parent(&self) -> &Isometry { &self.delta } @@ -358,7 +380,7 @@ impl Collider { } /// The density of this collider. - pub fn density(&self) -> f32 { + pub fn density(&self) -> Real { self.density } @@ -391,13 +413,13 @@ pub struct ColliderBuilder { /// The shape of the collider to be built. pub shape: ColliderShape, /// The density of the collider to be built. - density: Option, + density: Option, /// The friction coefficient of the collider to be built. - pub friction: f32, + pub friction: Real, /// The restitution coefficient of the collider to be built. - pub restitution: f32, + pub restitution: Real, /// The position of this collider relative to the local frame of the rigid-body it is attached to. - pub delta: Isometry, + pub delta: Isometry, /// Is this collider a sensor? pub is_sensor: bool, /// The user-data of the collider being built. @@ -425,20 +447,24 @@ impl ColliderBuilder { } /// The density of the collider being built. - pub fn get_density(&self) -> f32 { + pub fn get_density(&self) -> Real { let default_density = if self.is_sensor { 0.0 } else { 1.0 }; self.density.unwrap_or(default_density) } + pub fn compound(shapes: Vec<(Isometry, ColliderShape)>) -> Self { + Self::new(ColliderShape::compound(shapes)) + } + /// Initialize a new collider builder with a ball shape defined by its radius. - pub fn ball(radius: f32) -> Self { + pub fn ball(radius: Real) -> Self { Self::new(ColliderShape::ball(radius)) } /// Initialize a new collider builder with a cylindrical shape defined by its half-height /// (along along the y axis) and its radius. #[cfg(feature = "dim3")] - pub fn cylinder(half_height: f32, radius: f32) -> Self { + pub fn cylinder(half_height: Real, radius: Real) -> Self { Self::new(ColliderShape::cylinder(half_height, radius)) } @@ -446,7 +472,7 @@ impl ColliderBuilder { /// (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 round_cylinder(half_height: f32, radius: f32, border_radius: f32) -> Self { + pub fn round_cylinder(half_height: Real, radius: Real, border_radius: Real) -> Self { Self::new(ColliderShape::round_cylinder( half_height, radius, @@ -457,7 +483,7 @@ impl ColliderBuilder { /// 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")] - pub fn cone(half_height: f32, radius: f32) -> Self { + pub fn cone(half_height: Real, radius: Real) -> Self { Self::new(ColliderShape::cone(half_height, radius)) } @@ -465,7 +491,7 @@ impl ColliderBuilder { /// (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 round_cone(half_height: f32, radius: f32, border_radius: f32) -> Self { + pub fn round_cone(half_height: Real, radius: Real, border_radius: Real) -> Self { Self::new(ColliderShape::round_cone( half_height, radius, @@ -475,98 +501,92 @@ impl ColliderBuilder { /// Initialize a new collider builder with a cuboid shape defined by its half-extents. #[cfg(feature = "dim2")] - pub fn cuboid(hx: f32, hy: f32) -> Self { - Self::new(ColliderShape::cuboid(Vector::new(hx, hy))) + pub fn cuboid(hx: Real, hy: Real) -> Self { + Self::new(ColliderShape::cuboid(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, - )) + pub fn round_cuboid(hx: Real, hy: Real, border_radius: Real) -> Self { + Self::new(ColliderShape::round_cuboid(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 { + pub fn capsule_x(half_height: Real, radius: Real) -> Self { let p = Point::from(Vector::x() * half_height); Self::new(ColliderShape::capsule(-p, p, radius)) } /// Initialize a new collider builder with a capsule shape aligned with the `y` axis. - pub fn capsule_y(half_height: f32, radius: f32) -> Self { + pub fn capsule_y(half_height: Real, radius: Real) -> Self { let p = Point::from(Vector::y() * half_height); Self::new(ColliderShape::capsule(-p, p, radius)) } /// Initialize a new collider builder with a capsule shape aligned with the `z` axis. #[cfg(feature = "dim3")] - pub fn capsule_z(half_height: f32, radius: f32) -> Self { + pub fn capsule_z(half_height: Real, radius: Real) -> Self { let p = Point::from(Vector::z() * half_height); Self::new(ColliderShape::capsule(-p, p, radius)) } /// Initialize a new collider builder with a cuboid shape defined by its half-extents. #[cfg(feature = "dim3")] - pub fn cuboid(hx: f32, hy: f32, hz: f32) -> Self { - Self::new(ColliderShape::cuboid(Vector::new(hx, hy, hz))) + pub fn cuboid(hx: Real, hy: Real, hz: Real) -> Self { + Self::new(ColliderShape::cuboid(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, - )) + pub fn round_cuboid(hx: Real, hy: Real, hz: Real, border_radius: Real) -> Self { + Self::new(ColliderShape::round_cuboid(hx, hy, hz, border_radius)) } /// Initializes a collider builder with a segment shape. - pub fn segment(a: Point, b: Point) -> Self { + pub fn segment(a: Point, b: Point) -> Self { Self::new(ColliderShape::segment(a, b)) } /// Initializes a collider builder with a triangle shape. - pub fn triangle(a: Point, b: Point, c: Point) -> Self { + pub fn triangle(a: Point, b: Point, c: Point) -> Self { Self::new(ColliderShape::triangle(a, b, c)) } /// Initializes a collider builder with a triangle mesh shape defined by its vertex and index buffers. - pub fn trimesh(vertices: Vec>, indices: Vec>) -> Self { + pub fn trimesh(vertices: Vec>, indices: Vec>) -> Self { Self::new(ColliderShape::trimesh(vertices, indices)) } - pub fn convex_hull(points: &[Point]) -> Option { + pub fn convex_hull(points: &[Point]) -> Option { ColliderShape::convex_hull(points).map(|cp| Self::new(cp)) } - pub fn round_convex_hull(points: &[Point], border_radius: f32) -> Option { + pub fn round_convex_hull(points: &[Point], border_radius: Real) -> Option { ColliderShape::round_convex_hull(points, border_radius).map(|cp| Self::new(cp)) } #[cfg(feature = "dim2")] - pub fn convex_polyline(points: Vec>) -> Option { + 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 { + pub fn round_convex_polyline(points: Vec>, border_radius: Real) -> 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 { + pub fn convex_mesh(points: Vec>, indices: &[usize]) -> Option { ColliderShape::convex_mesh(points, indices).map(|cp| Self::new(cp)) } #[cfg(feature = "dim3")] pub fn round_convex_mesh( - points: Vec>, + points: Vec>, indices: &[usize], - border_radius: f32, + border_radius: Real, ) -> Option { ColliderShape::round_convex_mesh(points, indices, border_radius).map(|cp| Self::new(cp)) } @@ -574,19 +594,19 @@ impl ColliderBuilder { /// Initializes a collider builder with a heightfield shape defined by its set of height and a scale /// factor along each coordinate axis. #[cfg(feature = "dim2")] - pub fn heightfield(heights: na::DVector, scale: Vector) -> Self { + pub fn heightfield(heights: na::DVector, scale: Vector) -> Self { Self::new(ColliderShape::heightfield(heights, scale)) } /// Initializes a collider builder with a heightfield shape defined by its set of height and a scale /// factor along each coordinate axis. #[cfg(feature = "dim3")] - pub fn heightfield(heights: na::DMatrix, scale: Vector) -> Self { + pub fn heightfield(heights: na::DMatrix, scale: Vector) -> Self { Self::new(ColliderShape::heightfield(heights, scale)) } /// The default friction coefficient used by the collider builder. - pub fn default_friction() -> f32 { + pub fn default_friction() -> Real { 0.5 } @@ -621,19 +641,19 @@ impl ColliderBuilder { } /// Sets the friction coefficient of the collider this builder will build. - pub fn friction(mut self, friction: f32) -> Self { + pub fn friction(mut self, friction: Real) -> Self { self.friction = friction; self } /// Sets the restitution coefficient of the collider this builder will build. - pub fn restitution(mut self, restitution: f32) -> Self { + pub fn restitution(mut self, restitution: Real) -> Self { self.restitution = restitution; self } /// Sets the density of the collider this builder will build. - pub fn density(mut self, density: f32) -> Self { + pub fn density(mut self, density: Real) -> Self { self.density = Some(density); self } @@ -641,7 +661,7 @@ impl ColliderBuilder { /// Sets the initial translation of the collider to be created, /// relative to the rigid-body it is attached to. #[cfg(feature = "dim2")] - pub fn translation(mut self, x: f32, y: f32) -> Self { + pub fn translation(mut self, x: Real, y: Real) -> Self { self.delta.translation.x = x; self.delta.translation.y = y; self @@ -650,7 +670,7 @@ impl ColliderBuilder { /// Sets the initial translation of the collider to be created, /// relative to the rigid-body it is attached to. #[cfg(feature = "dim3")] - pub fn translation(mut self, x: f32, y: f32, z: f32) -> Self { + pub fn translation(mut self, x: Real, y: Real, z: Real) -> Self { self.delta.translation.x = x; self.delta.translation.y = y; self.delta.translation.z = z; @@ -659,21 +679,21 @@ impl ColliderBuilder { /// Sets the initial orientation of the collider to be created, /// relative to the rigid-body it is attached to. - pub fn rotation(mut self, angle: AngVector) -> Self { + pub fn rotation(mut self, angle: AngVector) -> Self { self.delta.rotation = Rotation::new(angle); self } /// Sets the initial position (translation and orientation) of the collider to be created, /// relative to the rigid-body it is attached to. - pub fn position(mut self, pos: Isometry) -> Self { + pub fn position(mut self, pos: Isometry) -> Self { self.delta = pos; self } /// Set the position of this collider in the local-space of the rigid-body it is attached to. #[deprecated(note = "Use `.position` instead.")] - pub fn delta(mut self, delta: Isometry) -> Self { + pub fn delta(mut self, delta: Isometry) -> Self { self.delta = delta; self } -- cgit From e2006599a8fa90090393ff4fed326ee78fd7c0b7 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Wed, 20 Jan 2021 15:15:03 +0100 Subject: Add 3D convex decomposition example. --- src/geometry/collider.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/geometry/collider.rs') diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index edf4dbb..8533c81 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -140,7 +140,7 @@ impl ColliderShape { } #[cfg(feature = "dim3")] - pub fn convex_mesh(points: Vec>, indices: &[usize]) -> Option { + pub fn convex_mesh(points: Vec>, indices: &[Point3]) -> Option { ConvexPolyhedron::from_convex_mesh(points, indices).map(|ch| ColliderShape(Arc::new(ch))) } @@ -174,7 +174,7 @@ impl ColliderShape { #[cfg(feature = "dim3")] pub fn round_convex_mesh( points: Vec>, - indices: &[usize], + indices: &[Point], border_radius: Real, ) -> Option { ConvexPolyhedron::from_convex_mesh(points, indices).map(|ch| { @@ -578,14 +578,14 @@ impl ColliderBuilder { } #[cfg(feature = "dim3")] - pub fn convex_mesh(points: Vec>, indices: &[usize]) -> Option { + pub fn convex_mesh(points: Vec>, indices: &[Point3]) -> Option { ColliderShape::convex_mesh(points, indices).map(|cp| Self::new(cp)) } #[cfg(feature = "dim3")] pub fn round_convex_mesh( points: Vec>, - indices: &[usize], + indices: &[Point], border_radius: Real, ) -> Option { ColliderShape::round_convex_mesh(points, indices, border_radius).map(|cp| Self::new(cp)) -- cgit From 28b7866aee68ca844406bea4761d630a7913188d Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Wed, 20 Jan 2021 15:40:00 +0100 Subject: Switch to [u32; DIM] instead of Point for element indices. --- src/geometry/collider.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'src/geometry/collider.rs') diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index 8533c81..96fcbf9 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -12,7 +12,6 @@ use cdl::shape::{ }; #[cfg(feature = "dim2")] use cdl::shape::{ConvexPolygon, RoundConvexPolygon}; -use na::Point3; use std::ops::Deref; use std::sync::Arc; @@ -123,7 +122,7 @@ impl ColliderShape { } /// Initializes a triangle mesh shape defined by its vertex and index buffers. - pub fn trimesh(vertices: Vec>, indices: Vec>) -> Self { + pub fn trimesh(vertices: Vec>, indices: Vec<[u32; 3]>) -> Self { ColliderShape(Arc::new(TriMesh::new(vertices, indices))) } @@ -140,7 +139,7 @@ impl ColliderShape { } #[cfg(feature = "dim3")] - pub fn convex_mesh(points: Vec>, indices: &[Point3]) -> Option { + pub fn convex_mesh(points: Vec>, indices: &[[u32; 3]]) -> Option { ConvexPolyhedron::from_convex_mesh(points, indices).map(|ch| ColliderShape(Arc::new(ch))) } @@ -174,7 +173,7 @@ impl ColliderShape { #[cfg(feature = "dim3")] pub fn round_convex_mesh( points: Vec>, - indices: &[Point], + indices: &[[u32; 3]], border_radius: Real, ) -> Option { ConvexPolyhedron::from_convex_mesh(points, indices).map(|ch| { @@ -555,7 +554,7 @@ impl ColliderBuilder { } /// Initializes a collider builder with a triangle mesh shape defined by its vertex and index buffers. - pub fn trimesh(vertices: Vec>, indices: Vec>) -> Self { + pub fn trimesh(vertices: Vec>, indices: Vec<[u32; 3]>) -> Self { Self::new(ColliderShape::trimesh(vertices, indices)) } @@ -578,14 +577,14 @@ impl ColliderBuilder { } #[cfg(feature = "dim3")] - pub fn convex_mesh(points: Vec>, indices: &[Point3]) -> Option { + pub fn convex_mesh(points: Vec>, indices: &[[u32; 3]]) -> Option { ColliderShape::convex_mesh(points, indices).map(|cp| Self::new(cp)) } #[cfg(feature = "dim3")] pub fn round_convex_mesh( points: Vec>, - indices: &[Point], + indices: &[[u32; 3]], border_radius: Real, ) -> Option { ColliderShape::round_convex_mesh(points, indices, border_radius).map(|cp| Self::new(cp)) -- cgit From 0ade350b5f4b6e7c0c4116e1f4f2b30ab86b7e52 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Wed, 20 Jan 2021 16:33:42 +0100 Subject: Use newtypes for collider, rigid-body and joint handles. --- src/geometry/collider.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/geometry/collider.rs') diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index 96fcbf9..a4de108 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -1,4 +1,4 @@ -use crate::dynamics::{MassProperties, RigidBodyHandle, RigidBodySet}; +use crate::dynamics::{MassProperties, RigidBodyHandle}; use crate::geometry::InteractionGroups; use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector}; use cdl::bounding_volume::AABB; @@ -333,7 +333,7 @@ pub struct Collider { impl Collider { pub(crate) fn reset_internal_references(&mut self) { - self.parent = RigidBodySet::invalid_handle(); + self.parent = RigidBodyHandle::invalid(); self.proxy_index = crate::INVALID_USIZE; } @@ -708,7 +708,7 @@ impl ColliderBuilder { restitution: self.restitution, delta: self.delta, is_sensor: self.is_sensor, - parent: RigidBodySet::invalid_handle(), + parent: RigidBodyHandle::invalid(), position: Isometry::identity(), predicted_position: Isometry::identity(), proxy_index: crate::INVALID_USIZE, -- cgit From 98d3980db7a9803f4ee965237599a87771a417d1 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Thu, 21 Jan 2021 16:03:27 +0100 Subject: Allow several rules for combining friction/restitution coefficients. --- src/geometry/collider.rs | 344 +++++++---------------------------------------- 1 file changed, 51 insertions(+), 293 deletions(-) (limited to 'src/geometry/collider.rs') diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index a4de108..c5f53f7 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -1,309 +1,44 @@ -use crate::dynamics::{MassProperties, RigidBodyHandle}; -use crate::geometry::InteractionGroups; +use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle}; +use crate::geometry::{ColliderShape, InteractionGroups}; use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector}; use cdl::bounding_volume::AABB; -use cdl::shape::{ - Ball, Capsule, Compound, Cuboid, HalfSpace, HeightField, RoundCuboid, RoundShape, - RoundTriangle, Segment, Shape, ShapeType, TriMesh, Triangle, -}; -#[cfg(feature = "dim3")] -use cdl::shape::{ - Cone, ConvexPolyhedron, Cylinder, RoundCone, RoundConvexPolyhedron, RoundCylinder, -}; +use cdl::shape::Shape; #[cfg(feature = "dim2")] use cdl::shape::{ConvexPolygon, RoundConvexPolygon}; -use std::ops::Deref; -use std::sync::Arc; -// TODO: move this to its own file. -/// The shape of a collider. -#[derive(Clone)] -pub struct ColliderShape(pub Arc); - -impl Deref for ColliderShape { - type Target = dyn Shape; - fn deref(&self) -> &dyn Shape { - &*self.0 +bitflags::bitflags! { + #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] + /// Flags affecting the behavior of the constraints solver for a given contact manifold. + pub(crate) struct ColliderFlags: u8 { + const SENSOR = 1 << 0; + const FRICTION_COMBINE_RULE_01 = 1 << 1; + const FRICTION_COMBINE_RULE_10 = 1 << 2; + const RESTITUTION_COMBINE_RULE_01 = 1 << 3; + const RESTITUTION_COMBINE_RULE_10 = 1 << 4; } } -impl ColliderShape { - /// Initialize a compound shape defined by its subshapes. - pub fn compound(shapes: Vec<(Isometry, ColliderShape)>) -> Self { - let raw_shapes = shapes.into_iter().map(|s| (s.0, s.1 .0)).collect(); - let compound = Compound::new(raw_shapes); - ColliderShape(Arc::new(compound)) - } - - /// Initialize a ball shape defined by its radius. - pub fn ball(radius: Real) -> Self { - ColliderShape(Arc::new(Ball::new(radius))) - } - - /// Initialize a cylindrical shape defined by its half-height - /// (along along the y axis) and its radius. - #[cfg(feature = "dim3")] - pub fn cylinder(half_height: Real, radius: Real) -> Self { - 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 round_cylinder(half_height: Real, radius: Real, border_radius: Real) -> Self { - ColliderShape(Arc::new(RoundShape { - base_shape: Cylinder::new(half_height, radius), - border_radius, - })) - } - - /// Initialize a rounded cone 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 round_cone(half_height: Real, radius: Real, border_radius: Real) -> Self { - ColliderShape(Arc::new(RoundShape { - base_shape: Cone::new(half_height, radius), - border_radius, - })) - } - - /// Initialize a cone shape defined by its half-height - /// (along along the y axis) and its basis radius. - #[cfg(feature = "dim3")] - pub fn cone(half_height: Real, radius: Real) -> Self { - ColliderShape(Arc::new(Cone::new(half_height, radius))) - } - - /// Initialize a cuboid shape defined by its half-extents. - #[cfg(feature = "dim2")] - pub fn cuboid(hx: Real, hy: Real) -> Self { - ColliderShape(Arc::new(Cuboid::new(Vector::new(hx, hy)))) - } - - /// Initialize a round cuboid shape defined by its half-extents and border radius. - #[cfg(feature = "dim2")] - pub fn round_cuboid(hx: Real, hy: Real, border_radius: Real) -> Self { - ColliderShape(Arc::new(RoundShape { - base_shape: Cuboid::new(Vector::new(hx, hy)), - border_radius, - })) - } - - /// Initialize a cuboid shape defined by its half-extents. - #[cfg(feature = "dim3")] - pub fn cuboid(hx: Real, hy: Real, hz: Real) -> Self { - ColliderShape(Arc::new(Cuboid::new(Vector::new(hx, hy, hz)))) - } - - /// Initialize a round cuboid shape defined by its half-extents and border radius. - #[cfg(feature = "dim3")] - pub fn round_cuboid(hx: Real, hy: Real, hz: Real, border_radius: Real) -> Self { - ColliderShape(Arc::new(RoundShape { - base_shape: Cuboid::new(Vector::new(hx, hy, hz)), - border_radius, - })) - } - - /// Initialize a capsule shape from its endpoints and radius. - pub fn capsule(a: Point, b: Point, radius: Real) -> Self { - ColliderShape(Arc::new(Capsule::new(a, b, radius))) - } - - /// Initialize a segment shape from its endpoints. - pub fn segment(a: Point, b: Point) -> Self { - ColliderShape(Arc::new(Segment::new(a, b))) - } - - /// Initializes a triangle shape. - pub fn triangle(a: Point, b: Point, c: Point) -> Self { - ColliderShape(Arc::new(Triangle::new(a, b, c))) - } - - /// Initializes a triangle mesh shape defined by its vertex and index buffers. - pub fn trimesh(vertices: Vec>, indices: Vec<[u32; 3]>) -> Self { - ColliderShape(Arc::new(TriMesh::new(vertices, indices))) - } - - pub fn convex_hull(points: &[Point]) -> Option { - #[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")] - pub fn convex_mesh(points: Vec>, indices: &[[u32; 3]]) -> Option { - ConvexPolyhedron::from_convex_mesh(points, indices).map(|ch| ColliderShape(Arc::new(ch))) - } - - pub fn round_convex_hull(points: &[Point], border_radius: Real) -> Option { - #[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: Real) -> Option { - ConvexPolygon::from_convex_polyline(points).map(|ch| { - ColliderShape(Arc::new(RoundShape { - base_shape: ch, - border_radius, - })) - }) - } - - #[cfg(feature = "dim3")] - pub fn round_convex_mesh( - points: Vec>, - indices: &[[u32; 3]], - border_radius: Real, - ) -> Option { - ConvexPolyhedron::from_convex_mesh(points, indices).map(|ch| { - ColliderShape(Arc::new(RoundShape { - base_shape: ch, - border_radius, - })) - }) +impl ColliderFlags { + pub fn is_sensor(self) -> bool { + self.contains(ColliderFlags::SENSOR) } - /// Initializes an heightfield shape defined by its set of height and a scale - /// factor along each coordinate axis. - #[cfg(feature = "dim2")] - pub fn heightfield(heights: na::DVector, scale: Vector) -> Self { - ColliderShape(Arc::new(HeightField::new(heights, scale))) + pub fn friction_combine_rule_value(self) -> u8 { + (self.bits & 0b0000_0110) >> 1 } - /// Initializes an heightfield shape on the x-z plane defined by its set of height and a scale - /// factor along each coordinate axis. - #[cfg(feature = "dim3")] - pub fn heightfield(heights: na::DMatrix, scale: Vector) -> Self { - ColliderShape(Arc::new(HeightField::new(heights, scale))) + pub fn restitution_combine_rule_value(self) -> u8 { + (self.bits & 0b0001_1000) >> 3 } -} -#[cfg(feature = "serde-serialize")] -impl serde::Serialize for ColliderShape { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - use crate::serde::ser::SerializeStruct; - - if let Some(ser) = self.0.as_serialize() { - let typ = self.0.shape_type(); - let mut state = serializer.serialize_struct("ColliderShape", 2)?; - state.serialize_field("tag", &(typ as i32))?; - state.serialize_field("inner", ser)?; - state.end() - } else { - Err(serde::ser::Error::custom( - "Found a non-serializable custom shape.", - )) - } + pub fn with_friction_combine_rule(mut self, rule: CoefficientCombineRule) -> Self { + self.bits = (self.bits & !0b0000_0110) | ((rule as u8) << 1); + self } -} -#[cfg(feature = "serde-serialize")] -impl<'de> serde::Deserialize<'de> for ColliderShape { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - struct Visitor {}; - impl<'de> serde::de::Visitor<'de> for Visitor { - type Value = ColliderShape; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(formatter, "one shape type tag and the inner shape data") - } - - fn visit_seq(self, mut seq: A) -> Result - where - A: serde::de::SeqAccess<'de>, - { - use num::cast::FromPrimitive; - - let tag: i32 = seq - .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) => deser::(&mut seq)?, - Some(ShapeType::Cuboid) => deser::(&mut seq)?, - Some(ShapeType::Capsule) => deser::(&mut seq)?, - Some(ShapeType::Triangle) => deser::(&mut seq)?, - Some(ShapeType::Segment) => deser::(&mut seq)?, - Some(ShapeType::TriMesh) => deser::(&mut seq)?, - Some(ShapeType::Heig