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))]
16#[cfg_attr(target_arch = "spirv", rust_gpu::vector::v1)]
17pub struct BVec3 {
18 pub x: bool,
19 pub y: bool,
20 pub z: bool,
21}
22
23const MASK: [u32; 2] = [0, 0xff_ff_ff_ff];
24
25impl BVec3 {
26 pub const FALSE: Self = Self::splat(false);
28
29 pub const TRUE: Self = Self::splat(true);
31
32 #[inline(always)]
34 #[must_use]
35 pub const fn new(x: bool, y: bool, z: bool) -> Self {
36 Self { x, y, z }
37 }
38
39 #[inline]
41 #[must_use]
42 pub const fn splat(v: bool) -> Self {
43 Self::new(v, v, v)
44 }
45
46 #[inline]
48 #[must_use]
49 pub const fn from_array(a: [bool; 3]) -> Self {
50 Self::new(a[0], a[1], a[2])
51 }
52
53 #[inline]
58 #[must_use]
59 pub fn bitmask(self) -> u32 {
60 (self.x as u32) | ((self.y as u32) << 1) | ((self.z as u32) << 2)
61 }
62
63 #[inline]
65 #[must_use]
66 pub fn any(self) -> bool {
67 self.x || self.y || self.z
68 }
69
70 #[inline]
72 #[must_use]
73 pub fn all(self) -> bool {
74 self.x && self.y && self.z
75 }
76
77 #[inline]
81 #[must_use]
82 #[track_caller]
83 pub fn test(self, index: usize) -> bool {
84 match index {
85 0 => self.x,
86 1 => self.y,
87 2 => self.z,
88 _ => panic!("index out of bounds"),
89 }
90 }
91
92 #[inline]
96 #[track_caller]
97 pub fn set(&mut self, index: usize, value: bool) {
98 match index {
99 0 => self.x = value,
100 1 => self.y = value,
101 2 => self.z = value,
102 _ => panic!("index out of bounds"),
103 }
104 }
105
106 #[inline]
107 #[must_use]
108 fn into_bool_array(self) -> [bool; 3] {
109 [self.x, self.y, self.z]
110 }
111
112 #[inline]
113 #[must_use]
114 fn into_u32_array(self) -> [u32; 3] {
115 [
116 MASK[self.x as usize],
117 MASK[self.y as usize],
118 MASK[self.z as usize],
119 ]
120 }
121}
122
123impl Default for BVec3 {
124 #[inline]
125 fn default() -> Self {
126 Self::FALSE
127 }
128}
129
130impl BitAnd for BVec3 {
131 type Output = Self;
132 #[inline]
133 fn bitand(self, rhs: Self) -> Self {
134 Self {
135 x: self.x & rhs.x,
136 y: self.y & rhs.y,
137 z: self.z & rhs.z,
138 }
139 }
140}
141
142impl BitAnd<&Self> for BVec3 {
143 type Output = Self;
144 #[inline]
145 fn bitand(self, rhs: &Self) -> Self {
146 self.bitand(*rhs)
147 }
148}
149
150impl BitAnd<&BVec3> for &BVec3 {
151 type Output = BVec3;
152 #[inline]
153 fn bitand(self, rhs: &BVec3) -> BVec3 {
154 (*self).bitand(*rhs)
155 }
156}
157
158impl BitAnd<BVec3> for &BVec3 {
159 type Output = BVec3;
160 #[inline]
161 fn bitand(self, rhs: BVec3) -> BVec3 {
162 (*self).bitand(rhs)
163 }
164}
165
166impl BitAndAssign for BVec3 {
167 #[inline]
168 fn bitand_assign(&mut self, rhs: Self) {
169 *self = self.bitand(rhs);
170 }
171}
172
173impl BitAndAssign<&Self> for BVec3 {
174 #[inline]
175 fn bitand_assign(&mut self, rhs: &Self) {
176 self.bitand_assign(*rhs);
177 }
178}
179
180impl BitOr for BVec3 {
181 type Output = Self;
182 #[inline]
183 fn bitor(self, rhs: Self) -> Self {
184 Self {
185 x: self.x | rhs.x,
186 y: self.y | rhs.y,
187 z: self.z | rhs.z,
188 }
189 }
190}
191
192impl BitOr<&Self> for BVec3 {
193 type Output = Self;
194 #[inline]
195 fn bitor(self, rhs: &Self) -> Self {
196 self.bitor(*rhs)
197 }
198}
199
200impl BitOr<&BVec3> for &BVec3 {
201 type Output = BVec3;
202 #[inline]
203 fn bitor(self, rhs: &BVec3) -> BVec3 {
204 (*self).bitor(*rhs)
205 }
206}
207
208impl BitOr<BVec3> for &BVec3 {
209 type Output = BVec3;
210 #[inline]
211 fn bitor(self, rhs: BVec3) -> BVec3 {
212 (*self).bitor(rhs)
213 }
214}
215
216impl BitOrAssign for BVec3 {
217 #[inline]
218 fn bitor_assign(&mut self, rhs: Self) {
219 *self = self.bitor(rhs);
220 }
221}
222
223impl BitOrAssign<&Self> for BVec3 {
224 #[inline]
225 fn bitor_assign(&mut self, rhs: &Self) {
226 self.bitor_assign(*rhs);
227 }
228}
229
230impl BitXor for BVec3 {
231 type Output = Self;
232 #[inline]
233 fn bitxor(self, rhs: Self) -> Self {
234 Self {
235 x: self.x ^ rhs.x,
236 y: self.y ^ rhs.y,
237 z: self.z ^ rhs.z,
238 }
239 }
240}
241
242impl BitXor<&Self> for BVec3 {
243 type Output = Self;
244 #[inline]
245 fn bitxor(self, rhs: &Self) -> Self {
246 self.bitxor(*rhs)
247 }
248}
249
250impl BitXor<&BVec3> for &BVec3 {
251 type Output = BVec3;
252 #[inline]
253 fn bitxor(self, rhs: &BVec3) -> BVec3 {
254 (*self).bitxor(*rhs)
255 }
256}
257
258impl BitXor<BVec3> for &BVec3 {
259 type Output = BVec3;
260 #[inline]
261 fn bitxor(self, rhs: BVec3) -> BVec3 {
262 (*self).bitxor(rhs)
263 }
264}
265
266impl BitXorAssign for BVec3 {
267 #[inline]
268 fn bitxor_assign(&mut self, rhs: Self) {
269 *self = self.bitxor(rhs);
270 }
271}
272
273impl BitXorAssign<&Self> for BVec3 {
274 #[inline]
275 fn bitxor_assign(&mut self, rhs: &Self) {
276 self.bitxor_assign(*rhs);
277 }
278}
279
280impl Not for BVec3 {
281 type Output = Self;
282 #[inline]
283 fn not(self) -> Self {
284 Self {
285 x: !self.x,
286 y: !self.y,
287 z: !self.z,
288 }
289 }
290}
291
292impl Not for &BVec3 {
293 type Output = BVec3;
294 #[inline]
295 fn not(self) -> BVec3 {
296 (*self).not()
297 }
298}
299
300impl fmt::Debug for BVec3 {
301 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
302 let arr = self.into_u32_array();
303 write!(
304 f,
305 "{}({:#x}, {:#x}, {:#x})",
306 stringify!(BVec3),
307 arr[0],
308 arr[1],
309 arr[2]
310 )
311 }
312}
313
314impl fmt::Display for BVec3 {
315 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
316 let arr = self.into_bool_array();
317 write!(f, "[{}, {}, {}]", arr[0], arr[1], arr[2])
318 }
319}
320
321impl From<[bool; 3]> for BVec3 {
322 #[inline]
323 fn from(a: [bool; 3]) -> Self {
324 Self::from_array(a)
325 }
326}
327
328impl From<BVec3> for [bool; 3] {
329 #[inline]
330 fn from(mask: BVec3) -> Self {
331 mask.into_bool_array()
332 }
333}
334
335impl From<BVec3> for [u32; 3] {
336 #[inline]
337 fn from(mask: BVec3) -> Self {
338 mask.into_u32_array()
339 }
340}