use bevy::math::Vec3;
#[inline]
pub(crate) fn to_v3(v: Vec3) -> bloodstain::V3 {
[v.x, v.y, v.z]
}
#[inline]
pub(crate) fn from_v3(v: bloodstain::V3) -> Vec3 {
Vec3::new(v[0], v[1], v[2])
}
#[cfg_attr(not(feature = "vfx"), allow(dead_code))]
#[inline]
pub(crate) fn wound(w: &crate::Wound) -> bloodstain::Wound {
bloodstain::Wound {
at: to_v3(w.at),
normal: to_v3(w.normal),
area: w.area,
severity: w.severity,
kind: w.kind,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_round_trip_is_bit_exact() {
for v in [
Vec3::ZERO,
Vec3::new(0.1, -0.9, 1.0e-7),
Vec3::new(f32::MIN_POSITIVE, 1.0e30, -0.0),
] {
let back = from_v3(to_v3(v));
assert_eq!(
(back.x.to_bits(), back.y.to_bits(), back.z.to_bits()),
(v.x.to_bits(), v.y.to_bits(), v.z.to_bits()),
"the conversion must be a copy, not an approximation"
);
}
}
#[test]
fn a_wound_crosses_the_boundary_unchanged() {
let w = crate::Wound {
at: Vec3::new(0.1, 0.9, -0.2),
normal: Vec3::X,
area: 0.004,
severity: 0.5,
kind: crate::WoundKind::Channel,
};
let m = wound(&w);
assert_eq!(m.at, [0.1, 0.9, -0.2]);
assert_eq!(m.normal, [1.0, 0.0, 0.0]);
assert_eq!(m.area, w.area);
assert_eq!(m.severity, w.severity);
assert_eq!(m.kind, crate::WoundKind::Channel);
assert_eq!(
bloodstain::wound_seed(&m),
bloodstain::wound_seed(&wound(&w)),
"the mirror must be a pure function of the wound"
);
}
}