Replace the Rounded<S> type by a non-generic RoundCylinder type.
This commit is contained in:
@@ -4,7 +4,7 @@ use crate::geometry::{
|
|||||||
Segment, Shape, ShapeType, Triangle, Trimesh,
|
Segment, Shape, ShapeType, Triangle, Trimesh,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
use crate::geometry::{Cone, Cylinder, Rounded};
|
use crate::geometry::{Cone, Cylinder, RoundCylinder};
|
||||||
use crate::math::{AngVector, Isometry, Point, Rotation, Vector};
|
use crate::math::{AngVector, Isometry, Point, Rotation, Vector};
|
||||||
use na::Point3;
|
use na::Point3;
|
||||||
use ncollide::bounding_volume::AABB;
|
use ncollide::bounding_volume::AABB;
|
||||||
@@ -39,10 +39,11 @@ impl ColliderShape {
|
|||||||
/// (along along the y axis), its radius, and its roundedness (the
|
/// (along along the y axis), its radius, and its roundedness (the
|
||||||
/// radius of the sphere used for dilating the cylinder).
|
/// radius of the sphere used for dilating the cylinder).
|
||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
pub fn round_cylinder(half_height: f32, radius: f32, round_radius: f32) -> Self {
|
pub fn round_cylinder(half_height: f32, radius: f32, border_radius: f32) -> Self {
|
||||||
ColliderShape(Arc::new(Rounded::new(
|
ColliderShape(Arc::new(RoundCylinder::new(
|
||||||
Cylinder::new(half_height, radius),
|
half_height,
|
||||||
round_radius,
|
radius,
|
||||||
|
border_radius,
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +171,7 @@ impl<'de> serde::Deserialize<'de> for ColliderShape {
|
|||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
Some(ShapeType::Cone) => deser::<A, Cone>(&mut seq)?,
|
Some(ShapeType::Cone) => deser::<A, Cone>(&mut seq)?,
|
||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
Some(ShapeType::RoundCylinder) => deser::<A, Rounded<Cylinder>>(&mut seq)?,
|
Some(ShapeType::RoundCylinder) => deser::<A, RoundCylinder>(&mut seq)?,
|
||||||
None => {
|
None => {
|
||||||
return Err(serde::de::Error::custom(
|
return Err(serde::de::Error::custom(
|
||||||
"found invalid shape type to deserialize",
|
"found invalid shape type to deserialize",
|
||||||
@@ -332,11 +333,11 @@ impl ColliderBuilder {
|
|||||||
/// (along along the y axis), its radius, and its roundedness (the
|
/// (along along the y axis), its radius, and its roundedness (the
|
||||||
/// radius of the sphere used for dilating the cylinder).
|
/// radius of the sphere used for dilating the cylinder).
|
||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
pub fn round_cylinder(half_height: f32, radius: f32, round_radius: f32) -> Self {
|
pub fn round_cylinder(half_height: f32, radius: f32, border_radius: f32) -> Self {
|
||||||
Self::new(ColliderShape::round_cylinder(
|
Self::new(ColliderShape::round_cylinder(
|
||||||
half_height,
|
half_height,
|
||||||
radius,
|
radius,
|
||||||
round_radius,
|
border_radius,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ impl Default for PfmPfmContactManifoldGeneratorWorkspace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_contacts_pfm_pfm(ctxt: &mut PrimitiveContactGenerationContext) {
|
pub fn generate_contacts_pfm_pfm(ctxt: &mut PrimitiveContactGenerationContext) {
|
||||||
if let (Some((pfm1, round_radius1)), Some((pfm2, round_radius2))) = (
|
if let (Some((pfm1, border_radius1)), Some((pfm2, border_radius2))) = (
|
||||||
ctxt.shape1.as_polygonal_feature_map(),
|
ctxt.shape1.as_polygonal_feature_map(),
|
||||||
ctxt.shape2.as_polygonal_feature_map(),
|
ctxt.shape2.as_polygonal_feature_map(),
|
||||||
) {
|
) {
|
||||||
do_generate_contacts(pfm1, round_radius1, pfm2, round_radius2, ctxt);
|
do_generate_contacts(pfm1, border_radius1, pfm2, border_radius2, ctxt);
|
||||||
ctxt.manifold.update_warmstart_multiplier();
|
ctxt.manifold.update_warmstart_multiplier();
|
||||||
ctxt.manifold.sort_contacts(ctxt.prediction_distance);
|
ctxt.manifold.sort_contacts(ctxt.prediction_distance);
|
||||||
}
|
}
|
||||||
@@ -36,9 +36,9 @@ pub fn generate_contacts_pfm_pfm(ctxt: &mut PrimitiveContactGenerationContext) {
|
|||||||
|
|
||||||
fn do_generate_contacts(
|
fn do_generate_contacts(
|
||||||
pfm1: &dyn PolygonalFeatureMap,
|
pfm1: &dyn PolygonalFeatureMap,
|
||||||
round_radius1: f32,
|
border_radius1: f32,
|
||||||
pfm2: &dyn PolygonalFeatureMap,
|
pfm2: &dyn PolygonalFeatureMap,
|
||||||
round_radius2: f32,
|
border_radius2: f32,
|
||||||
ctxt: &mut PrimitiveContactGenerationContext,
|
ctxt: &mut PrimitiveContactGenerationContext,
|
||||||
) {
|
) {
|
||||||
let pos12 = ctxt.position1.inverse() * ctxt.position2;
|
let pos12 = ctxt.position1.inverse() * ctxt.position2;
|
||||||
@@ -61,7 +61,7 @@ fn do_generate_contacts(
|
|||||||
.downcast_mut()
|
.downcast_mut()
|
||||||
.expect("Invalid workspace type, expected a PfmPfmContactManifoldGeneratorWorkspace.");
|
.expect("Invalid workspace type, expected a PfmPfmContactManifoldGeneratorWorkspace.");
|
||||||
|
|
||||||
let total_prediction = ctxt.prediction_distance + round_radius1 + round_radius2;
|
let total_prediction = ctxt.prediction_distance + border_radius1 + border_radius2;
|
||||||
let contact = query::contact_support_map_support_map_with_params(
|
let contact = query::contact_support_map_support_map_with_params(
|
||||||
&Isometry::identity(),
|
&Isometry::identity(),
|
||||||
pfm1,
|
pfm1,
|
||||||
@@ -93,11 +93,11 @@ fn do_generate_contacts(
|
|||||||
ctxt.manifold,
|
ctxt.manifold,
|
||||||
);
|
);
|
||||||
|
|
||||||
if round_radius1 != 0.0 || round_radius2 != 0.0 {
|
if border_radius1 != 0.0 || border_radius2 != 0.0 {
|
||||||
for contact in &mut ctxt.manifold.points {
|
for contact in &mut ctxt.manifold.points {
|
||||||
contact.local_p1 += *normal1 * round_radius1;
|
contact.local_p1 += *normal1 * border_radius1;
|
||||||
contact.local_p2 += *normal2 * round_radius2;
|
contact.local_p2 += *normal2 * border_radius2;
|
||||||
contact.dist -= round_radius1 + round_radius2;
|
contact.dist -= border_radius1 + border_radius2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub use self::narrow_phase::NarrowPhase;
|
|||||||
pub use self::polygon::Polygon;
|
pub use self::polygon::Polygon;
|
||||||
pub use self::proximity::ProximityPair;
|
pub use self::proximity::ProximityPair;
|
||||||
pub use self::proximity_detector::{DefaultProximityDispatcher, ProximityDispatcher};
|
pub use self::proximity_detector::{DefaultProximityDispatcher, ProximityDispatcher};
|
||||||
pub use self::rounded::{Roundable, Rounded};
|
pub use self::round_cylinder::RoundCylinder;
|
||||||
pub use self::trimesh::Trimesh;
|
pub use self::trimesh::Trimesh;
|
||||||
pub use ncollide::query::Proximity;
|
pub use ncollide::query::Proximity;
|
||||||
|
|
||||||
@@ -98,5 +98,5 @@ mod wquadtree;
|
|||||||
mod capsule;
|
mod capsule;
|
||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
mod polygonal_feature_map;
|
mod polygonal_feature_map;
|
||||||
mod rounded;
|
mod round_cylinder;
|
||||||
mod shape;
|
mod shape;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
use crate::geometry::Cylinder;
|
use crate::geometry::Cylinder;
|
||||||
use crate::geometry::ShapeType;
|
|
||||||
use crate::math::{Isometry, Point, Vector};
|
use crate::math::{Isometry, Point, Vector};
|
||||||
use na::Unit;
|
use na::Unit;
|
||||||
use ncollide::query::{
|
use ncollide::query::{
|
||||||
@@ -8,44 +7,35 @@ use ncollide::query::{
|
|||||||
};
|
};
|
||||||
use ncollide::shape::{FeatureId, SupportMap};
|
use ncollide::shape::{FeatureId, SupportMap};
|
||||||
|
|
||||||
/// A shape which corner can be rounded.
|
/// A rounded cylinder.
|
||||||
pub trait Roundable {
|
|
||||||
/// The ShapeType fo this shape after rounding its corners.
|
|
||||||
fn rounded_shape_type() -> ShapeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "dim3")]
|
|
||||||
impl Roundable for Cylinder {
|
|
||||||
fn rounded_shape_type() -> ShapeType {
|
|
||||||
ShapeType::RoundCylinder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A rounded shape.
|
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
pub struct Rounded<S: Roundable> {
|
#[derive(Copy, Clone, Debug)]
|
||||||
/// The shape being rounded.
|
pub struct RoundCylinder {
|
||||||
pub shape: S,
|
/// The cylinder being rounded.
|
||||||
|
pub cylinder: Cylinder,
|
||||||
/// The rounding radius.
|
/// The rounding radius.
|
||||||
pub radius: f32,
|
pub border_radius: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Roundable> Rounded<S> {
|
impl RoundCylinder {
|
||||||
/// Create sa new shape where all its edges and vertices are rounded by a radius of `radius`.
|
/// Create sa new cylinder where all its edges and vertices are rounded by a radius of `radius`.
|
||||||
///
|
///
|
||||||
/// This is done by applying a dilation of the given radius to the shape.
|
/// This is done by applying a dilation of the given radius to the cylinder.
|
||||||
pub fn new(shape: S, radius: f32) -> Self {
|
pub fn new(half_height: f32, radius: f32, border_radius: f32) -> Self {
|
||||||
Self { shape, radius }
|
Self {
|
||||||
|
cylinder: Cylinder::new(half_height, radius),
|
||||||
|
border_radius,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Roundable + SupportMap<f32>> SupportMap<f32> for Rounded<S> {
|
impl SupportMap<f32> for RoundCylinder {
|
||||||
fn local_support_point(&self, dir: &Vector<f32>) -> Point<f32> {
|
fn local_support_point(&self, dir: &Vector<f32>) -> Point<f32> {
|
||||||
self.local_support_point_toward(&Unit::new_normalize(*dir))
|
self.local_support_point_toward(&Unit::new_normalize(*dir))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_support_point_toward(&self, dir: &Unit<Vector<f32>>) -> Point<f32> {
|
fn local_support_point_toward(&self, dir: &Unit<Vector<f32>>) -> Point<f32> {
|
||||||
self.shape.local_support_point_toward(dir) + **dir * self.radius
|
self.cylinder.local_support_point_toward(dir) + **dir * self.border_radius
|
||||||
}
|
}
|
||||||
|
|
||||||
fn support_point(&self, transform: &Isometry<f32>, dir: &Vector<f32>) -> Point<f32> {
|
fn support_point(&self, transform: &Isometry<f32>, dir: &Vector<f32>) -> Point<f32> {
|
||||||
@@ -63,7 +53,7 @@ impl<S: Roundable + SupportMap<f32>> SupportMap<f32> for Rounded<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Roundable + SupportMap<f32>> RayCast<f32> for Rounded<S> {
|
impl RayCast<f32> for RoundCylinder {
|
||||||
fn toi_and_normal_with_ray(
|
fn toi_and_normal_with_ray(
|
||||||
&self,
|
&self,
|
||||||
m: &Isometry<f32>,
|
m: &Isometry<f32>,
|
||||||
@@ -90,7 +80,7 @@ impl<S: Roundable + SupportMap<f32>> RayCast<f32> for Rounded<S> {
|
|||||||
|
|
||||||
// TODO: if PointQuery had a `project_point_with_normal` method, we could just
|
// TODO: if PointQuery had a `project_point_with_normal` method, we could just
|
||||||
// call this and adjust the projected point accordingly.
|
// call this and adjust the projected point accordingly.
|
||||||
impl<S: Roundable + SupportMap<f32>> PointQuery<f32> for Rounded<S> {
|
impl PointQuery<f32> for RoundCylinder {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn project_point(
|
fn project_point(
|
||||||
&self,
|
&self,
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::dynamics::MassProperties;
|
use crate::dynamics::MassProperties;
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
Ball, Capsule, Cuboid, HeightField, Roundable, Rounded, Segment, Triangle, Trimesh,
|
Ball, Capsule, Cuboid, HeightField, RoundCylinder, Segment, Triangle, Trimesh,
|
||||||
};
|
};
|
||||||
use crate::math::Isometry;
|
use crate::math::Isometry;
|
||||||
use downcast_rs::{impl_downcast, DowncastSync};
|
use downcast_rs::{impl_downcast, DowncastSync};
|
||||||
@@ -132,11 +132,8 @@ impl dyn Shape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Converts this abstract shape to a cone, if it is one.
|
/// Converts this abstract shape to a cone, if it is one.
|
||||||
pub fn as_rounded<S>(&self) -> Option<&Rounded<S>>
|
#[cfg(feature = "dim3")]
|
||||||
where
|
pub fn as_round_cylinder(&self) -> Option<&RoundCylinder> {
|
||||||
S: Roundable,
|
|
||||||
Rounded<S>: Shape,
|
|
||||||
{
|
|
||||||
self.downcast_ref()
|
self.downcast_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -364,19 +361,21 @@ impl Shape for Cone {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
impl Shape for Rounded<Cylinder> {
|
impl Shape for RoundCylinder {
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
fn as_serialize(&self) -> Option<&dyn Serialize> {
|
fn as_serialize(&self) -> Option<&dyn Serialize> {
|
||||||
Some(self as &dyn Serialize)
|
Some(self as &dyn Serialize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_aabb(&self, position: &Isometry<f32>) -> AABB<f32> {
|
fn compute_aabb(&self, position: &Isometry<f32>) -> AABB<f32> {
|
||||||
self.shape.compute_aabb(position).loosened(self.radius)
|
self.cylinder
|
||||||
|
.compute_aabb(position)
|
||||||
|
.loosened(self.border_radius)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mass_properties(&self, density: f32) -> MassProperties {
|
fn mass_properties(&self, density: f32) -> MassProperties {
|
||||||
// We ignore the margin here.
|
// We ignore the margin here.
|
||||||
self.shape.mass_properties(density)
|
self.cylinder.mass_properties(density)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shape_type(&self) -> ShapeType {
|
fn shape_type(&self) -> ShapeType {
|
||||||
@@ -385,6 +384,9 @@ impl Shape for Rounded<Cylinder> {
|
|||||||
|
|
||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
fn as_polygonal_feature_map(&self) -> Option<(&dyn PolygonalFeatureMap, f32)> {
|
fn as_polygonal_feature_map(&self) -> Option<(&dyn PolygonalFeatureMap, f32)> {
|
||||||
Some((&self.shape as &dyn PolygonalFeatureMap, self.radius))
|
Some((
|
||||||
|
&self.cylinder as &dyn PolygonalFeatureMap,
|
||||||
|
self.border_radius,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -412,7 +412,10 @@ impl GraphicsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
if let Some(cylinder) = shape.as_cylinder().or(shape.as_rounded().map(|r| &r.shape)) {
|
if let Some(cylinder) = shape
|
||||||
|
.as_cylinder()
|
||||||
|
.or(shape.as_round_cylinder().map(|r| &r.cylinder))
|
||||||
|
{
|
||||||
out.push(Node::Cylinder(Cylinder::new(
|
out.push(Node::Cylinder(Cylinder::new(
|
||||||
handle,
|
handle,
|
||||||
cylinder.half_height,
|
cylinder.half_height,
|
||||||
|
|||||||
Reference in New Issue
Block a user