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) -> [f32; 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 vertices_packed(&self, quad: Quad) -> [Vertex; 4] {
88 let w = quad.width() as u32;
89 let h = quad.height() as u32;
90 let xyz = (MASK_XYZ & quad.0) as u32;
91 match self {
92 Face::Left => [
93 Vertex::pack(xyz, h, w),
94 Vertex::pack(xyz + packed_xyz(0, 0, h), 0, w),
95 Vertex::pack(xyz + packed_xyz(0, w, 0), h, 0),
96 Vertex::pack(xyz + packed_xyz(0, w, h), 0, 0),
97 ],
98 Face::Down => [
99 Vertex::pack(xyz - packed_xyz(w, 0, 0) + packed_xyz(0, 0, h), w, h),
100 Vertex::pack(xyz - packed_xyz(w, 0, 0), w, 0),
101 Vertex::pack(xyz + packed_xyz(0, 0, h), 0, h),
102 Vertex::pack(xyz, 0, 0),
103 ],
104 Face::Back => [
105 Vertex::pack(xyz, w, h),
106 Vertex::pack(xyz + packed_xyz(0, h, 0), w, 0),
107 Vertex::pack(xyz + packed_xyz(w, 0, 0), 0, h),
108 Vertex::pack(xyz + packed_xyz(w, h, 0), 0, 0),
109 ],
110 Face::Right => [
111 Vertex::pack(xyz, 0, 0),
112 Vertex::pack(xyz + packed_xyz(0, 0, h), h, 0),
113 Vertex::pack(xyz - packed_xyz(0, w, 0), 0, w),
114 Vertex::pack(xyz + packed_xyz(0, 0, h) - packed_xyz(0, w, 0), h, w),
115 ],
116 Face::Up => [
117 Vertex::pack(xyz + packed_xyz(w, 0, h), w, h),
118 Vertex::pack(xyz + packed_xyz(w, 0, 0), w, 0),
119 Vertex::pack(xyz + packed_xyz(0, 0, h), 0, h),
120 Vertex::pack(xyz, 0, 0),
121 ],
122 Face::Front => [
123 Vertex::pack(xyz - packed_xyz(w, 0, 0) + packed_xyz(0, h, 0), 0, 0),
124 Vertex::pack(xyz - packed_xyz(w, 0, 0), 0, h),
125 Vertex::pack(xyz + packed_xyz(0, h, 0), w, 0),
126 Vertex::pack(xyz, w, h),
127 ],
128 }
129 }
130}