use glam::Vec2;
use crate::math_segment::{Segment, SegmentColor};
#[derive(Default)]
pub(crate) struct SegmentSoa {
pub(crate) from: Vec<Vec2>,
pub(crate) to: Vec<Vec2>,
pub(crate) tangent: Vec<Vec2>,
pub(crate) inv_tangent_len_sq: Vec<f32>,
pub(crate) tangent_unit: Vec<Vec2>,
pub(crate) color_mask: Vec<u8>,
}
impl SegmentSoa {
pub(crate) fn new() -> Self {
Self::default()
}
pub(crate) fn len(&self) -> usize {
self.from.len()
}
pub(crate) fn populate(&mut self, segs: &[Segment]) {
let n = segs.len();
self.from.clear();
self.to.clear();
self.tangent.clear();
self.inv_tangent_len_sq.clear();
self.tangent_unit.clear();
self.color_mask.clear();
self.from.reserve(n);
self.to.reserve(n);
self.tangent.reserve(n);
self.inv_tangent_len_sq.reserve(n);
self.tangent_unit.reserve(n);
self.color_mask.reserve(n);
for seg in segs {
let tangent = seg.to - seg.from;
let len_sq = tangent.length_squared();
let (inv, unit) = if len_sq > 1e-6 {
let len = len_sq.sqrt();
(1.0 / len_sq, tangent / len)
} else {
(0.0, Vec2::ZERO)
};
self.from.push(seg.from);
self.to.push(seg.to);
self.tangent.push(tangent);
self.inv_tangent_len_sq.push(inv);
self.tangent_unit.push(unit);
self.color_mask.push(channel_mask(seg.color));
}
}
}
#[inline]
fn channel_mask(c: SegmentColor) -> u8 {
match c {
SegmentColor::White => 0b111,
SegmentColor::RedGreen => 0b011,
SegmentColor::GreenBlue => 0b110,
SegmentColor::BlueRed => 0b101,
}
}