1use crate::Quad;
2
3const MASK_XYZ: u64 = 0b111111_111111_111111;
4
5#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
6pub enum Face {
7 Up,
8 Down,
9 Right,
10 Left,
11 Front,
12 Back,
13}
14
15impl From<u8> for Face {
16 fn from(value: u8) -> Self {
17 assert!(value < 6);
18 match value {
19 0 => Self::Up,
20 1 => Self::Down,
21 2 => Self::Right,
22 3 => Self::Left,
23 4 => Self::Front,
24 5 => Self::Back,
25 _ => unreachable!(),
26 }
27 }
28}
29
30#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
31pub struct Vertex(pub u32);
32
33impl Vertex {
34 const MASK_6: u32 = 0b111111;
35
36 pub fn new() -> Self {
37 Self(0u32)
38 }
39
40 pub fn pack(xyz: u32, u: u32, v: u32) -> Self {
41 Self((v << 24) | (u << 18) | xyz)
42 }
43
44 pub fn x(&self) -> u32 {
45 self.0 & Vertex::MASK_6
46 }
47
48 pub fn y(&self) -> u32 {
49 (self.0 >> 6) & Vertex::MASK_6
50 }
51
52 pub fn z(&self) -> u32 {
53 (self.0 >> 12) & Vertex::MASK_6
54 }
55
56 pub fn u(&self) -> u32 {
57 (self.0 >> 18) & Vertex::MASK_6
58 }
59
60 pub fn v(&self) -> u32 {
61 (self.0 >> 24) & Vertex::MASK_6
62 }
63
64 pub fn xyz(&self) -> [u32; 3] {
65 [self.x(), self.y(), self.z()]
66 }
67}
68
69fn packed_xyz(x: u32, y: u32, z: u32) -> u32 {
70 (z << 12) | (y << 6) | x
71}
72
73impl Face {
74 pub fn n(&self) -> [i32; 3] {
75 match self {
76 Self::Up => [0, 1, 0],
77 Self::Down => [0, -1, 0],
78 Self::Right => [1, 0, 0],
79 Self::Left => [-1, 0, 0],
80 Self::Front => [0, 0, 1],
81 Self::Back => [0, 0, -1],
82 }
83 }
84
85 pub fn opposite(&self) -> Self {
86 match self {
87 Self::Up => Self::Down,
88 Self::Down => Self::Up,
89 Self::Right => Self::Left,
90 Self::Left => Self::Right,
91 Self::Front => Self::Back,
92 Self::Back => Self::Front,
93 }
94 }
95
96 pub fn vertices_packed(&self, quad: Quad) -> [Vertex; 4] {
99 let w = quad.width() as u32;
100 let h = quad.height() as u32;
101 let xyz = (MASK_XYZ & quad.0) as u32;
102 match self {
103 Face::Left => [
104 Vertex::pack(xyz, h, w),
105 Vertex::pack(xyz + packed_xyz(0, 0, h), 0, w),
106 Vertex::pack(xyz + packed_xyz(0, w, 0), h, 0),
107 Vertex::pack(xyz + packed_xyz(0, w, h), 0, 0),
108 ],
109 Face::Down => [
110 Vertex::pack(xyz - packed_xyz(w, 0, 0) + packed_xyz(0, 0, h), w, h),
111 Vertex::pack(xyz - packed_xyz(w, 0, 0), w, 0),
112 Vertex::pack(xyz + packed_xyz(0, 0, h), 0, h),
113 Vertex::pack(xyz, 0, 0),
114 ],
115 Face::Back => [
116 Vertex::pack(xyz, w, h),
117 Vertex::pack(xyz + packed_xyz(0, h, 0), w, 0),
118 Vertex::pack(xyz + packed_xyz(w, 0, 0), 0, h),
119 Vertex::pack(xyz + packed_xyz(w, h, 0), 0, 0),
120 ],
121 Face::Right => [
122 Vertex::pack(xyz, 0, 0),
123 Vertex::pack(xyz + packed_xyz(0, 0, h), h, 0),
124 Vertex::pack(xyz - packed_xyz(0, w, 0), 0, w),
125 Vertex::pack(xyz + packed_xyz(0, 0, h) - packed_xyz(0, w, 0), h, w),
126 ],
127 Face::Up => [
128 Vertex::pack(xyz + packed_xyz(w, 0, h), w, h),
129 Vertex::pack(xyz + packed_xyz(w, 0, 0), w, 0),
130 Vertex::pack(xyz + packed_xyz(0, 0, h), 0, h),
131 Vertex::pack(xyz, 0, 0),
132 ],
133 Face::Front => [
134 Vertex::pack(xyz - packed_xyz(w, 0, 0) + packed_xyz(0, h, 0), 0, 0),
135 Vertex::pack(xyz - packed_xyz(w, 0, 0), 0, h),
136 Vertex::pack(xyz + packed_xyz(0, h, 0), w, 0),
137 Vertex::pack(xyz, w, h),
138 ],
139 }
140 }
141}