1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
use math::{Vec2, Matrix}; struct Data { parent: Option<Transform>, dirty: bool, position: Vec2, scale: Vec2, global: Matrix, } #[derive(Copy, Clone)] pub struct Transform(usize); pub struct TransformSystem { transforms: Vec<Data>, } impl TransformSystem { pub fn new() -> Self { Self { transforms: Vec::new() } } pub fn add(&mut self, position: Vec2, scale: Vec2) -> Transform { self.add_inner(None, position, scale) } pub fn add_child(&mut self, parent: Transform, position: Vec2, scale: Vec2) -> Transform { self.add_inner(Some(parent), position, scale) } pub fn position(&self, transform: Transform) -> Vec2 { self.transforms[transform.0].position } pub fn global(&self, transform: Transform) -> Matrix { self.transforms[transform.0].global } pub fn set_position(&mut self, transform: Transform, position: Vec2) { self.transforms[transform.0].position = position; } pub fn update(&mut self) { for transform in self.transforms.iter_mut() { transform.dirty = true; } for index in 0 .. self.transforms.len() { self.update_transform(index); } } fn update_transform(&mut self, index: usize) { if self.transforms[index].dirty { self.transforms[index].dirty = false; let local = Matrix::model(self.transforms[index].position, self.transforms[index].scale); if let Some(parent) = self.transforms[index].parent { self.update_transform(parent.0); self.transforms[index].global = self.transforms[parent.0].global * local; } else { self.transforms[index].global = local; } } } fn add_inner(&mut self, parent: Option<Transform>, position: Vec2, scale: Vec2) -> Transform { self.transforms.push(Data { parent, position, scale, dirty: false, global: Matrix::identity(), }); Transform(self.transforms.len() - 1) } }