schematic_mesher/types/
mod.rs1mod direction;
4mod transform;
5
6pub use direction::{Direction, Axis};
7pub use transform::{BlockTransform, ElementRotation};
8
9use std::collections::HashMap;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13pub struct BlockPosition {
14 pub x: i32,
15 pub y: i32,
16 pub z: i32,
17}
18
19impl BlockPosition {
20 pub fn new(x: i32, y: i32, z: i32) -> Self {
21 Self { x, y, z }
22 }
23
24 pub fn neighbor(&self, direction: Direction) -> Self {
26 let (dx, dy, dz) = direction.offset();
27 Self {
28 x: self.x + dx,
29 y: self.y + dy,
30 z: self.z + dz,
31 }
32 }
33}
34
35#[derive(Debug, Clone, Copy, PartialEq)]
37pub struct BoundingBox {
38 pub min: [f32; 3],
39 pub max: [f32; 3],
40}
41
42impl BoundingBox {
43 pub fn new(min: [f32; 3], max: [f32; 3]) -> Self {
44 Self { min, max }
45 }
46
47 pub fn from_points(points: impl Iterator<Item = [f32; 3]>) -> Option<Self> {
48 let mut min = [f32::MAX; 3];
49 let mut max = [f32::MIN; 3];
50 let mut has_points = false;
51
52 for p in points {
53 has_points = true;
54 for i in 0..3 {
55 min[i] = min[i].min(p[i]);
56 max[i] = max[i].max(p[i]);
57 }
58 }
59
60 if has_points {
61 Some(Self { min, max })
62 } else {
63 None
64 }
65 }
66
67 pub fn dimensions(&self) -> [f32; 3] {
68 [
69 self.max[0] - self.min[0],
70 self.max[1] - self.min[1],
71 self.max[2] - self.min[2],
72 ]
73 }
74}
75
76#[derive(Debug, Clone, PartialEq, Eq)]
78pub struct InputBlock {
79 pub name: String,
81 pub properties: HashMap<String, String>,
83}
84
85impl InputBlock {
86 pub fn new(name: impl Into<String>) -> Self {
87 Self {
88 name: name.into(),
89 properties: HashMap::new(),
90 }
91 }
92
93 pub fn with_property(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
94 self.properties.insert(key.into(), value.into());
95 self
96 }
97
98 pub fn namespace(&self) -> &str {
100 self.name.split(':').next().unwrap_or("minecraft")
101 }
102
103 pub fn block_id(&self) -> &str {
105 self.name.split(':').nth(1).unwrap_or(&self.name)
106 }
107
108 pub fn is_air(&self) -> bool {
110 matches!(
111 self.name.as_str(),
112 "minecraft:air" | "minecraft:cave_air" | "minecraft:void_air" | "air"
113 )
114 }
115}
116
117pub trait BlockSource {
119 fn get_block(&self, pos: BlockPosition) -> Option<&InputBlock>;
121
122 fn iter_blocks(&self) -> Box<dyn Iterator<Item = (BlockPosition, &InputBlock)> + '_>;
124
125 fn bounds(&self) -> BoundingBox;
127}