dimforge / nphysics

2 and 3-dimensional rigid body physics engine for Rust.
https://nphysics.org
Apache License 2.0
1.62k stars 121 forks source link

impl Volumetric for Shape doesn't allow for your own shapes #135

Open kevinw opened 6 years ago

kevinw commented 6 years ago

I was implementing an Ellipsoid Shape, but when I got to the Volumetric trait, I realized that it is hardcoded for the specific Shapes that ship with nphysics:

macro_rules! dispatch(
    ($p: ty, $i: ty, $sself: ident.$name: ident($($argN: ident),*)) => {
        {
            if let Some(b) = $sself.as_shape::<Ball<N>>() {
                return b.$name($($argN,)*)
            }
            if let Some(c) = $sself.as_shape::<Compound<N>>() {
                return c.$name($($argN,)*)
            }
            // else if let Some(c) = $sself.as_shape::<Cone<N>>() {
            //     (c as &Volumetric<N, $p, $i>).$name($($argN,)*)
            // }
            #[cfg(feature = "dim3")]
            {
                if let Some(c) = $sself.as_shape::<ConvexHull<N>>() {
                    return c.$name($($argN,)*)
                }
            }
            #[cfg(feature = "dim2")]
            {
                if let Some(c) = $sself.as_shape::<ConvexPolygon<N>>() {
                    return c.$name($($argN,)*)
                }
            }
            if let Some(c) = $sself.as_shape::<Cuboid<N>>() {
                return c.$name($($argN,)*)
            }
            // if let Some(c) = $sself.as_shape::<Cylinder<N>>() {
            //     return c.$name($($argN,)*)
            // }

            /*
             * XXX: dispatch by custom type.
             */
            panic!("The `Volumetric` is not implemented by the given shape.")
        }
    }
);

We need a way to implement Volumetric for crate-provided Shape structs.

sebcrozet commented 6 years ago

I agree this is not extensible enough and should be improved!

Though keep in mind the Volumetric trait is not strictly required by nphysics: all you need is a way to retrieve the center of mass and inertia from your shape if you want to use them for the creation of a rigid body or multibody link.

sebcrozet commented 4 years ago

One solution for this would be to:

  1. Move the Volumetric trait to ncollide.
  2. Add to the Shape trait the method fn as_volumetric(&self) -> Option<&Volumetric> {}.
  3. Move to ncollide the relevant implementations of Volumetric and adapt the corresponding implementation of Shape so it includes: fn as_volumetric(&self) -> Option<&Volumetric> { Some(self as &Volumetric) }.