ncollide3d/interpolation/
rigid_motion.rsuse na::RealField;
use crate::math::{Isometry, Point, Translation, Vector};
pub trait RigidMotion<N: RealField + Copy> {
fn position_at_time(&self, t: N) -> Isometry<N>;
}
impl<N: RealField + Copy> RigidMotion<N> for Isometry<N> {
fn position_at_time(&self, _: N) -> Isometry<N> {
*self
}
}
pub struct InterpolatedRigidMotion<N: RealField + Copy> {
pub start: Isometry<N>,
pub end: Isometry<N>,
}
impl<N: RealField + Copy> InterpolatedRigidMotion<N> {
pub fn new(start: Isometry<N>, end: Isometry<N>) -> Self {
InterpolatedRigidMotion { start, end }
}
}
impl<N: RealField + Copy> RigidMotion<N> for InterpolatedRigidMotion<N> {
fn position_at_time(&self, t: N) -> Isometry<N> {
self.start.lerp_slerp(&self.end, t)
}
}
pub struct ConstantLinearVelocityRigidMotion<N: RealField + Copy> {
pub t0: N,
pub start: Isometry<N>,
pub velocity: Vector<N>,
}
impl<N: RealField + Copy> ConstantLinearVelocityRigidMotion<N> {
pub fn new(t0: N, start: Isometry<N>, velocity: Vector<N>) -> Self {
ConstantLinearVelocityRigidMotion {
t0,
start,
velocity,
}
}
}
impl<N: RealField + Copy> RigidMotion<N> for ConstantLinearVelocityRigidMotion<N> {
fn position_at_time(&self, t: N) -> Isometry<N> {
Isometry::from_parts(
(self.start.translation.vector + self.velocity * (t - self.t0)).into(),
self.start.rotation,
)
}
}
#[derive(Debug)]
pub struct ConstantVelocityRigidMotion<N: RealField + Copy> {
pub t0: N,
pub start: Isometry<N>,
pub local_center: Point<N>,
pub linvel: Vector<N>,
#[cfg(feature = "dim2")]
pub angvel: N,
#[cfg(feature = "dim3")]
pub angvel: Vector<N>,
}
impl<N: RealField + Copy> ConstantVelocityRigidMotion<N> {
#[cfg(feature = "dim2")]
pub fn new(
t0: N,
start: Isometry<N>,
local_center: Point<N>,
linvel: Vector<N>,
angvel: N,
) -> Self {
ConstantVelocityRigidMotion {
t0,
start,
local_center,
linvel,
angvel,
}
}
#[cfg(feature = "dim3")]
pub fn new(
t0: N,
start: Isometry<N>,
local_center: Point<N>,
linvel: Vector<N>,
angvel: Vector<N>,
) -> Self {
ConstantVelocityRigidMotion {
t0,
start,
local_center,
linvel,
angvel,
}
}
}
impl<N: RealField + Copy> RigidMotion<N> for ConstantVelocityRigidMotion<N> {
fn position_at_time(&self, t: N) -> Isometry<N> {
let scaled_linvel = self.linvel * (t - self.t0);
let scaled_angvel = self.angvel * (t - self.t0);
let center = self.start.rotation * self.local_center.coords;
let lhs = self.start.translation * Translation::from(center);
let rhs = Translation::from(-center) * self.start.rotation;
lhs * Isometry::new(scaled_linvel, scaled_angvel) * rhs
}
}
pub trait RigidMotionComposition<N: RealField + Copy>: RigidMotion<N> {
fn prepend_translation(&self, translation: Vector<N>) -> PrependTranslation<N, Self> {
PrependTranslation {
motion: self,
translation,
}
}
fn prepend_transformation(
&self,
transformation: Isometry<N>,
) -> PrependTransformation<N, Self> {
PrependTransformation {
motion: self,
transformation,
}
}
}
impl<N: RealField + Copy, M: ?Sized + RigidMotion<N>> RigidMotionComposition<N> for M {}
pub struct PrependTranslation<'a, N: RealField + Copy, M: ?Sized> {
motion: &'a M,
translation: Vector<N>,
}
impl<'a, N: RealField + Copy, M: ?Sized + RigidMotion<N>> RigidMotion<N>
for PrependTranslation<'a, N, M>
{
fn position_at_time(&self, t: N) -> Isometry<N> {
let m = self.motion.position_at_time(t);
m * Translation::from(self.translation)
}
}
pub struct PrependTransformation<'a, N: RealField + Copy, M: ?Sized> {
motion: &'a M,
transformation: Isometry<N>,
}
impl<'a, N: RealField + Copy, M: ?Sized + RigidMotion<N>> RigidMotion<N>
for PrependTransformation<'a, N, M>
{
fn position_at_time(&self, t: N) -> Isometry<N> {
let m = self.motion.position_at_time(t);
m * self.transformation
}
}