Get wavefront collapse generator to work in engine transitional_engine
authorunC0Rr
Mon, 13 Feb 2023 17:02:08 +0100
branchtransitional_engine
changeset 15923 d46ad15c6dec
parent 15922 da6b67f13c12
child 15924 9502611bffc1
Get wavefront collapse generator to work in engine
rust/landgen/src/wavefront_collapse/generator.rs
rust/landgen/src/wavefront_collapse/wavefront_collapse.rs
rust/lib-hwengine-future/src/lib.rs
rust/mapgen/src/lib.rs
rust/mapgen/src/template/outline.rs
rust/mapgen/src/template/wavefront_collapse.rs
share/hedgewars/Data/Tiles/120_bar.png
share/hedgewars/Data/Tiles/120_corner.png
share/hedgewars/Data/Tiles/120_filled.png
share/hedgewars/Data/Tiles/120_two_corners.png
share/hedgewars/Data/wfc_templates.yaml
--- 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<TileDescription>,
@@ -50,11 +52,15 @@
 
     fn load_image_tiles<T: Copy + PartialEq + Default>(
         parameters: &LandGenerationParameters<T>,
-        path: &Path,
+        tile_description: &TileDescription,
     ) -> Result<Vec<TileImage<T, String>>> {
         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<Edge<String>> = [
+            &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::<T, String>::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::<T, String>::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<TileImage<T, String>> {
         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
--- 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<I: Iterator<Item = u32>>(&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?")
                     }
                 }
             }
--- 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::<OutlineTemplate>::new();
+    let mut map_gen = MapGenerator::<WfcTemplate>::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(&params, &mut random_numbers_gen);
     let size = collision.size().size();
 
--- 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<OutlineTemplate> {
     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<WfcTemplate> {
     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>(
--- 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 {
--- 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,
Binary file share/hedgewars/Data/Tiles/120_bar.png has changed
Binary file share/hedgewars/Data/Tiles/120_corner.png has changed
Binary file share/hedgewars/Data/Tiles/120_filled.png has changed
Binary file share/hedgewars/Data/Tiles/120_two_corners.png has changed
--- /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]