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 BitAnd<&Self> for BVec3 {
140 type Output = Self;
141 #[inline]
142 fn bitand(self, rhs: &Self) -> Self {
143 self.bitand(*rhs)
144 }
145}
146
147impl BitAnd<&BVec3> for &BVec3 {
148 type Output = BVec3;
149 #[inline]
150 fn bitand(self, rhs: &BVec3) -> BVec3 {
151 (*self).bitand(*rhs)
152 }
153}
154
155impl BitAnd<BVec3> for &BVec3 {
156 type Output = BVec3;
157 #[inline]
158 fn bitand(self, rhs: BVec3) -> BVec3 {
159 (*self).bitand(rhs)
160 }
161}
162
163impl BitAndAssign for BVec3 {
164 #[inline]
165 fn bitand_assign(&mut self, rhs: Self) {
166 *self = self.bitand(rhs);
167 }
168}
169
170impl BitAndAssign<&Self> for BVec3 {
171 #[inline]
172 fn bitand_assign(&mut self, rhs: &Self) {
173 self.bitand_assign(*rhs);
174 }
175}
176
177impl BitOr for BVec3 {
178 type Output = Self;
179 #[inline]
180 fn bitor(self, rhs: Self) -> Self {
181 Self {
182 x: self.x | rhs.x,
183 y: self.y | rhs.y,
184 z: self.z | rhs.z,
185 }
186 }
187}
188
189impl BitOr<&Self> for BVec3 {
190 type Output = Self;
191 #[inline]
192 fn bitor(self, rhs: &Self) -> Self {
193 self.bitor(*rhs)
194 }
195}
196
197impl BitOr<&BVec3> for &BVec3 {
198 type Output = BVec3;
199 #[inline]
200 fn bitor(self, rhs: &BVec3) -> BVec3 {
201 (*self).bitor(*rhs)
202 }
203}
204
205impl BitOr<BVec3> for &BVec3 {
206 type Output = BVec3;
207 #[inline]
208 fn bitor(self, rhs: BVec3) -> BVec3 {
209 (*self).bitor(rhs)
210 }
211}
212
213impl BitOrAssign for BVec3 {
214 #[inline]
215 fn bitor_assign(&mut self, rhs: Self) {
216 *self = self.bitor(rhs);
217 }
218}
219
220impl BitOrAssign<&Self> for BVec3 {
221 #[inline]
222 fn bitor_assign(&mut self, rhs: &Self) {
223 self.bitor_assign(*rhs);
224 }
225}
226
227impl BitXor for BVec3 {
228 type Output = Self;
229 #[inline]
230 fn bitxor(self, rhs: Self) -> Self {
231 Self {
232 x: self.x ^ rhs.x,
233 y: self.y ^ rhs.y,
234 z: self.z ^ rhs.z,
235 }
236 }
237}
238
239impl BitXor<&Self> for BVec3 {
240 type Output = Self;
241 #[inline]
242 fn bitxor(self, rhs: &Self) -> Self {
243 self.bitxor(*rhs)
244 }
245}
246
247impl BitXor<&BVec3> for &BVec3 {
248 type Output = BVec3;
249 #[inline]
250 fn bitxor(self, rhs: &BVec3) -> BVec3 {
251 (*self).bitxor(*rhs)
252 }
253}
254
255impl BitXor<BVec3> for &BVec3 {
256 type Output = BVec3;
257 #[inline]
258 fn bitxor(self, rhs: BVec3) -> BVec3 {
259 (*self).bitxor(rhs)
260 }
261}
262
263impl BitXorAssign for BVec3 {
264 #[inline]
265 fn bitxor_assign(&mut self, rhs: Self) {
266 *self = self.bitxor(rhs);
267 }
268}
269
270impl BitXorAssign<&Self> for BVec3 {
271 #[inline]
272 fn bitxor_assign(&mut self, rhs: &Self) {
273 self.bitxor_assign(*rhs);
274 }
275}
276
277impl Not for BVec3 {
278 type Output = Self;
279 #[inline]
280 fn not(self) -> Self {
281 Self {
282 x: !self.x,
283 y: !self.y,
284 z: !self.z,
285 }
286 }
287}
288
289impl Not for &BVec3 {
290 type Output = BVec3;
291 #[inline]
292 fn not(self) -> BVec3 {
293 (*self).not()
294 }
295}
296
297impl fmt::Debug for BVec3 {
298 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299 let arr = self.into_u32_array();
300 write!(
301 f,
302 "{}({:#x}, {:#x}, {:#x})",
303 stringify!(BVec3),
304 arr[0],
305 arr[1],
306 arr[2]
307 )
308 }
309}
310
311impl fmt::Display for BVec3 {
312 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
313 let arr = self.into_bool_array();
314 write!(f, "[{}, {}, {}]", arr[0], arr[1], arr[2])
315 }
316}
317
318impl From<[bool; 3]> for BVec3 {
319 #[inline]
320 fn from(a: [bool; 3]) -> Self {
321 Self::from_array(a)
322 }
323}
324
325impl From<BVec3> for [bool; 3] {
326 #[inline]
327 fn from(mask: BVec3) -> Self {
328 mask.into_bool_array()
329 }
330}
331
332impl From<BVec3> for [u32; 3] {
333 #[inline]
334 fn from(mask: BVec3) -> Self {
335 mask.into_u32_array()
336 }
337}