pack.rs
3.0 kB · rust · 98 lines
1use mrlyrs::math::three::Vec3;23/// A builder packing triangles and lines into one flat float buffer.4#[derive(Default)]5pub struct Pack {6 tris: Vec<f32>,7 lines: Vec<f32>,8}910impl Pack {11 /// Builds an empty pack.12 pub fn new() -> Pack {13 Pack::default()14 }15 /// Packs one triangle, writing position and normal per vertex.16 pub fn face(&mut self, verts: [Vec3; 3], normal: Vec3) {17 for v in verts {18 self.tris19 .extend([v.x, v.y, v.z, normal.x, normal.y, normal.z]);20 }21 }22 /// Packs a quad as two triangles sharing the normal.23 pub fn quad(&mut self, verts: [Vec3; 4], normal: Vec3) {24 self.face([verts[0], verts[1], verts[2]], normal);25 self.face([verts[0], verts[2], verts[3]], normal);26 }27 /// Packs one line, writing position, spin flag and color per endpoint.28 pub fn line(&mut self, a: Vec3, b: Vec3, spins: bool, color: [u8; 4]) {29 for v in [a, b] {30 self.lines31 .extend([v.x, v.y, v.z, if spins { 1.0 } else { 0.0 }]);32 self.lines.extend(color.map(|c| c as f32 / 255.0));33 }34 }35 /// Closes the pack into one buffer, the two section lengths first.36 pub fn buffer(self) -> Vec<f32> {37 let mut out = vec![self.tris.len() as f32, self.lines.len() as f32];38 out.extend(self.tris);39 out.extend(self.lines);40 out41 }42}4344#[cfg(test)]45mod tests {46 use super::*;4748 #[test]49 fn the_pack_lays_out_the_wire_format() {50 let mut pack = Pack::new();51 pack.face(52 [53 Vec3::new(0.0, 0.0, 0.0),54 Vec3::new(1.0, 0.0, 0.0),55 Vec3::new(0.0, 1.0, 0.0),56 ],57 Vec3::new(0.0, 0.0, 1.0),58 );59 pack.line(60 Vec3::new(0.0, 0.0, 0.0),61 Vec3::new(0.0, 0.0, 1.0),62 true,63 [255, 0, 0, 128],64 );65 let buf = pack.buffer();66 assert_eq!(buf[0], 18.0);67 assert_eq!(buf[1], 16.0);68 assert_eq!(&buf[2..8], &[0.0, 0.0, 0.0, 0.0, 0.0, 1.0]);69 assert_eq!(&buf[8..14], &[1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);70 assert_eq!(&buf[14..20], &[0.0, 1.0, 0.0, 0.0, 0.0, 1.0]);71 let glass = 128.0 / 255.0;72 assert_eq!(&buf[20..28], &[0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, glass]);73 assert_eq!(&buf[28..36], &[0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, glass]);74 }75 #[test]76 fn the_pack_splits_quads_and_keeps_furniture_still() {77 let mut pack = Pack::new();78 pack.quad(79 [80 Vec3::new(0.0, 0.0, 0.0),81 Vec3::new(1.0, 0.0, 0.0),82 Vec3::new(1.0, 1.0, 0.0),83 Vec3::new(0.0, 1.0, 0.0),84 ],85 Vec3::new(0.0, 0.0, 1.0),86 );87 pack.line(88 Vec3::new(0.0, 0.0, 0.0),89 Vec3::new(1.0, 0.0, 0.0),90 false,91 [0, 0, 0, 255],92 );93 let buf = pack.buffer();94 assert_eq!(buf[0], 36.0);95 assert_eq!(buf[2 + 36 + 3], 0.0);96 assert_eq!(buf[2 + 36 + 8 + 3], 0.0);97 }98}