# HG changeset patch # User unC0Rr # Date 1676304128 -3600 # Node ID d46ad15c6dec609b8c2c349b792e2b5495ffca41 # Parent da6b67f13c12879dd4de0d1c7474bf4fa6c6dc0b Get wavefront collapse generator to work in engine diff -r da6b67f13c12 -r d46ad15c6dec rust/landgen/src/wavefront_collapse/generator.rs --- a/rust/landgen/src/wavefront_collapse/generator.rs Mon Feb 13 12:31:30 2023 +0100 +++ b/rust/landgen/src/wavefront_collapse/generator.rs Mon Feb 13 17:02:08 2023 +0100 @@ -27,6 +27,7 @@ pub struct TileDescription { pub name: String, pub edges: EdgesDescription, + pub is_negative: bool, pub can_flip: bool, pub can_mirror: bool, pub can_rotate90: bool, @@ -34,6 +35,7 @@ pub can_rotate270: bool, } +#[derive(Clone)] pub struct TemplateDescription { pub size: Size, pub tiles: Vec, @@ -50,11 +52,15 @@ fn load_image_tiles( parameters: &LandGenerationParameters, - path: &Path, + tile_description: &TileDescription, ) -> Result>> { let mut result = Vec::new(); - let file = File::open(path)?; + let file = File::open( + Path::new("../share/hedgewars/Data/Tiles") + .join(&tile_description.name) + .as_path(), + )?; let decoder = Decoder::new(BufReader::new(file)); let mut reader = decoder.read_info().unwrap(); @@ -68,36 +74,93 @@ let info = reader.next_frame(&mut buf).unwrap(); let bytes = &buf[..info.buffer_size()]; - let mut tiles_image_pixels = tiles_image.as_mut_slice().into_iter(); + let mut tiles_image_pixels = tiles_image.as_mut_slice().iter_mut(); + + let (zero, basic) = if tile_description.is_negative { + (parameters.basic(), parameters.zero()) + } else { + (parameters.zero(), parameters.basic()) + }; - for line in bytes.chunks_exact(info.line_size) { - for value in line.chunks_exact(info.color_type.samples()) { - *tiles_image_pixels - .next() - .expect("vec2d size matching image dimensions") = - if value.into_iter().all(|p| *p == 0) { - parameters.zero - } else { - parameters.basic - }; + match info.color_type.samples() { + 1 => { + for line in bytes.chunks_exact(info.line_size) { + for value in line.iter() { + *tiles_image_pixels + .next() + .expect("vec2d size matching image dimensions") = + if *value == 0 { zero } else { basic }; + } + } + } + a => { + for line in bytes.chunks_exact(info.line_size) { + for value in line.chunks_exact(a) { + print!("{:?},", value); + *tiles_image_pixels + .next() + .expect("vec2d size matching image dimensions") = + if value[0] == 0u8 { + zero + } else { + basic + }; + } + } } } - let top_edge = Edge::new("ef".to_owned(), false); - let right_edge = top_edge.reversed(); - let bottom_edge = Edge::new("ee".to_owned(), true); - let left_edge = bottom_edge.clone(); + let edges: Vec> = [ + &tile_description.edges.top, + &tile_description.edges.right, + &tile_description.edges.bottom, + &tile_description.edges.left, + ] + .iter() + .map(|descr| { + let edge = Edge::new(descr.name.clone(), descr.symmetrical.unwrap_or_default()); - let tile = - TileImage::::new(tiles_image, top_edge, right_edge, bottom_edge, left_edge); + if descr.reversed.unwrap_or_default() { + edge.reversed() + } else { + edge + } + }) + .collect(); + + let [top_edge, right_edge, bottom_edge, left_edge] = edges.as_slice() else { + unreachable!() + }; + + let tile = TileImage::::new( + tiles_image, + top_edge.clone(), + right_edge.clone(), + bottom_edge.clone(), + left_edge.clone(), + ); result.push(tile.clone()); - result.push(tile.flipped()); - result.push(tile.mirrored()); - result.push(tile.mirrored().flipped()); - result.push(tile.rotated90()); - result.push(tile.rotated180()); - result.push(tile.rotated270()); + + if tile_description.can_flip { + result.push(tile.flipped()); + } + if tile_description.can_mirror { + result.push(tile.mirrored()); + } + if tile_description.can_flip && tile_description.can_mirror { + result.push(tile.mirrored().flipped()); + } + + if tile_description.can_rotate90 { + result.push(tile.rotated90()); + } + if tile_description.can_rotate180 { + result.push(tile.rotated180()); + } + if tile_description.can_rotate270 { + result.push(tile.rotated270()); + } Ok(result) } @@ -108,8 +171,10 @@ ) -> Vec> { let mut result = Vec::new(); - if let Ok(mut tiles) = Self::load_image_tiles(parameters, Path::new("sample.png")) { - result.append(&mut tiles); + for tile_description in self.template.tiles.iter() { + if let Ok(mut tiles) = Self::load_image_tiles(parameters, tile_description) { + result.append(&mut tiles); + } } result diff -r da6b67f13c12 -r d46ad15c6dec rust/landgen/src/wavefront_collapse/wavefront_collapse.rs --- a/rust/landgen/src/wavefront_collapse/wavefront_collapse.rs Mon Feb 13 12:31:30 2023 +0100 +++ b/rust/landgen/src/wavefront_collapse/wavefront_collapse.rs Mon Feb 13 17:02:08 2023 +0100 @@ -45,7 +45,7 @@ seed_fn: F, random_numbers: &mut I, ) { - self.grid = Vec2D::new(&map_size, Tile::Empty); + self.grid = Vec2D::new(map_size, Tile::Empty); seed_fn(&mut self.grid); @@ -56,12 +56,8 @@ self.rules = rules; } - pub fn add_rule(&mut self, rule: CollapseRule) { - self.rules.push(rule); - } - fn get_tile(&self, y: usize, x: usize) -> Tile { - self.grid.get(y, x).map(|p| *p).unwrap_or_default() + self.grid.get(y, x).copied().unwrap_or_default() } fn collapse_step>(&mut self, random_numbers: &mut I) -> bool { @@ -119,7 +115,7 @@ ); println!("Rules are: {:?}", self.rules);*/ - todo!("no collapse possible - what to do?") + //todo!("no collapse possible - what to do?") } } } diff -r da6b67f13c12 -r d46ad15c6dec rust/lib-hwengine-future/src/lib.rs --- a/rust/lib-hwengine-future/src/lib.rs Mon Feb 13 12:31:30 2023 +0100 +++ b/rust/lib-hwengine-future/src/lib.rs Mon Feb 13 17:02:08 2023 +0100 @@ -1,8 +1,8 @@ use integral_geometry::{Point, Size}; -use land2d; + use landgen::{ - outline_template_based::{ - outline_template::OutlineTemplate, template_based::TemplatedLandGenerator, + wavefront_collapse::generator::{ + TemplateDescription as WfcTemplate, }, LandGenerationParameters, LandGenerator, }; @@ -62,18 +62,18 @@ let mut random_numbers_gen = LaggedFibonacciPRNG::new(seed.as_bytes()); let yaml_templates = - fs::read_to_string(data_path.join(Path::new("map_templates.yaml")).as_path()) + fs::read_to_string(data_path.join(Path::new("wfc_templates.yaml")).as_path()) .expect("Error reading map templates file"); - let mut map_gen = MapGenerator::::new(); + let mut map_gen = MapGenerator::::new(); map_gen.import_yaml_templates(&yaml_templates); let distance_divisor = feature_size.pow(2) / 8 + 10; let params = LandGenerationParameters::new(0u16, 0x8000u16, distance_divisor, false, false); let template = map_gen .get_template(template_type, &mut random_numbers_gen) - .expect("Error reading map templates file") + .expect("Error reading templates file") .clone(); - let landgen = TemplatedLandGenerator::new(template); + let landgen = map_gen.build_generator(template); let collision = landgen.generate_land(¶ms, &mut random_numbers_gen); let size = collision.size().size(); diff -r da6b67f13c12 -r d46ad15c6dec rust/mapgen/src/lib.rs --- a/rust/mapgen/src/lib.rs Mon Feb 13 12:31:30 2023 +0100 +++ b/rust/mapgen/src/lib.rs Mon Feb 13 17:02:08 2023 +0100 @@ -4,7 +4,7 @@ use self::theme::Theme; use crate::template::outline::TemplateCollectionDesc as OutlineTemplateCollectionDesc; use crate::template::wavefront_collapse::TemplateCollectionDesc as WfcTemplateCollectionDesc; -use integral_geometry::{Point, Rect, Size}; + use land2d::Land2D; use landgen::{ outline_template_based::{ @@ -16,9 +16,9 @@ LandGenerationParameters, LandGenerator, }; use rand::{seq::SliceRandom, Rng}; -use serde_derive::Deserialize; -use serde_yaml; -use std::{borrow::Borrow, collections::hash_map::HashMap, mem::replace}; + + +use std::{borrow::Borrow, collections::hash_map::HashMap}; use vec2d::Vec2D; #[derive(PartialEq, Eq, Hash, Clone, Debug)] @@ -124,7 +124,7 @@ impl MapGenerator { pub fn import_yaml_templates(&mut self, text: &str) { let mut desc: OutlineTemplateCollectionDesc = serde_yaml::from_str(text).unwrap(); - let templates = replace(&mut desc.templates, vec![]); + let templates = std::mem::take(&mut desc.templates); self.templates = desc .template_types .into_iter() @@ -145,7 +145,7 @@ impl MapGenerator { pub fn import_yaml_templates(&mut self, text: &str) { let mut desc: WfcTemplateCollectionDesc = serde_yaml::from_str(text).unwrap(); - let templates = replace(&mut desc.templates, vec![]); + let templates = std::mem::take(&mut desc.templates); self.templates = desc .template_types .into_iter() @@ -169,7 +169,7 @@ impl Color { #[inline] fn red(self) -> u8 { - (self.0 >> 0 & 0xFF) as u8 + (self.0 & 0xFF) as u8 } #[inline] @@ -201,7 +201,7 @@ let red = lerp(target.red(), source.red(), source.alpha()); let green = lerp(target.green(), source.green(), source.alpha()); let blue = lerp(target.blue(), source.blue(), source.alpha()); - (red as u32) << 0 | (green as u32) << 8 | (blue as u32) << 16 | (alpha as u32) << 24 + (red as u32) | (green as u32) << 8 | (blue as u32) << 16 | (alpha as u32) << 24 } fn land_border_pass<'a, LandT, T, F>( diff -r da6b67f13c12 -r d46ad15c6dec rust/mapgen/src/template/outline.rs --- a/rust/mapgen/src/template/outline.rs Mon Feb 13 12:31:30 2023 +0100 +++ b/rust/mapgen/src/template/outline.rs Mon Feb 13 17:02:08 2023 +0100 @@ -1,11 +1,11 @@ use integral_geometry::{Point, Rect, Size}; -use land2d::Land2D; + use landgen::{ - outline_template_based::outline_template::OutlineTemplate, LandGenerationParameters, + outline_template_based::outline_template::OutlineTemplate, }; use serde_derive::Deserialize; -use serde_yaml; -use std::{borrow::Borrow, collections::hash_map::HashMap, mem::replace}; + +use std::{collections::hash_map::HashMap}; #[derive(Deserialize)] pub struct PointDesc { diff -r da6b67f13c12 -r d46ad15c6dec rust/mapgen/src/template/wavefront_collapse.rs --- a/rust/mapgen/src/template/wavefront_collapse.rs Mon Feb 13 12:31:30 2023 +0100 +++ b/rust/mapgen/src/template/wavefront_collapse.rs Mon Feb 13 17:02:08 2023 +0100 @@ -1,9 +1,9 @@ -use integral_geometry::{Point, Rect, Size}; -use land2d::Land2D; -use landgen::{wavefront_collapse::generator::*, LandGenerationParameters}; +use integral_geometry::{Size}; + +use landgen::{wavefront_collapse::generator::*}; use serde_derive::Deserialize; -use serde_yaml; -use std::{borrow::Borrow, collections::hash_map::HashMap, mem::replace}; + +use std::{collections::hash_map::HashMap}; #[derive(Deserialize)] #[serde(remote = "EdgeDescription")] @@ -32,6 +32,7 @@ pub name: String, #[serde(with = "EdgesDesc")] pub edges: EdgesDescription, + pub is_negative: bool, pub can_flip: bool, pub can_mirror: bool, pub can_rotate90: bool, @@ -46,7 +47,7 @@ pub struct TemplateDesc { pub width: usize, pub height: usize, - pub can_flip: bool, + pub can_invert: bool, pub is_negative: bool, pub put_girders: bool, pub max_hedgehogs: u8, diff -r da6b67f13c12 -r d46ad15c6dec share/hedgewars/Data/Tiles/120_bar.png Binary file share/hedgewars/Data/Tiles/120_bar.png has changed diff -r da6b67f13c12 -r d46ad15c6dec share/hedgewars/Data/Tiles/120_corner.png Binary file share/hedgewars/Data/Tiles/120_corner.png has changed diff -r da6b67f13c12 -r d46ad15c6dec share/hedgewars/Data/Tiles/120_filled.png Binary file share/hedgewars/Data/Tiles/120_filled.png has changed diff -r da6b67f13c12 -r d46ad15c6dec share/hedgewars/Data/Tiles/120_two_corners.png Binary file share/hedgewars/Data/Tiles/120_two_corners.png has changed diff -r da6b67f13c12 -r d46ad15c6dec share/hedgewars/Data/wfc_templates.yaml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/wfc_templates.yaml Mon Feb 13 17:02:08 2023 +0100 @@ -0,0 +1,137 @@ +# Templates for wavefront collapse map generator in hedgewars + +templates: + # 00 + - + width: 3960 + height: 1980 + can_invert: false + is_negative: false + put_girders: true + max_hedgehogs: 40 + tiles: + - name: "120_bar.png" + edges: + top: + name: "ff" + symmetrical: true + right: + name: "fe" + bottom: + name: "ee" + symmetrical: true + left: + name: "fe" + reversed: true + is_negative: true + can_mirror: false + can_flip: false + can_rotate90: true + can_rotate180: true + can_rotate270: true + - name: "120_corner.png" + edges: + top: + name: "fe" + right: + name: "ee" + symmetrical: true + bottom: + name: "ee" + symmetrical: true + left: + name: "fe" + reversed: true + is_negative: true + can_mirror: false + can_flip: false + can_rotate90: true + can_rotate180: true + can_rotate270: true + - name: "120_corner.png" + edges: + top: + name: "fe" + reversed: true + right: + name: "ff" + symmetrical: true + bottom: + name: "ff" + symmetrical: true + left: + name: "fe" + is_negative: false + can_mirror: false + can_flip: false + can_rotate90: true + can_rotate180: true + can_rotate270: true + - name: "120_filled.png" + edges: + top: + name: "ff" + symmetrical: true + right: + name: "ff" + symmetrical: true + bottom: + name: "ff" + symmetrical: true + left: + name: "ff" + symmetrical: true + is_negative: true + can_mirror: false + can_flip: false + can_rotate90: false + can_rotate180: false + can_rotate270: false + - name: "120_filled.png" + edges: + top: + name: "ee" + symmetrical: true + right: + name: "ee" + symmetrical: true + bottom: + name: "ee" + symmetrical: true + left: + name: "ee" + symmetrical: true + is_negative: false + can_mirror: false + can_flip: false + can_rotate90: false + can_rotate180: false + can_rotate270: false + - name: "120_two_corners.png" + edges: + top: + name: "fe" + right: + name: "fe" + reversed: true + bottom: + name: "fe" + left: + name: "fe" + reversed: true + is_negative: true + can_mirror: true + can_flip: false + can_rotate90: false + can_rotate180: false + can_rotate270: false + + + + +template_types: + small: [0] + medium: [0] + large: [0] + cavern: [0] + wacky: [0]