diff -r de01be16df95 -r 2acea266d297 rust/landgen/src/wavefront_collapse/generator.rs --- a/rust/landgen/src/wavefront_collapse/generator.rs Sat Jan 18 16:57:26 2025 +0100 +++ b/rust/landgen/src/wavefront_collapse/generator.rs Tue Jan 21 22:10:55 2025 +0100 @@ -9,14 +9,14 @@ use std::io::{BufReader, Result}; use std::path::{Path, PathBuf}; -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct EdgeDescription { pub name: String, pub reversed: Option, pub symmetrical: Option, } -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct EdgesDescription { pub top: EdgeDescription, pub right: EdgeDescription, @@ -24,7 +24,7 @@ pub left: EdgeDescription, } -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct TileDescription { pub name: String, pub edges: EdgesDescription, @@ -36,19 +36,26 @@ pub can_rotate270: Option, } -#[derive(Clone)] -pub struct NonStrictEdgesDescription { - pub top: Option, - pub right: Option, - pub bottom: Option, - pub left: Option, +#[derive(Debug, Clone)] +pub struct ComplexEdgeDescription { + pub begin: Option, + pub fill: Option, + pub end: Option, } -#[derive(Clone)] +#[derive(Debug, Clone)] +pub struct NonStrictComplexEdgesDescription { + pub top: Option, + pub right: Option, + pub bottom: Option, + pub left: Option, +} + +#[derive(Debug, Clone)] pub struct TemplateDescription { pub size: Size, pub tiles: Vec, - pub edges: NonStrictEdgesDescription, + pub edges: NonStrictComplexEdgesDescription, pub wrap: bool, } @@ -79,7 +86,7 @@ .as_path(), )?; let decoder = Decoder::new(BufReader::new(file)); - let mut reader = decoder.read_info().unwrap(); + let mut reader = decoder.read_info()?; let info = reader.info(); let mut tiles_image = vec2d::Vec2D::new( @@ -88,7 +95,7 @@ ); let mut buf = vec![0; reader.output_buffer_size()]; - let info = reader.next_frame(&mut buf).unwrap(); + let info = reader.next_frame(&mut buf)?; let bytes = &buf[..info.buffer_size()]; let mut tiles_image_pixels = tiles_image.as_mut_slice().iter_mut(); @@ -183,14 +190,14 @@ probability_distribution_factor: i32, ) -> Vec { let [grid_top_edge, grid_right_edge, grid_bottom_edge, grid_left_edge]: [Option< - Edge, + [Option>; 3], >; 4] = [ self.template.edges.top.as_ref(), self.template.edges.right.as_ref(), self.template.edges.bottom.as_ref(), self.template.edges.left.as_ref(), ] - .map(|opt| opt.map(|d| d.into())); + .map(|opt| opt.map(|d| [&d.begin, &d.fill, &d.end].map(|e| e.as_ref().map(Into::into)))); let mut rules = Vec::::new(); @@ -201,34 +208,32 @@ let mut left = default_connection.clone(); let mut top = default_connection.clone(); + let iteration = [ + (&grid_top_edge, tile.top_edge(), &mut top), + (&grid_right_edge, tile.right_edge(), &mut right), + (&grid_bottom_edge, tile.bottom_edge(), &mut bottom), + (&grid_left_edge, tile.left_edge(), &mut left), + ]; + // compatibility with grid edges - if grid_top_edge - .as_ref() - .map(|e| e.is_compatible(tile.top_edge())) - .unwrap_or(true) - { - top.insert(Tile::Outside); - } - if grid_right_edge - .as_ref() - .map(|e| e.is_compatible(tile.right_edge())) - .unwrap_or(true) - { - right.insert(Tile::Outside); - } - if grid_bottom_edge - .as_ref() - .map(|e| e.is_compatible(tile.bottom_edge())) - .unwrap_or(true) - { - bottom.insert(Tile::Outside); - } - if grid_left_edge - .as_ref() - .map(|e| e.is_compatible(tile.left_edge())) - .unwrap_or(true) - { - left.insert(Tile::Outside); + for (edge, tile_edge, set) in iteration { + for (is_compatible, tile) in edge + .as_ref() + .map(|e| { + e.clone().map(|ed| { + ed.as_ref() + .map(|e| e.is_compatible(tile_edge)) + .unwrap_or(true) + }) + }) + .unwrap_or([true, true, true]) + .into_iter() + .zip([Tile::OutsideBegin, Tile::OutsideFill, Tile::OutsideEnd].into_iter()) + { + if is_compatible { + set.insert(tile); + } + } } // compatibility with itself @@ -244,21 +249,25 @@ // compatibility with previously defined tiles for p in 0..i { + // Check left edge if tiles[p].left_edge().is_compatible(tile.right_edge()) { rules[p].left.insert(Tile::Numbered(i)); right.insert(Tile::Numbered(p)); } + // Check right edge if tiles[p].right_edge().is_compatible(tile.left_edge()) { rules[p].right.insert(Tile::Numbered(i)); left.insert(Tile::Numbered(p)); } + // Check top edge if tiles[p].top_edge().is_compatible(tile.bottom_edge()) { rules[p].top.insert(Tile::Numbered(i)); bottom.insert(Tile::Numbered(p)); } + // Check bottom edge if tiles[p].bottom_edge().is_compatible(tile.top_edge()) { rules[p].bottom.insert(Tile::Numbered(i)); top.insert(Tile::Numbered(p));