rust/landgen/src/wavefront_collapse/generator.rs
branchtransitional_engine
changeset 15923 d46ad15c6dec
parent 15922 da6b67f13c12
child 15924 9502611bffc1
equal deleted inserted replaced
15922:da6b67f13c12 15923:d46ad15c6dec
    25 
    25 
    26 #[derive(Clone)]
    26 #[derive(Clone)]
    27 pub struct TileDescription {
    27 pub struct TileDescription {
    28     pub name: String,
    28     pub name: String,
    29     pub edges: EdgesDescription,
    29     pub edges: EdgesDescription,
       
    30     pub is_negative: bool,
    30     pub can_flip: bool,
    31     pub can_flip: bool,
    31     pub can_mirror: bool,
    32     pub can_mirror: bool,
    32     pub can_rotate90: bool,
    33     pub can_rotate90: bool,
    33     pub can_rotate180: bool,
    34     pub can_rotate180: bool,
    34     pub can_rotate270: bool,
    35     pub can_rotate270: bool,
    35 }
    36 }
    36 
    37 
       
    38 #[derive(Clone)]
    37 pub struct TemplateDescription {
    39 pub struct TemplateDescription {
    38     pub size: Size,
    40     pub size: Size,
    39     pub tiles: Vec<TileDescription>,
    41     pub tiles: Vec<TileDescription>,
    40 }
    42 }
    41 
    43 
    48         Self { template }
    50         Self { template }
    49     }
    51     }
    50 
    52 
    51     fn load_image_tiles<T: Copy + PartialEq + Default>(
    53     fn load_image_tiles<T: Copy + PartialEq + Default>(
    52         parameters: &LandGenerationParameters<T>,
    54         parameters: &LandGenerationParameters<T>,
    53         path: &Path,
    55         tile_description: &TileDescription,
    54     ) -> Result<Vec<TileImage<T, String>>> {
    56     ) -> Result<Vec<TileImage<T, String>>> {
    55         let mut result = Vec::new();
    57         let mut result = Vec::new();
    56 
    58 
    57         let file = File::open(path)?;
    59         let file = File::open(
       
    60             Path::new("../share/hedgewars/Data/Tiles")
       
    61                 .join(&tile_description.name)
       
    62                 .as_path(),
       
    63         )?;
    58         let decoder = Decoder::new(BufReader::new(file));
    64         let decoder = Decoder::new(BufReader::new(file));
    59         let mut reader = decoder.read_info().unwrap();
    65         let mut reader = decoder.read_info().unwrap();
    60 
    66 
    61         let info = reader.info();
    67         let info = reader.info();
    62         let mut tiles_image = vec2d::Vec2D::new(
    68         let mut tiles_image = vec2d::Vec2D::new(
    66 
    72 
    67         let mut buf = vec![0; reader.output_buffer_size()];
    73         let mut buf = vec![0; reader.output_buffer_size()];
    68         let info = reader.next_frame(&mut buf).unwrap();
    74         let info = reader.next_frame(&mut buf).unwrap();
    69         let bytes = &buf[..info.buffer_size()];
    75         let bytes = &buf[..info.buffer_size()];
    70 
    76 
    71         let mut tiles_image_pixels = tiles_image.as_mut_slice().into_iter();
    77         let mut tiles_image_pixels = tiles_image.as_mut_slice().iter_mut();
    72 
    78 
    73         for line in bytes.chunks_exact(info.line_size) {
    79         let (zero, basic) = if tile_description.is_negative {
    74             for value in line.chunks_exact(info.color_type.samples()) {
    80             (parameters.basic(), parameters.zero())
    75                 *tiles_image_pixels
    81         } else {
    76                     .next()
    82             (parameters.zero(), parameters.basic())
    77                     .expect("vec2d size matching image dimensions") =
    83         };
    78                     if value.into_iter().all(|p| *p == 0) {
    84 
    79                         parameters.zero
    85         match info.color_type.samples() {
    80                     } else {
    86             1 => {
    81                         parameters.basic
    87                 for line in bytes.chunks_exact(info.line_size) {
    82                     };
    88                     for value in line.iter() {
    83             }
    89                         *tiles_image_pixels
    84         }
    90                             .next()
    85 
    91                             .expect("vec2d size matching image dimensions") =
    86         let top_edge = Edge::new("ef".to_owned(), false);
    92                             if *value == 0 { zero } else { basic };
    87         let right_edge = top_edge.reversed();
    93                     }
    88         let bottom_edge = Edge::new("ee".to_owned(), true);
    94                 }
    89         let left_edge = bottom_edge.clone();
    95             }
    90 
    96             a => {
    91         let tile =
    97                 for line in bytes.chunks_exact(info.line_size) {
    92             TileImage::<T, String>::new(tiles_image, top_edge, right_edge, bottom_edge, left_edge);
    98                     for value in line.chunks_exact(a) {
       
    99                         print!("{:?},", value);
       
   100                         *tiles_image_pixels
       
   101                             .next()
       
   102                             .expect("vec2d size matching image dimensions") =
       
   103                             if value[0] == 0u8 {
       
   104                                 zero
       
   105                             } else {
       
   106                                 basic
       
   107                             };
       
   108                     }
       
   109                 }
       
   110             }
       
   111         }
       
   112 
       
   113         let edges: Vec<Edge<String>> = [
       
   114             &tile_description.edges.top,
       
   115             &tile_description.edges.right,
       
   116             &tile_description.edges.bottom,
       
   117             &tile_description.edges.left,
       
   118         ]
       
   119         .iter()
       
   120         .map(|descr| {
       
   121             let edge = Edge::new(descr.name.clone(), descr.symmetrical.unwrap_or_default());
       
   122 
       
   123             if descr.reversed.unwrap_or_default() {
       
   124                 edge.reversed()
       
   125             } else {
       
   126                 edge
       
   127             }
       
   128         })
       
   129         .collect();
       
   130 
       
   131         let [top_edge, right_edge, bottom_edge, left_edge] = edges.as_slice() else {
       
   132             unreachable!()
       
   133         };
       
   134 
       
   135         let tile = TileImage::<T, String>::new(
       
   136             tiles_image,
       
   137             top_edge.clone(),
       
   138             right_edge.clone(),
       
   139             bottom_edge.clone(),
       
   140             left_edge.clone(),
       
   141         );
    93 
   142 
    94         result.push(tile.clone());
   143         result.push(tile.clone());
    95         result.push(tile.flipped());
   144 
    96         result.push(tile.mirrored());
   145         if tile_description.can_flip {
    97         result.push(tile.mirrored().flipped());
   146             result.push(tile.flipped());
    98         result.push(tile.rotated90());
   147         }
    99         result.push(tile.rotated180());
   148         if tile_description.can_mirror {
   100         result.push(tile.rotated270());
   149             result.push(tile.mirrored());
       
   150         }
       
   151         if tile_description.can_flip && tile_description.can_mirror {
       
   152             result.push(tile.mirrored().flipped());
       
   153         }
       
   154 
       
   155         if tile_description.can_rotate90 {
       
   156             result.push(tile.rotated90());
       
   157         }
       
   158         if tile_description.can_rotate180 {
       
   159             result.push(tile.rotated180());
       
   160         }
       
   161         if tile_description.can_rotate270 {
       
   162             result.push(tile.rotated270());
       
   163         }
   101 
   164 
   102         Ok(result)
   165         Ok(result)
   103     }
   166     }
   104 
   167 
   105     pub fn load_template<T: Copy + PartialEq + Default>(
   168     pub fn load_template<T: Copy + PartialEq + Default>(
   106         &self,
   169         &self,
   107         parameters: &LandGenerationParameters<T>,
   170         parameters: &LandGenerationParameters<T>,
   108     ) -> Vec<TileImage<T, String>> {
   171     ) -> Vec<TileImage<T, String>> {
   109         let mut result = Vec::new();
   172         let mut result = Vec::new();
   110 
   173 
   111         if let Ok(mut tiles) = Self::load_image_tiles(parameters, Path::new("sample.png")) {
   174         for tile_description in self.template.tiles.iter() {
   112             result.append(&mut tiles);
   175             if let Ok(mut tiles) = Self::load_image_tiles(parameters, tile_description) {
       
   176                 result.append(&mut tiles);
       
   177             }
   113         }
   178         }
   114 
   179 
   115         result
   180         result
   116     }
   181     }
   117 }
   182 }