rust/landgen/src/wavefront_collapse/generator.rs
author unC0Rr
Mon, 13 Feb 2023 17:02:08 +0100
branchtransitional_engine
changeset 15923 d46ad15c6dec
parent 15922 da6b67f13c12
child 15924 9502611bffc1
permissions -rw-r--r--
Get wavefront collapse generator to work in engine
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
     1
use super::tile_image::{Edge, TileImage};
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
     2
use super::wavefront_collapse::{CollapseRule, Tile, WavefrontCollapse};
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
     3
use crate::{LandGenerationParameters, LandGenerator};
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
     4
use integral_geometry::Size;
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
     5
use png::Decoder;
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
     6
use std::collections::HashSet;
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
     7
use std::fs::File;
15920
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
     8
use std::io::{BufReader, Result};
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
     9
use std::path::Path;
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    10
15922
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    11
#[derive(Clone)]
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    12
pub struct EdgeDescription {
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    13
    pub name: String,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    14
    pub reversed: Option<bool>,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    15
    pub symmetrical: Option<bool>,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    16
}
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    17
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    18
#[derive(Clone)]
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    19
pub struct EdgesDescription {
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    20
    pub top: EdgeDescription,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    21
    pub right: EdgeDescription,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    22
    pub bottom: EdgeDescription,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    23
    pub left: EdgeDescription,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    24
}
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    25
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    26
#[derive(Clone)]
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    27
pub struct TileDescription {
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    28
    pub name: String,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    29
    pub edges: EdgesDescription,
15923
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    30
    pub is_negative: bool,
15922
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    31
    pub can_flip: bool,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    32
    pub can_mirror: bool,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    33
    pub can_rotate90: bool,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    34
    pub can_rotate180: bool,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    35
    pub can_rotate270: bool,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    36
}
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    37
15923
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    38
#[derive(Clone)]
15922
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    39
pub struct TemplateDescription {
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    40
    pub size: Size,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    41
    pub tiles: Vec<TileDescription>,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    42
}
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    43
15918
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
    44
