main.rs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. #[macro_use]
  2. extern crate serde_derive;
  3. extern crate serde;
  4. extern crate serde_json;
  5. use std::io::BufWriter;
  6. use std::io::BufReader;
  7. use std::fs::File;
  8. use std::ops::{Add, Sub, Div};
  9. use std::collections::HashMap;
  10. // use nalgebra::Vector3;
  11. #[macro_use] extern crate log;
  12. extern crate simplelog;
  13. use simplelog::*;
  14. #[derive(Clone, Debug, Serialize, Deserialize, Copy, Eq, PartialEq, Hash)]
  15. struct V3 {
  16. x: i32,
  17. y: i32,
  18. z: i32
  19. }
  20. impl V3 {
  21. fn new(x: i32, y: i32, z: i32) -> V3 {
  22. V3 { x: x, y: y, z: z }
  23. }
  24. fn neighbors(self) -> [V3;6] {
  25. let o = self.offsets();
  26. [
  27. self+o[0],
  28. self+o[1],
  29. self+o[2],
  30. self+o[3],
  31. self+o[4],
  32. self+o[5]
  33. ]
  34. }
  35. fn offsets(self) -> [V3;6] {
  36. [
  37. V3::new(1,0,0),
  38. V3::new(-1,0,0),
  39. V3::new(0,1,0),
  40. V3::new(0,-1,0),
  41. V3::new(0,0,1),
  42. V3::new(0,0,-1),
  43. ]
  44. }
  45. }
  46. impl Add<V3> for V3 {
  47. type Output = V3;
  48. fn add(self, other: V3) -> V3 {
  49. V3 {
  50. x: self.x + other.x,
  51. y: self.y + other.y,
  52. z: self.z + other.z,
  53. }
  54. }
  55. }
  56. impl Add<i32> for V3 {
  57. type Output = V3;
  58. fn add(self, other: i32) -> V3 {
  59. V3 {
  60. x: self.x + other,
  61. y: self.y + other,
  62. z: self.z + other,
  63. }
  64. }
  65. }
  66. impl<'a, 'b> Add<&'b V3> for &'a V3 {
  67. type Output = V3;
  68. fn add(self, other: &'b V3) -> V3 {
  69. V3 {
  70. x: self.x + other.x,
  71. y: self.y + other.y,
  72. z: self.z + other.z,
  73. }
  74. }
  75. }
  76. // impl Sub<V3> for V3 {
  77. // type Output = V3;
  78. // fn sub(self, other: V3) -> V3 {
  79. // V3 {
  80. // x: self.x - other.x,
  81. // y: self.y - other.y,
  82. // z: self.z - other.z,
  83. // }
  84. // }
  85. // }
  86. // #[derive(Clone, Debug)]
  87. // struct Voxel {
  88. // id: String,
  89. // // adjacency: HashMap<&'static str, u16>,
  90. // adjacency: HashMap<V3, Vec<String>>,
  91. // // offsets: [V3; 6]
  92. // }
  93. /// A graphics tile as ex- or imported from a 3d program
  94. #[derive(Clone, Debug, Serialize, Deserialize)]
  95. struct GfxTile {
  96. name: String,
  97. pos: Vec<f32>,
  98. }
  99. fn unitized_grid(vol: &HashMap<V3, String>, divisor: i32) -> HashMap<V3, String> {
  100. vol.iter().map(|(k,v)| (V3{x: k.x/divisor, y: k.y/divisor, z: k.z/divisor},v.clone())).collect()
  101. }
  102. fn guess_gridsize(vol: &HashMap<V3, String>) -> i32{
  103. let mut x_positions: Vec<i32> = vol.iter().map(|(k,v)| k.x).collect();
  104. x_positions.sort();
  105. x_positions.dedup();
  106. let mut dist_count: HashMap<i32, i32> = HashMap::new();
  107. let mut last: Option<i32> = None;
  108. for px in x_positions {
  109. if let Some(l) = last {
  110. let delta = px.abs() - l;
  111. let c = dist_count.entry(delta.abs()).or_insert(1);
  112. *c += 1;
  113. }
  114. last = Some(px.abs());
  115. }
  116. let mut grid = 1;
  117. let mut maxcount = 0;
  118. for (size, count) in dist_count {
  119. if count > maxcount {
  120. grid = size;
  121. maxcount = count;
  122. }
  123. }
  124. // dbg!(&grid);
  125. grid
  126. }
  127. fn train_volume(vol: &HashMap<V3, String>) -> HashMap<String, HashMap<V3, Vec<String>>> {
  128. let mut trained: HashMap<String, HashMap<V3, Vec<String>>> = HashMap::new();
  129. for (pos, tilename) in vol {
  130. // lookup neighbors
  131. let tile = trained.entry(tilename.clone()).or_insert(
  132. HashMap::new()
  133. );
  134. for p_o in pos.offsets().iter() {
  135. let p_n = p_o + pos;
  136. if let Some(neighbor) = vol.get(&p_n) {
  137. if let Some(neighbor_tile) = tile.get_mut(&p_o) {
  138. neighbor_tile.push(neighbor.clone());
  139. } else {
  140. tile.insert(p_o.clone(), vec![neighbor.clone()]);
  141. }
  142. }
  143. }
  144. }
  145. trained
  146. }
  147. fn load_export(path: &'static str) -> HashMap<V3, String> {
  148. let reader = BufReader::new(File::open(path).unwrap());
  149. let loaded_tiles: Vec<GfxTile> = serde_json::from_reader(reader).unwrap();
  150. loaded_tiles
  151. .iter()
  152. .map(|x| {
  153. (V3::new(x.pos[0] as i32, x.pos[1] as i32, x.pos[2] as i32), x.name.clone())
  154. })
  155. .collect()
  156. }
  157. fn get_adjacent_tiles(grid: &HashMap<V3, String>, training_data: &HashMap<String, HashMap<V3, Vec<String>>>) -> HashMap<V3, String> {
  158. let mut adjacents: HashMap<V3, String> = HashMap::new();
  159. for (pos, tile) in grid {
  160. }
  161. adjacents
  162. }
  163. fn get_unsolved_neighbors(cell: &V3, grid: &HashMap<V3, String>) -> Vec<V3> {
  164. let mut neighbors = vec![];
  165. for n in &cell.neighbors() {
  166. if !grid.contains_key(n) {
  167. neighbors.push(n.clone());
  168. }
  169. }
  170. neighbors
  171. }
  172. fn wfc_solver(training_data: HashMap<String, HashMap<V3, Vec<String>>>) -> HashMap<V3, String> {
  173. let mut new_grid: HashMap<V3, String> = HashMap::new();
  174. // init start conditions
  175. new_grid.insert(V3::new(10, 0, 0), String::from("grass"));
  176. for (pos, name) in &new_grid {
  177. for unsolved_neighbor in get_unsolved_neighbors(pos, &new_grid) {
  178. println!("Solving {:?} (next to {})", unsolved_neighbor, name);
  179. let trained_data_for_this_tile = training_data.get(name).unwrap();
  180. }
  181. }
  182. new_grid
  183. }
  184. fn main() {
  185. let _ = simplelog::SimpleLogger::init(LevelFilter::Info, Config::default());
  186. let mut import_volume: HashMap<V3, String> = HashMap::new();
  187. let imported_tiles = load_export("out.json");
  188. let gridsize = guess_gridsize(&imported_tiles);
  189. info!("Detected grid size: {}", gridsize);
  190. let imported_tiles = unitized_grid(&imported_tiles, gridsize);
  191. info!("Tiles imported: {}", imported_tiles.len());
  192. for (pos, tile) in imported_tiles {
  193. import_volume.insert(pos, tile);
  194. }
  195. let training_data = train_volume(&import_volume);
  196. info!("Training done: {} tiles", training_data.len());
  197. // for (tilename, adjacency_map) in training_data {
  198. // println!("\n{}", tilename);
  199. // for (pos, fitting_tiles) in adjacency_map{
  200. // println!("{:?}{:?}", pos, fitting_tiles);
  201. // }
  202. // }
  203. let new_grid: HashMap<V3, String> = HashMap::new();
  204. wfc_solver(training_data);
  205. // dbg!(&vol);
  206. // let mut adj_map: HashMap<String, Adjacency> = HashMap::new();
  207. }