1use core::fmt;
4use core::ops::*;
5
6#[inline(always)]
8#[must_use]
9pub const fn bvec3(x: bool, y: bool, z: bool) -> BVec3 {
10 BVec3::new(x, y, z)
11}
12
13#[derive(Clone, Copy, PartialEq, Eq, Hash)]
15#[repr(C, align(1))]
16pub struct BVec3 {
17 pub x: bool,
18 pub y: bool,
19 pub z: bool,
20}
21
22const MASK: [u32; 2] = [0, 0xff_ff_ff_ff];
23
24impl BVec3 {
25 pub const FALSE: Self = Self::splat(false);
27
28 pub const TRUE: Self = Self::splat(true);
30
31 #[inline(always)]
33 #[must_use]
34 pub const fn new(x: bool, y: bool, z: bool) -> Self {
35 Self { x, y, z }
36 }
37
38 #[inline]
40 #[must_use]
41 pub const fn splat(v: bool) -> Self {
42 Self::new(v, v, v)
43 }
44
45 #[inline]
47 #[must_use]
48 pub const fn from_array(a: [bool; 3]) -> Self {
49 Self::new(a[0], a[1], a[2])
50 }
51
52 #[inline]
57 #[must_use]
58 pub fn bitmask(self) -> u32 {
59 (self.x as u32) | (self.y as u32) << 1 | (self.z as u32) << 2
60 }
61
62 #[inline]
64 #[must_use]
65 pub fn any(self) -> bool {
66 self.x || self.y || self.z
67 }
68
69 #[inline]
71 #[must_use]
72 pub fn all(self) -> bool {
73 self.x && self.y && self.z
74 }
75
76 #[inline]
80 #[must_use]
81 pub fn test(&self, index: usize) -> bool {
82 match index {
83 0 => self.x,
84 1 => self.y,
85 2 => self.z,
86 _ => panic!("index out of bounds"),
87 }
88 }
89
90 #[inline]
94 pub fn set(&mut self, index: usize, value: bool) {
95 match index {
96 0 => self.x = value,
97 1 => self.y = value,
98 2 => self.z = value,
99 _ => panic!("index out of bounds"),
100 }
101 }
102
103 #[inline]
104 #[must_use]
105 fn into_bool_array(self) -> [bool; 3] {
106 [self.x, self.y, self.z]
107 }
108
109 #[inline]
110 #[must_use]
111 fn into_u32_array(self) -> [u32; 3] {
112 [
113 MASK[self.x as usize],
114 MASK[self.y as usize],
115 MASK[self.z as usize],
116 ]
117 }
118}
119
120impl Default for BVec3 {
121 #[inline]
122 fn default() -> Self {
123 Self::FALSE
124 }
125}
126
127impl BitAnd for BVec3 {
128 type Output = Self;
129 #[inline]
130 fn bitand(self, rhs: Self) -> Self {
131 Self {
132 x: self.x & rhs.x,
133 y: self.y & rhs.y,
134 z: self.z & rhs.z,
135 }
136 }
137}
138
139impl BitAndAssign for BVec3 {
140 #[inline]
141 fn bitand_assign(&mut self, rhs: Self) {
142 *self = self.bitand(rhs);
143 }
144}
145
146impl BitOr for BVec3 {
147 type Output = Self;
148 #[inline]
149 fn bitor(self, rhs: Self) -> Self {
150 Self {
151 x: self.x | rhs.x,
152 y: self.y | rhs.y,
153 z: self.z | rhs.z,
154 }
155 }
156}
157
158impl BitOrAssign for BVec3 {
159 #[inline]
160 fn bitor_assign(&mut self, rhs: Self) {
161 *self = self.bitor(rhs);
162 }
163}
164
165impl BitXor for BVec3 {
166 type Output = Self;
167 #[inline]
168 fn bitxor(self, rhs: Self) -> Self {
169 Self {
170 x: self.x ^ rhs.x,
171 y: self.y ^ rhs.y,
172 z: self.z ^ rhs.z,
173 }
174 }
175}
176
177impl BitXorAssign for BVec3 {
178 #[inline]
179 fn bitxor_assign(&mut self, rhs: Self) {
180 *self = self.bitxor(rhs);
181 }
182}
183
184impl Not for BVec3 {
185 type Output = Self;
186 #[inline]
187 fn not(self) -> Self {
188 Self {
189 x: !self.x,
190 y: !self.y,
191 z: !self.z,
192 }
193 }
194}
195
196impl fmt::Debug for BVec3 {
197 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
198 let arr = self.into_u32_array();
199 write!(
200 f,
201 "{}({:#x}, {:#x}, {:#x})",
202 stringify!(BVec3),
203 arr[0],
204 arr[1],
205 arr[2]
206 )
207 }
208}
209
210impl fmt::Display for BVec3 {
211 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
212 let arr = self.into_bool_array();
213 write!(f, "[{}, {}, {}]", arr[0], arr[1], arr[2])
214 }
215}
216
217impl From<[bool; 3]> for BVec3 {
218 #[inline]
219 fn from(a: [bool; 3]) -> Self {
220 Self::from_array(a)
221 }
222}
223
224impl From<BVec3> for [bool; 3] {
225 #[inline]
226 fn from(mask: BVec3) -> Self {
227 mask.into_bool_array()
228 }
229}
230
231impl From<BVec3> for [u32; 3] {
232 #[inline]
233 fn from(mask: BVec3) -> Self {
234 mask.into_u32_array()
235 }
236}