use super::*;
use core::num::NonZeroU16;
#[cfg(feature = "builtin-types")]
use rayon::prelude::*;
pub type SampleWeight = f32;
pub trait Sample<T> {
fn sample(&self, shutter: &Shutter, samples: NonZeroU16) -> Result<Vec<(T, SampleWeight)>>;
}
#[cfg(feature = "builtin-types")]
macro_rules! impl_sample {
($data_type:ty) => {
impl Sample<$data_type> for TimeDataMap<$data_type> {
fn sample(
&self,
shutter: &Shutter,
samples: NonZeroU16,
) -> Result<Vec<($data_type, SampleWeight)>> {
Ok((0..samples.into())
.into_par_iter()
.map(|t| {
let time = shutter.evaluate(t as f32 / u16::from(samples) as f32);
(self.interpolate(time), shutter.opening(time))
})
.collect::<Vec<_>>())
}
}
};
}
#[cfg(feature = "builtin-types")]
impl_sample!(Real);
#[cfg(feature = "builtin-types")]
impl_sample!(Integer);
#[cfg(feature = "builtin-types")]
impl_sample!(Color);
#[cfg(all(feature = "builtin-types", feature = "vector2"))]
impl_sample!(Vector2);
#[cfg(all(feature = "builtin-types", feature = "vector3"))]
impl_sample!(Vector3);
#[cfg(all(feature = "builtin-types", feature = "normal3"))]
impl_sample!(Normal3);
#[cfg(all(feature = "builtin-types", feature = "point3"))]
impl_sample!(Point3);
#[cfg(all(feature = "builtin-types", feature = "matrix4"))]
impl_sample!(Matrix4);
#[cfg(all(feature = "builtin-types", feature = "matrix3"))]
impl Sample<Matrix3> for TimeDataMap<Matrix3> {
fn sample(
&self,
shutter: &Shutter,
samples: NonZeroU16,
) -> Result<Vec<(Matrix3, SampleWeight)>> {
let mut translations = BTreeMap::new();
let mut rotations = BTreeMap::new();
let mut stretches = BTreeMap::new();
#[cfg(not(feature = "interpolation"))]
for (time, matrix) in self.values.as_btree_map().iter() {
let crate::Matrix3(ref inner) = *matrix;
let (translate, rotate, stretch) = decompose_matrix(inner);
translations.insert(*time, translate);
rotations.insert(*time, rotate);
stretches.insert(*time, stretch);
}
#[cfg(feature = "interpolation")]
for (time, (matrix, _spec)) in self.values.as_btree_map().iter() {
let crate::Matrix3(ref inner) = *matrix;
let (translate, rotate, stretch) = decompose_matrix(inner);
translations.insert(*time, translate);
rotations.insert(*time, rotate);
stretches.insert(*time, stretch);
}
Ok((0..samples.into())
.into_par_iter()
.map(|t| {
let time = shutter.evaluate(t as f32 / u16::from(samples) as f32);
(
crate::Matrix3(recompose_matrix(
interpolate(&translations, time),
interpolate_rotation(&rotations, time),
interpolate(&stretches, time),
)),
shutter.opening(time),
)
})
.collect::<Vec<_>>())
}
}