rust/landgen/src/wavefront_collapse/tile_image.rs
changeset 16108 65c017453e83
parent 16106 aba25f4e4645
child 16109 2fc37552b587
equal deleted inserted replaced
16107:e12d9a4d0e04 16108:65c017453e83
    33     pub fn is_compatible(&self, other: &Self) -> bool {
    33     pub fn is_compatible(&self, other: &Self) -> bool {
    34         self.id == other.id && ((self.reverse != other.reverse) || self.symmetrical)
    34         self.id == other.id && ((self.reverse != other.reverse) || self.symmetrical)
    35     }
    35     }
    36 }
    36 }
    37 
    37 
       
    38 impl Edge<String> {
       
    39     pub fn name(&self) -> String {
       
    40         if self.reverse {
       
    41             self.id.chars().rev().collect()
       
    42         } else {
       
    43             self.id.clone()
       
    44         }
       
    45     }
       
    46 }
       
    47 
       
    48 #[derive(PartialEq, Clone, Debug)]
       
    49 pub struct EdgeSet<I: PartialEq + Clone>([Edge<I>; 4]);
       
    50 
       
    51 impl<I: PartialEq + Clone> EdgeSet<I> {
       
    52     pub fn new(edge_set: [Edge<I>; 4]) -> Self {
       
    53         Self(edge_set)
       
    54     }
       
    55 
       
    56     pub fn top(&self) -> &Edge<I> {
       
    57         &self.0[0]
       
    58     }
       
    59 
       
    60     pub fn right(&self) -> &Edge<I> {
       
    61         &self.0[1]
       
    62     }
       
    63 
       
    64     pub fn bottom(&self) -> &Edge<I> {
       
    65         &self.0[2]
       
    66     }
       
    67 
       
    68     pub fn left(&self) -> &Edge<I> {
       
    69         &self.0[3]
       
    70     }
       
    71 
       
    72     pub fn mirrored(&self) -> Self {
       
    73         Self([
       
    74             self.0[0].reversed(),
       
    75             self.0[3].reversed(),
       
    76             self.0[2].reversed(),
       
    77             self.0[1].reversed(),
       
    78         ])
       
    79     }
       
    80 
       
    81     pub fn flipped(&self) -> Self {
       
    82         Self([
       
    83             self.0[2].reversed(),
       
    84             self.0[1].reversed(),
       
    85             self.0[0].reversed(),
       
    86             self.0[3].reversed(),
       
    87         ])
       
    88     }
       
    89 
       
    90     pub fn rotated90(&self) -> Self {
       
    91         Self([
       
    92             self.0[3].clone(),
       
    93             self.0[0].clone(),
       
    94             self.0[1].clone(),
       
    95             self.0[2].clone(),
       
    96         ])
       
    97     }
       
    98 
       
    99     pub fn rotated180(&self) -> Self {
       
   100         Self([
       
   101             self.0[2].clone(),
       
   102             self.0[3].clone(),
       
   103             self.0[0].clone(),
       
   104             self.0[1].clone(),
       
   105         ])
       
   106     }
       
   107 
       
   108     pub fn rotated270(&self) -> Self {
       
   109         Self([
       
   110             self.0[1].clone(),
       
   111             self.0[2].clone(),
       
   112             self.0[3].clone(),
       
   113             self.0[0].clone(),
       
   114         ])
       
   115     }
       
   116 }
       
   117 
       
   118 #[derive(PartialEq, Clone, Debug)]
       
   119 pub enum MatchSide {
       
   120     OnTop,
       
   121     OnRight,
       
   122     OnBottom,
       
   123     OnLeft,
       
   124 }
    38 #[derive(Clone)]
   125 #[derive(Clone)]
    39 pub struct TileImage<T, I: PartialEq + Clone> {
   126 pub struct TileImage<T, I: PartialEq + Clone> {
    40     image: Rc<Vec2D<T>>,
   127     image: Rc<Vec2D<T>>,
    41     pub weight: u8,
   128     pub weight: u8,
    42     pub transform: Transform,
   129     pub transform: Transform,
    43     top: Edge<I>,
   130     edges: EdgeSet<I>,
    44     right: Edge<I>,
   131     anti_match: [u64; 4],
    45     bottom: Edge<I>,
       
    46     left: Edge<I>,
       
    47 }
   132 }
    48 
   133 
    49 impl<T: Copy, I: PartialEq + Clone> TileImage<T, I> {
   134 impl<T: Copy, I: PartialEq + Clone> TileImage<T, I> {
    50     pub fn new(
   135     pub fn new(image: Vec2D<T>, weight: u8, edges: EdgeSet<I>, anti_match: [u64; 4]) -> Self {
    51         image: Vec2D<T>,
       
    52         weight: u8,
       
    53         top: Edge<I>,
       
    54         right: Edge<I>,
       
    55         bottom: Edge<I>,
       
    56         left: Edge<I>,
       
    57     ) -> Self {
       
    58         Self {
   136         Self {
    59             image: Rc::new(image),
   137             image: Rc::new(image),
    60             weight,
   138             weight,
    61             transform: Transform::default(),
   139             transform: Transform::default(),
    62             top,
   140             edges,
    63             right,
   141             anti_match,
    64             bottom,
   142         }
    65             left,
   143     }
       
   144 
       
   145     pub fn is_compatible(&self, other: &Self, direction: MatchSide) -> bool {
       
   146         match direction {
       
   147             MatchSide::OnTop => {
       
   148                 self.anti_match[0] & other.anti_match[2] == 0
       
   149                     && self
       
   150                         .edge_set()
       
   151                         .top()
       
   152                         .is_compatible(other.edge_set().bottom())
       
   153             }
       
   154             MatchSide::OnRight => {
       
   155                 self.anti_match[1] & other.anti_match[3] == 0
       
   156                     && self
       
   157                         .edge_set()
       
   158                         .right()
       
   159                         .is_compatible(other.edge_set().left())
       
   160             }
       
   161             MatchSide::OnBottom => {
       
   162                 self.anti_match[2] & other.anti_match[0] == 0
       
   163                     && self
       
   164                         .edge_set()
       
   165                         .bottom()
       
   166                         .is_compatible(other.edge_set().top())
       
   167             }
       
   168             MatchSide::OnLeft => {
       
   169                 self.anti_match[3] & other.anti_match[1] == 0
       
   170                     && self
       
   171                         .edge_set()
       
   172                         .left()
       
   173                         .is_compatible(other.edge_set().right())
       
   174             }
    66         }
   175         }
    67     }
   176     }
    68 
   177 
    69     pub fn mirrored(&self) -> Self {
   178     pub fn mirrored(&self) -> Self {
    70         Self {
   179         Self {
    71             image: self.image.clone(),
   180             image: self.image.clone(),
    72             weight: self.weight,
   181             weight: self.weight,
    73             transform: self.transform.mirror(),
   182             transform: self.transform.mirror(),
    74             top: self.top.reversed(),
   183             edges: self.edges.mirrored(),
    75             right: self.left.reversed(),
   184             anti_match: [
    76             bottom: self.bottom.reversed(),
   185                 self.anti_match[0],
    77             left: self.right.reversed(),
   186                 self.anti_match[3],
       
   187                 self.anti_match[2],
       
   188                 self.anti_match[1],
       
   189             ],
    78         }
   190         }
    79     }
   191     }
    80 
   192 
    81     pub fn flipped(&self) -> Self {
   193     pub fn flipped(&self) -> Self {
    82         Self {
   194         Self {
    83             image: self.image.clone(),
   195             image: self.image.clone(),
    84             weight: self.weight,
   196             weight: self.weight,
    85             transform: self.transform.flip(),
   197             transform: self.transform.flip(),
    86             top: self.bottom.reversed(),
   198             edges: self.edges.flipped(),
    87             right: self.right.reversed(),
   199             anti_match: [
    88             bottom: self.top.reversed(),
   200                 self.anti_match[2],
    89             left: self.left.reversed(),
   201                 self.anti_match[1],
       
   202                 self.anti_match[0],
       
   203                 self.anti_match[3],
       
   204             ],
    90         }
   205         }
    91     }
   206     }
    92 
   207 
    93     pub fn rotated90(&self) -> Self {
   208     pub fn rotated90(&self) -> Self {
    94         Self {
   209         Self {
    95             image: self.image.clone(),
   210             image: self.image.clone(),
    96             weight: self.weight,
   211             weight: self.weight,
    97             transform: self.transform.rotate90(),
   212             transform: self.transform.rotate90(),
    98             top: self.left.clone(),
   213             edges: self.edges.rotated90(),
    99             right: self.top.clone(),
   214             anti_match: [
   100             bottom: self.right.clone(),
   215                 self.anti_match[3],
   101             left: self.bottom.clone(),
   216                 self.anti_match[0],
       
   217                 self.anti_match[1],
       
   218                 self.anti_match[2],
       
   219             ],
   102         }
   220         }
   103     }
   221     }
   104 
   222 
   105     pub fn rotated180(&self) -> Self {
   223     pub fn rotated180(&self) -> Self {
   106         Self {
   224         Self {
   107             image: self.image.clone(),
   225             image: self.image.clone(),
   108             weight: self.weight,
   226             weight: self.weight,
   109             transform: self.transform.rotate180(),
   227             transform: self.transform.rotate180(),
   110             top: self.bottom.clone(),
   228             edges: self.edges.rotated180(),
   111             right: self.left.clone(),
   229             anti_match: [
   112             bottom: self.top.clone(),
   230                 self.anti_match[2],
   113             left: self.right.clone(),
   231                 self.anti_match[3],
       
   232                 self.anti_match[0],
       
   233                 self.anti_match[1],
       
   234             ],
   114         }
   235         }
   115     }
   236     }
   116 
   237 
   117     pub fn rotated270(&self) -> Self {
   238     pub fn rotated270(&self) -> Self {
   118         Self {
   239         Self {
   119             image: self.image.clone(),
   240             image: self.image.clone(),
   120             weight: self.weight,
   241             weight: self.weight,
   121             transform: self.transform.rotate270(),
   242             transform: self.transform.rotate270(),
   122             top: self.right.clone(),
   243             edges: self.edges.rotated270(),
   123             right: self.bottom.clone(),
   244             anti_match: [
   124             bottom: self.left.clone(),
   245                 self.anti_match[1],
   125             left: self.top.clone(),
   246                 self.anti_match[2],
   126         }
   247                 self.anti_match[3],
   127     }
   248                 self.anti_match[0],
   128 
   249             ],
   129     #[inline]
   250         }
   130     pub fn right_edge(&self) -> &Edge<I> {
   251     }
   131         &self.right
   252 
   132     }
   253     #[inline]
   133 
   254     pub fn edge_set(&self) -> &EdgeSet<I> {
   134     #[inline]
   255         &self.edges
   135     pub fn bottom_edge(&self) -> &Edge<I> {
       
   136         &self.bottom
       
   137     }
       
   138 
       
   139     #[inline]
       
   140     pub fn left_edge(&self) -> &Edge<I> {
       
   141         &self.left
       
   142     }
       
   143 
       
   144     #[inline]
       
   145     pub fn top_edge(&self) -> &Edge<I> {
       
   146         &self.top
       
   147     }
   256     }
   148 
   257 
   149     #[inline]
   258     #[inline]
   150     pub fn size(&self) -> Size {
   259     pub fn size(&self) -> Size {
   151         match self.transform {
   260         match self.transform {