Skip to content

Commit

Permalink
Add clone_scaled to Shape traits
Browse files Browse the repository at this point in the history
  • Loading branch information
Neo-Zhixing committed Jul 2, 2024
1 parent 9e723ee commit 35d16bb
Showing 1 changed file with 187 additions and 8 deletions.
195 changes: 187 additions & 8 deletions src/shape/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::shape::{ConvexPolyhedron, RoundConvexPolyhedron};
#[cfg(feature = "std")]
use crate::shape::{ConvexPolygon, RoundConvexPolygon};
use downcast_rs::{impl_downcast, DowncastSync};
use either::Either::{Left, Right};
use na::{RealField, Unit};
use num::Zero;
use num_derive::FromPrimitive;
Expand Down Expand Up @@ -282,6 +283,9 @@ pub trait Shape: RayCast + PointQuery + DowncastSync {
#[cfg(feature = "std")]
fn clone_box(&self) -> Box<dyn Shape>;

#[cfg(feature = "std")]
fn clone_scaled(&self, scale: &Vector<Real>, num_subdivisions: u32) -> Option<Box<dyn Shape>>;

/// Computes the [`Aabb`] of this shape with the given position.
fn compute_aabb(&self, position: &Isometry<Real>) -> Aabb {
self.compute_local_aabb().transform_by(position)
Expand Down Expand Up @@ -585,6 +589,12 @@ impl Shape for Ball {
Box::new(*self)
}

#[cfg(feature = "std")]
fn clone_scaled(&self, scale: &Vector<Real>, num_subdivisions: u32) -> Option<Box<dyn Shape>> {
let scaled = self.scaled(scale, num_subdivisions)?;
Some(scaled.either::<_, _, Box<dyn Shape>>(|x| Box::new(x), |x| Box::new(x)))
}

fn compute_local_aabb(&self) -> Aabb {
self.local_aabb()
}
Expand Down Expand Up @@ -642,6 +652,11 @@ impl Shape for Cuboid {
Box::new(*self)
}

#[cfg(feature = "std")]
fn clone_scaled(&self, scale: &Vector<Real>, _num_subdivisions: u32) -> Option<Box<dyn Shape>> {
Some(Box::new(self.scaled(scale)))
}

fn compute_local_aabb(&self) -> Aabb {
self.local_aabb()
}
Expand Down Expand Up @@ -701,6 +716,12 @@ impl Shape for Capsule {
Box::new(*self)
}

#[cfg(feature = "std")]
fn clone_scaled(&self, scale: &Vector<Real>, num_subdivisions: u32) -> Option<Box<dyn Shape>> {
let scaled = self.scaled(scale, num_subdivisions)?;
Some(scaled.either::<_, _, Box<dyn Shape>>(|x| Box::new(x), |x| Box::new(x)))
}

fn compute_local_aabb(&self) -> Aabb {
self.local_aabb()
}
Expand Down Expand Up @@ -752,6 +773,11 @@ impl Shape for Triangle {
Box::new(*self)
}

#[cfg(feature = "std")]
fn clone_scaled(&self, scale: &Vector<Real>, _num_subdivisions: u32) -> Option<Box<dyn Shape>> {
Some(Box::new(self.scaled(scale)))
}

fn compute_local_aabb(&self) -> Aabb {
self.local_aabb()
}
Expand Down Expand Up @@ -815,6 +841,11 @@ impl Shape for Segment {
Box::new(*self)
}

#[cfg(feature = "std")]
fn clone_scaled(&self, scale: &Vector<Real>, _num_subdivisions: u32) -> Option<Box<dyn Shape>> {
Some(Box::new(self.scaled(scale)))
}

fn compute_local_aabb(&self) -> Aabb {
self.local_aabb()
}
Expand Down Expand Up @@ -874,6 +905,26 @@ impl Shape for Compound {
Box::new(self.clone())
}

fn clone_scaled(&self, scale: &Vector<Real>, num_subdivisions: u32) -> Option<Box<dyn Shape>> {
use super::SharedShape;

let scaled: Vec<_> = self
.shapes()
.iter()
.map(|(pos, shape)| {
let scaled_shape = shape.clone_scaled(scale, num_subdivisions)?;
Some((
Isometry::from_parts(
(pos.translation.vector.component_mul(scale)).into(),
pos.rotation,
),
SharedShape(scaled_shape.into()),
))
})
.collect::<Option<Vec<_>>>()?;
Some(Box::new(Compound::new(scaled)))
}

fn compute_local_aabb(&self) -> Aabb {
*self.local_aabb()
}
Expand Down Expand Up @@ -922,6 +973,10 @@ impl Shape for Polyline {
Box::new(self.clone())
}

fn clone_scaled(&self, scale: &Vector<Real>, _num_subdivisions: u32) -> Option<Box<dyn Shape>> {
Some(Box::new(self.clone().scaled(scale)))
}

fn compute_local_aabb(&self) -> Aabb {
*self.local_aabb()
}
Expand Down Expand Up @@ -968,6 +1023,10 @@ impl Shape for TriMesh {
Box::new(self.clone())
}

fn clone_scaled(&self, scale: &Vector<Real>, _num_subdivisions: u32) -> Option<Box<dyn Shape>> {
Some(Box::new(self.clone().scaled(scale)))
}

fn compute_local_aabb(&self) -> Aabb {
*self.local_aabb()
}
Expand Down Expand Up @@ -1015,6 +1074,10 @@ impl Shape for HeightField {
Box::new(self.clone())
}

fn clone_scaled(&self, scale: &Vector<Real>, _num_subdivisions: u32) -> Option<Box<dyn Shape>> {
Some(Box::new(self.clone().scaled(scale)))
}

fn compute_local_aabb(&self) -> Aabb {
self.local_aabb()
}
Expand Down Expand Up @@ -1057,6 +1120,10 @@ impl Shape for ConvexPolygon {
Box::new(self.clone())
}

fn clone_scaled(&self, scale: &Vector<Real>, _num_subdivisions: u32) -> Option<Box<dyn Shape>> {
Some(Box::new(self.clone().scaled(scale)?))
}

fn compute_local_aabb(&self) -> Aabb {
self.local_aabb()
}
Expand Down Expand Up @@ -1120,6 +1187,10 @@ impl Shape for ConvexPolyhedron {
Box::new(self.clone())
}

fn clone_scaled(&self, scale: &Vector<Real>, _num_subdivisions: u32) -> Option<Box<dyn Shape>> {
Some(Box::new(self.clone().scaled(scale)?))
}

fn compute_local_aabb(&self) -> Aabb {
self.local_aabb()
}
Expand Down Expand Up @@ -1184,6 +1255,12 @@ impl Shape for Cylinder {
Box::new(*self)
}

#[cfg(feature = "std")]
fn clone_scaled(&self, scale: &Vector<Real>, num_subdivisions: u32) -> Option<Box<dyn Shape>> {
let scaled = self.scaled(scale, num_subdivisions)?;
Some(scaled.either::<_, _, Box<dyn Shape>>(|x| Box::new(x), |x| Box::new(x)))
}

fn compute_local_aabb(&self) -> Aabb {
self.local_aabb()
}
Expand Down Expand Up @@ -1236,6 +1313,12 @@ impl Shape for Cone {
Box::new(*self)
}

#[cfg(feature = "std")]
fn clone_scaled(&self, scale: &Vector<Real>, num_subdivisions: u32) -> Option<Box<dyn Shape>> {
let scaled = self.scaled(scale, num_subdivisions)?;
Some(scaled.either::<_, _, Box<dyn Shape>>(|x| Box::new(x), |x| Box::new(x)))
}

fn compute_local_aabb(&self) -> Aabb {
self.local_aabb()
}
Expand Down Expand Up @@ -1290,6 +1373,11 @@ impl Shape for HalfSpace {
Box::new(*self)
}

#[cfg(feature = "std")]
fn clone_scaled(&self, scale: &Vector<Real>, _num_subdivisions: u32) -> Option<Box<dyn Shape>> {
Some(Box::new(self.clone().scaled(scale)?))
}

fn compute_local_aabb(&self) -> Aabb {
self.local_aabb()
}
Expand Down Expand Up @@ -1328,13 +1416,18 @@ impl Shape for HalfSpace {
}

macro_rules! impl_shape_for_round_shape(
($($S: ty, $Tag: ident);*) => {$(
($S: ty, $Tag: ident, $t: tt) => {
impl Shape for RoundShape<$S> {
#[cfg(feature = "std")]
fn clone_box(&self) -> Box<dyn Shape> {
Box::new(self.clone())
}

#[cfg(feature = "std")]
fn clone_scaled(&self, scale: &Vector<Real>, num_subdivisions: u32) -> Option<Box<dyn Shape>> {
$t(self, scale, num_subdivisions)
}

fn compute_local_aabb(&self) -> Aabb {
self.inner_shape.local_aabb().loosened(self.border_radius)
}
Expand Down Expand Up @@ -1381,22 +1474,108 @@ macro_rules! impl_shape_for_round_shape(
Some((&self.inner_shape as &dyn PolygonalFeatureMap, self.border_radius))
}
}
)*}
}
);

impl_shape_for_round_shape!(
Cuboid,
RoundCuboid,
(|this: &Self, scale: &Vector<Real>, _num_subdivisions: u32| {
let shape = RoundShape {
border_radius: this.border_radius,
inner_shape: this.inner_shape.scaled(scale),
};
Some(Box::new(shape) as Box<dyn Shape>)
})
);

impl_shape_for_round_shape!(
Cuboid, RoundCuboid;
Triangle, RoundTriangle
Triangle,
RoundTriangle,
(|this: &Self, scale: &Vector<Real>, _num_subdivisions: u32| {
let shape = RoundShape {
border_radius: this.border_radius,
inner_shape: this.inner_shape.scaled(scale),
};
Some(Box::new(shape) as Box<dyn Shape>)
})
);

#[cfg(feature = "dim2")]
#[cfg(feature = "std")]
impl_shape_for_round_shape!(ConvexPolygon, RoundConvexPolygon);
impl_shape_for_round_shape!(
ConvexPolygon,
RoundConvexPolygon,
(|this: &Self, scale: &Vector<Real>, _num_subdivisions: u32| {
let shape = RoundShape {
border_radius: this.border_radius,
inner_shape: this.inner_shape.clone().scaled(scale)?,
};
Some(Box::new(shape) as Box<dyn Shape>)
})
);

#[cfg(feature = "dim3")]
impl_shape_for_round_shape!(
Cylinder, RoundCylinder;
Cone, RoundCone
Cylinder,
RoundCylinder,
(|this: &Self, scale: &Vector<Real>, num_subdivisions: u32| {
Some(
this.inner_shape
.scaled(scale, num_subdivisions)?
.either::<_, _, Box<dyn Shape>>(
|inner_shape| {
Box::new(RoundShape {
border_radius: this.border_radius,
inner_shape,
})
},
|inner_shape| {
Box::new(RoundShape {
border_radius: this.border_radius,
inner_shape,
})
},
),
)
})
);
#[cfg(feature = "dim3")]
impl_shape_for_round_shape!(
Cone,
RoundCone,
(|this: &Self, scale: &Vector<Real>, num_subdivisions: u32| {
Some(
this.inner_shape
.scaled(scale, num_subdivisions)?
.either::<_, _, Box<dyn Shape>>(
|inner_shape| {
Box::new(RoundShape {
border_radius: this.border_radius,
inner_shape,
})
},
|inner_shape| {
Box::new(RoundShape {
border_radius: this.border_radius,
inner_shape,
})
},
),
)
})
);

#[cfg(feature = "dim3")]
#[cfg(feature = "std")]
impl_shape_for_round_shape!(ConvexPolyhedron, RoundConvexPolyhedron);
impl_shape_for_round_shape!(
ConvexPolyhedron,
RoundConvexPolyhedron,
(|this: &Self, scale: &Vector<Real>, _num_subdivisions: u32| {
let shape = RoundShape {
border_radius: this.border_radius,
inner_shape: this.inner_shape.clone().scaled(scale)?,
};
Some(Box::new(shape) as Box<dyn Shape>)
})
);

0 comments on commit 35d16bb

Please sign in to comment.