pack.rs

3.0 kB · rust · 98 lines

1use super::vec::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}