pub struct WavefrontCollapseLandGenerator {
15922
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    45
    pub template: TemplateDescription,
15918
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
    46
}
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    47
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    48
impl WavefrontCollapseLandGenerator {
15922
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    49
    pub fn new(template: TemplateDescription) -> Self {
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
    50
        Self { template }
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    51
    }
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    52
15920
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
    53
    fn load_image_tiles<T: Copy + PartialEq + Default>(
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    54
        parameters: &LandGenerationParameters<T>,
15923
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    55
        tile_description: &TileDescription,
15920
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
    56
    ) -> Result<Vec<TileImage<T, String>>> {
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    57
        let mut result = Vec::new();
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    58
15923
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    59
        let file = File::open(
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    60
            Path::new("../share/hedgewars/Data/Tiles")
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    61
                .join(&tile_description.name)
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    62
                .as_path(),
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    63
        )?;
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    64
        let decoder = Decoder::new(BufReader::new(file));
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    65
        let mut reader = decoder.read_info().unwrap();
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    66
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    67
        let info = reader.info();
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    68
        let mut tiles_image = vec2d::Vec2D::new(
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    69
            &Size::new(info.width as usize, info.height as usize),
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    70
            parameters.zero,
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    71
        );
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    72
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    73
        let mut buf = vec![0; reader.output_buffer_size()];
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    74
        let info = reader.next_frame(&mut buf).unwrap();
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    75
        let bytes = &buf[..info.buffer_size()];
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    76
15923
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    77
        let mut tiles_image_pixels = tiles_image.as_mut_slice().iter_mut();
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    78
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    79
        let (zero, basic) = if tile_description.is_negative {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    80
            (parameters.basic(), parameters.zero())
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    81
        } else {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    82
            (parameters.zero(), parameters.basic())
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    83
        };
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    84
15923
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    85
        match info.color_type.samples() {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    86
            1 => {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    87
                for line in bytes.chunks_exact(info.line_size) {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    88
                    for value in line.iter() {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    89
                        *tiles_image_pixels
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    90
                            .next()
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    91
                            .expect("vec2d size matching image dimensions") =
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    92
                            if *value == 0 { zero } else { basic };
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    93
                    }
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    94
                }
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    95
            }
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    96
            a => {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    97
                for line in bytes.chunks_exact(info.line_size) {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    98
                    for value in line.chunks_exact(a) {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    99
                        print!("{:?},", value);
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   100
                        *tiles_image_pixels
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   101
                            .next()
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   102
                            .expect("vec2d size matching image dimensions") =
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   103
                            if value[0] == 0u8 {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   104
                                zero
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   105
                            } else {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   106
                                basic
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   107
                            };
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   108
                    }
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   109
                }
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   110
            }
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   111
        }
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   112
15923
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   113
        let edges: Vec<Edge<String>> = [
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   114
            &tile_description.edges.top,
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   115
            &tile_description.edges.right,
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   116
            &tile_description.edges.bottom,
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   117
            &tile_description.edges.left,
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   118
        ]
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   119
        .iter()
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   120
        .map(|descr| {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   121
            let edge = Edge::new(descr.name.clone(), descr.symmetrical.unwrap_or_default());
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   122
15923
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   123
            if descr.reversed.unwrap_or_default() {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   124
                edge.reversed()
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   125
            } else {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   126
                edge
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   127
            }
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   128
        })
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   129
        .collect();
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   130
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   131
        let [top_edge, right_edge, bottom_edge, left_edge] = edges.as_slice() else {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   132
            unreachable!()
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   133
        };
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   134
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   135
        let tile = TileImage::<T, String>::new(
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   136
            tiles_image,
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   137
            top_edge.clone(),
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   138
            right_edge.clone(),
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   139
            bottom_edge.clone(),
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   140
            left_edge.clone(),
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   141
        );
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   142
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   143
        result.push(tile.clone());
15923
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   144
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   145
        if tile_description.can_flip {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   146
            result.push(tile.flipped());
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   147
        }
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   148
        if tile_description.can_mirror {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   149
            result.push(tile.mirrored());
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   150
        }
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   151
        if tile_description.can_flip && tile_description.can_mirror {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   152
            result.push(tile.mirrored().flipped());
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   153
        }
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   154
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   155
        if tile_description.can_rotate90 {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   156
            result.push(tile.rotated90());
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   157
        }
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   158
        if tile_description.can_rotate180 {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   159
            result.push(tile.rotated180());
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   160
        }
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   161
        if tile_description.can_rotate270 {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   162
            result.push(tile.rotated270());
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   163
        }
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   164
15920
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   165
        Ok(result)
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   166
    }
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   167
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   168
    pub fn load_template<T: Copy + PartialEq + Default>(
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   169
        &self,
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   170
        parameters: &LandGenerationParameters<T>,
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   171
    ) -> Vec<TileImage<T, String>> {
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   172
        let mut result = Vec::new();
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   173
15923
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   174
        for tile_description in self.template.tiles.iter() {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   175
            if let Ok(mut tiles) = Self::load_image_tiles(parameters, tile_description) {
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   176
                result.append(&mut tiles);
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   177
            }
15920
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   178
        }
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   179
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   180
        result
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
   181
    }
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
   182
}
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
   183
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
   184
