TLDR
Is it possible to write code that is generic over ncollide2d
and ncollide3d
?
Details
I have prototyped some code using ncollide2d
. I’m really more interested in the 3-dimensional version, but the 2-d version is useful for exploration purposes, so I would like to keep it around. The 2-D and 3-D versions should be almost identical in many respects, so I’d rather not duplicate the code but write a generic version wherever possible.
The original code starts off with something like this:
use ncollide2d as nc;
type Length = f64;
type Vector = nc::math ::Vector<Length>;
type Point = nc::math ::Point <Length>;
type Cuboid = nc::shape::Cuboid<Length>;
type Ray = nc::query::Ray <Length>;
// etc.
which allows me to switch most of the code over from 2-D to 3-D simply by changing the use
at the top from ncollide2d
to ncollide3d
.
However, I would like to be able to keep both the 2-D and 3-D versions at the same time. I tried the following approach
trait Dimension {
type Vector;
type Point;
// etc.
}
struct D2;
struct D3;
use ncollide2d as nc2;
use ncollide3d as nc3;
impl Dimension for D2 {
type Vector = nc2::math::Vector<Length>;
type Point = nc2::math::Point <Length>;
// etc.
}
impl Dimension for D3 {
type Vector = nc3::math::Vector<Length>;
type Point = nc3::math::Point <Length>;
// etc.
}
with the aim of parametrizing the code on the Dimension
trait.
This fails because many of the methods which are available in both 2-D and 3-D are not part any trait that I can identify, so the compiler is unaware of their availability.
Take 2
I also tried to bypass the ncollideNd
type aliases and go directly to the underlying types hidden behind them, that is, for example, nalgebra::geometry::Point<Length, D>
rather than ncollide2d::math::Point<Length>
, with the aim of parametrizing on D: DimName
.
This also failed, for reasons which are probably too messy to be usefully discussed at this point.
The question
Is it possible to write such polymorphic code, or am I fundamentally misguided?