rust/landgen/src/wavefront_collapse/tile_image.rs
branchtransitional_engine
changeset 15915 8f093b1b18bc
parent 15913 c5684cc62de8
child 15916 e82de0410da5
equal deleted inserted replaced
15914:c571d4b8879c 15915:8f093b1b18bc
     1 use land2d::Land2D;
     1 use vec2d::Vec2D;
     2 use std::rc::Rc;
     2 use std::rc::Rc;
       
     3 use integral_geometry::Size;
     3 
     4 
     4 pub struct TileImage {
     5 pub struct TileImage<T> {
     5     image: Rc<Land2D<u8>>,
     6     image: Rc<Vec2D<T>>,
     6     flip: bool,
     7     flip: bool,
     7     mirror: bool,
     8     mirror: bool,
     8 }
     9 }
     9 
    10 
    10 impl TileImage {
    11 impl<T: Copy> TileImage<T> {
    11     pub fn new(flip: bool, mirror: bool) -> Self {
    12     pub fn new(image: Vec2D<T>) -> Self {
    12         Self {
    13         Self {
    13             image: todo!(),
    14             image: Rc::new(image),
    14             flip,
    15             flip: false,
    15             mirror,
    16             mirror: false,
    16         }
    17         }
    17     }
    18     }
    18 
    19 
    19     pub fn mirrored(&self) -> Self {
    20     pub fn mirrored(&self) -> Self {
    20         Self {
    21         Self {
    21             image: self.image.clone(),
    22             image: self.image.clone(),
    22             flip: self.flip,
    23             flip: self.flip,
    23             mirror: !self.mirror
    24             mirror: !self.mirror,
    24         }
    25         }
    25     }
    26     }
    26 
    27 
    27     pub fn flipped(&self) -> Self {
    28     pub fn flipped(&self) -> Self {
    28         Self {
    29         Self {
    29             image: self.image.clone(),
    30             image: self.image.clone(),
    30             flip: !self.flip,
    31             flip: !self.flip,
    31             mirror: self.mirror
    32             mirror: self.mirror,
    32         }
    33         }
    33     }
    34     }
       
    35 
       
    36     pub fn split(&self, rows: usize, columns: usize) -> Vec<TileImage<T>> {
       
    37         let mut result = Vec::new();
       
    38         let self_image = self.image.as_ref();
       
    39         let (result_width, result_height) = (self_image.width() / columns, self.image.height() / rows);
       
    40 
       
    41         for row in 0..rows {
       
    42             for column in 0..columns {
       
    43                 let mut tile_pixels = Vec::new();
       
    44 
       
    45                 for out_row in 0..result_height {
       
    46                     tile_pixels.push(self_image[row * result_height + out_row][column*result_width..(column+1)*result_width].iter());
       
    47                 }
       
    48 
       
    49                 let tile_image = Vec2D::from_iter(tile_pixels.into_iter().flatten().map(|p| *p), &Size::new(result_width, result_height));
       
    50 
       
    51                 result.push(TileImage::new(tile_image.expect("correct calculation of tile dimensions")));
       
    52             }
       
    53         }
       
    54 
       
    55         result
       
    56     }
    34 }
    57 }
       
    58 
       
    59 #[cfg(test)]
       
    60 mod tests {
       
    61     use super::TileImage;
       
    62     use integral_geometry::Size;
       
    63     use vec2d::Vec2D;
       
    64 
       
    65     #[test]
       
    66     fn test_split() {
       
    67         let size = Size::new(6, 4);
       
    68         let sample_data = Vec2D::from_iter((0..24).into_iter(), &size);
       
    69 
       
    70         assert!(sample_data.is_some());
       
    71 
       
    72         let sample_data = sample_data.unwrap();
       
    73         let big_tile = TileImage::new(sample_data);
       
    74         let subtiles = big_tile.split(2, 2);
       
    75 
       
    76         assert_eq!(subtiles.len(), 4);
       
    77     }
       
    78 }