impl LandGenerator for WavefrontCollapseLandGenerator {
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
   185
    fn generate_land<T: Copy + PartialEq + Default, I: Iterator<Item = u32>>(
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
   186
        &self,
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
   187
        parameters: &LandGenerationParameters<T>,
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
   188
        random_numbers: &mut I,
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
   189
    ) -> land2d::Land2D<T> {
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   190
        let tiles = self.load_template(parameters);
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   191
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   192
        let mut rules = Vec::<CollapseRule>::new();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   193
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   194
        let default_connection = HashSet::from_iter(vec![Tile::Outside, Tile::Empty].into_iter());
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   195
        for (i, tile) in tiles.iter().enumerate() {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   196
            let mut right = default_connection.clone();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   197
            let mut bottom = default_connection.clone();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   198
            let mut left = default_connection.clone();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   199
            let mut top = default_connection.clone();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   200
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   201
            for p in 0..i {
15918
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   202
                if tiles[p].left_edge().is_compatible(tile.right_edge()) {
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   203
                    rules[p].left.insert(Tile::Numbered(i));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   204
                    right.insert(Tile::Numbered(p));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   205
                }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   206
15918
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   207
                if tiles[p].right_edge().is_compatible(tile.left_edge()) {
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   208
                    rules[p].right.insert(Tile::Numbered(i));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   209
                    left.insert(Tile::Numbered(p));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   210
                }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   211
15918
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   212
                if tiles[p].top_edge().is_compatible(tile.bottom_edge()) {
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   213
                    rules[p].top.insert(Tile::Numbered(i));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   214
                    bottom.insert(Tile::Numbered(p));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   215
                }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   216
15918
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   217
                if tiles[p].bottom_edge().is_compatible(tile.top_edge()) {
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   218
                    rules[p].bottom.insert(Tile::Numbered(i));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   219
                    top.insert(Tile::Numbered(p));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   220
                }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   221
            }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   222
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   223
            rules.push(CollapseRule {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   224
                tile: Tile::Numbered(i),
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   225
                top,
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   226
                right,
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   227
                bottom,
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   228
                left,
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   229
            });
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   230
        }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   231
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   232
        let mut wfc = WavefrontCollapse::default();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   233
        wfc.set_rules(rules);
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   234
15918
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   235
        let wfc_size = if let Some(first_tile) = tiles.first() {
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   236
            let tile_size = first_tile.size();
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   237
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   238
            Size::new(
15922
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
   239
                self.template.size.width / tile_size.width,
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
   240
                self.template.size.height / tile_size.height,
15918
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   241
            )
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   242
        } else {
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   243
            Size::new(1, 1)
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   244
        };
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   245
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   246
        wfc.generate_map(&wfc_size, |_| {}, random_numbers);
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   247
15922
da6b67f13c12 Refactor mapgen to allow for easy switching between generators
unC0Rr
parents: 15920
diff changeset
   248
        let mut result = land2d::Land2D::new(&self.template.size, parameters.zero);
15918
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   249
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   250
        for row in 0..wfc_size.height {
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   251
            for column in 0..wfc_size.width {
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   252
                if let Some(Tile::Numbered(tile_index)) = wfc.grid().get(row, column) {
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   253
                    let tile = &tiles[*tile_index];
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   254
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   255
                    for tile_row in 0..tile.size().height {
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   256
                        for tile_column in 0..tile.size().width {
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   257
                            result.map(
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   258
                                (row * tile.size().height + tile_row) as i32,
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   259
                                (column * tile.size().width + tile_column) as i32,
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   260
                                |p| {
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   261
                                    *p =
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   262
                                        *tile.get(tile_row, tile_column).unwrap_or(&parameters.zero)
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   263
                                },
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   264
                            );
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   265
                        }
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   266
                    }
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   267
                }
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   268
            }
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   269
        }
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   270
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   271
        result
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
   272
    }
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
   273
}
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   274
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   275
#[cfg(test)]
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   276
mod tests {
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   277
    use super::WavefrontCollapseLandGenerator;
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   278
    use crate::{LandGenerationParameters, LandGenerator};
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   279
    use integral_geometry::Size;
15918
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   280
    use std::fs::File;
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   281
    use std::io::BufWriter;
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   282
    use std::path::Path;
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   283
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   284
    #[test]
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   285
    fn test_generation() {
15918
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   286
        let wfc_gen = WavefrontCollapseLandGenerator::new(&Size::new(2048, 1024));
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   287
        let landgen_params = LandGenerationParameters::new(0u32, 0xff000000u32, 0, true, true);
15920
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   288
        let land = wfc_gen.generate_land(
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   289
            &landgen_params,
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   290
            &mut [0u32, 1u32, 3u32, 5u32, 7u32, 11u32].into_iter().cycle(),
168f44ef9b67 Extract tile loading into separate method
unC0Rr
parents: 15919
diff changeset
   291
        );
15918
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   292
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   293
        let path = Path::new(r"output.png");
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   294
        let file = File::create(path).unwrap();
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   295
        let ref mut w = BufWriter::new(file);
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   296
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   297
        let mut encoder = png::Encoder::new(w, land.width() as u32, land.height() as u32); // Width is 2 pixels and height is 1.
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   298
        encoder.set_color(png::ColorType::Rgba);
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   299
        encoder.set_depth(png::BitDepth::Eight);
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   300
        encoder.set_source_gamma(png::ScaledFloat::from_scaled(45455)); // 1.0 / 2.2, scaled by 100000
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   301
        encoder.set_source_gamma(png::ScaledFloat::new(1.0 / 2.2)); // 1.0 / 2.2, unscaled, but rounded
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   302
        let source_chromaticities = png::SourceChromaticities::new(
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   303
            // Using unscaled instantiation here
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   304
            (0.31270, 0.32900),
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   305
            (0.64000, 0.33000),
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   306
            (0.30000, 0.60000),
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   307
            (0.15000, 0.06000),
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   308
        );
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   309
        encoder.set_source_chromaticities(source_chromaticities);
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   310
        let mut writer = encoder.write_header().unwrap();
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   311
9bd828451d77 Fix several issues with transformations, more work on getting generated image
unC0Rr
parents: 15917
diff changeset
   312
        writer.write_image_data(land.raw_pixel_bytes()).unwrap(); // Save
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   313
    }
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   314
}