1use core::fmt;
4use core::ops::*;
5
6#[cfg(target_arch = "x86")]
7use core::arch::x86::*;
8#[cfg(target_arch = "x86_64")]
9use core::arch::x86_64::*;
10
11#[repr(C)]
12union UnionCast {
13 a: [u32; 4],
14 v: BVec3A,
15}
16
17#[inline(always)]
19#[must_use]
20pub const fn bvec3a(x: bool, y: bool, z: bool) -> BVec3A {
21 BVec3A::new(x, y, z)
22}
23
24#[derive(Clone, Copy)]
28#[repr(transparent)]
29pub struct BVec3A(pub(crate) __m128);
30
31const MASK: [u32; 2] = [0, 0xff_ff_ff_ff];
32
33impl BVec3A {
34 pub const FALSE: Self = Self::splat(false);
36
37 pub const TRUE: Self = Self::splat(true);
39
40 #[inline(always)]
42 #[must_use]
43 pub const fn new(x: bool, y: bool, z: bool) -> Self {
44 unsafe {
45 UnionCast {
46 a: [MASK[x as usize], MASK[y as usize], MASK[z as usize], 0],
47 }
48 .v
49 }
50 }
51
52 #[inline]
54 #[must_use]
55 pub const fn splat(v: bool) -> Self {
56 Self::new(v, v, v)
57 }
58
59 #[inline]
61 #[must_use]
62 pub const fn from_array(a: [bool; 3]) -> Self {
63 Self::new(a[0], a[1], a[2])
64 }
65
66 #[inline]
71 #[must_use]
72 pub fn bitmask(self) -> u32 {
73 unsafe { (_mm_movemask_ps(self.0) as u32) & 0x7 }
74 }
75
76 #[inline]
78 #[must_use]
79 pub fn any(self) -> bool {
80 self.bitmask() != 0
81 }
82
83 #[inline]
85 #[must_use]
86 pub fn all(self) -> bool {
87 self.bitmask() == 0x7
88 }
89
90 #[inline]
94 #[must_use]
95 pub fn test(&self, index: usize) -> bool {
96 match index {
97 0 => (self.bitmask() & (1 << 0)) != 0,
98 1 => (self.bitmask() & (1 << 1)) != 0,
99 2 => (self.bitmask() & (1 << 2)) != 0,
100 _ => panic!("index out of bounds"),
101 }
102 }
103
104 #[inline]
108 pub fn set(&mut self, index: usize, value: bool) {
109 use crate::Vec3A;
110 let mut v = Vec3A(self.0);
111 v[index] = f32::from_bits(MASK[value as usize]);
112 self.0 = v.0;
113 }
114
115 #[inline]
116 #[must_use]
117 fn into_bool_array(self) -> [bool; 3] {
118 let bitmask = self.bitmask();
119 [(bitmask & 1) != 0, (bitmask & 2) != 0, (bitmask & 4) != 0]
120 }
121
122 #[inline]
123 #[must_use]
124 fn into_u32_array(self) -> [u32; 3] {
125 let bitmask = self.bitmask();
126 [
127 MASK[(bitmask & 1) as usize],
128 MASK[((bitmask >> 1) & 1) as usize],
129 MASK[((bitmask >> 2) & 1) as usize],
130 ]
131 }
132}
133
134impl Default for BVec3A {
135 #[inline]
136 fn default() -> Self {
137 Self::FALSE
138 }
139}
140
141impl PartialEq for BVec3A {
142 #[inline]
143 fn eq(&self, rhs: &Self) -> bool {
144 self.bitmask().eq(&rhs.bitmask())
145 }
146}
147
148impl Eq for BVec3A {}
149
150impl core::hash::Hash for BVec3A {
151 #[inline]
152 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
153 self.bitmask().hash(state);
154 }
155}
156
157impl BitAnd for BVec3A {
158 type Output = Self;
159 #[inline]
160 fn bitand(self, rhs: Self) -> Self {
161 Self(unsafe { _mm_and_ps(self.0, rhs.0) })
162 }
163}
164
165impl BitAnd<&Self> for BVec3A {
166 type Output = Self;
167 #[inline]
168 fn bitand(self, rhs: &Self) -> Self {
169 self.bitand(*rhs)
170 }
171}
172
173impl BitAnd<&BVec3A> for &BVec3A {
174 type Output = BVec3A;
175 #[inline]
176 fn bitand(self, rhs: &BVec3A) -> BVec3A {
177 (*self).bitand(*rhs)
178 }
179}
180
181impl BitAnd<BVec3A> for &BVec3A {
182 type Output = BVec3A;
183 #[inline]
184 fn bitand(self, rhs: BVec3A) -> BVec3A {
185 (*self).bitand(rhs)
186 }
187}
188
189impl BitAndAssign for BVec3A {
190 #[inline]
191 fn bitand_assign(&mut self, rhs: Self) {
192 *self = self.bitand(rhs);
193 }
194}
195
196impl BitAndAssign<&Self> for BVec3A {
197 #[inline]
198 fn bitand_assign(&mut self, rhs: &Self) {
199 self.bitand_assign(*rhs);
200 }
201}
202
203impl BitOr for BVec3A {
204 type Output = Self;
205 #[inline]
206 fn bitor(self, rhs: Self) -> Self {
207 Self(unsafe { _mm_or_ps(self.0, rhs.0) })
208 }
209}
210
211impl BitOr<&Self> for BVec3A {
212 type Output = Self;
213 #[inline]
214 fn bitor(self, rhs: &Self) -> Self {
215 self.bitor(*rhs)
216 }
217}
218
219impl BitOr<&BVec3A> for &BVec3A {
220 type Output = BVec3A;
221 #[inline]
222 fn bitor(self, rhs: &BVec3A) -> BVec3A {
223 (*self).bitor(*rhs)
224 }
225}
226
227impl BitOr<BVec3A> for &BVec3A {
228 type Output = BVec3A;
229 #[inline]
230 fn bitor(self, rhs: BVec3A) -> BVec3A {
231 (*self).bitor(rhs)
232 }
233}
234
235impl BitOrAssign for BVec3A {
236 #[inline]
237 fn bitor_assign(&mut self, rhs: Self) {
238 *self = self.bitor(rhs);
239 }
240}
241
242impl BitOrAssign<&Self> for BVec3A {
243 #[inline]
244 fn bitor_assign(&mut self, rhs: &Self) {
245 self.bitor_assign(*rhs);
246 }
247}
248
249impl BitXor for BVec3A {
250 type Output = Self;
251 #[inline]
252 fn bitxor(self, rhs: Self) -> Self {
253 Self(unsafe { _mm_xor_ps(self.0, rhs.0) })
254 }
255}
256
257impl BitXor<&Self> for BVec3A {
258 type Output = Self;
259 #[inline]
260 fn bitxor(self, rhs: &Self) -> Self {
261 self.bitxor(*rhs)
262 }
263}
264
265impl BitXor<&BVec3A> for &BVec3A {
266 type Output = BVec3A;
267 #[inline]
268 fn bitxor(self, rhs: &BVec3A) -> BVec3A {
269 (*self).bitxor(*rhs)
270 }
271}
272
273impl BitXor<BVec3A> for &BVec3A {
274 type Output = BVec3A;
275 #[inline]
276 fn bitxor(self, rhs: BVec3A) -> BVec3A {
277 (*self).bitxor(rhs)
278 }
279}
280
281impl BitXorAssign for BVec3A {
282 #[inline]
283 fn bitxor_assign(&mut self, rhs: Self) {
284 *self = self.bitxor(rhs);
285 }
286}
287
288impl BitXorAssign<&Self> for BVec3A {
289 #[inline]
290 fn bitxor_assign(&mut self, rhs: &Self) {
291 self.bitxor_assign(*rhs);
292 }
293}
294
295impl Not for BVec3A {
296 type Output = Self;
297 #[inline]
298 fn not(self) -> Self {
299 Self(unsafe { _mm_andnot_ps(self.0, _mm_set_ps1(f32::from_bits(0xff_ff_ff_ff))) })
300 }
301}
302
303impl Not for &BVec3A {
304 type Output = BVec3A;
305 #[inline]
306 fn not(self) -> BVec3A {
307 (*self).not()
308 }
309}
310
311impl From<BVec3A> for __m128 {
312 #[inline]
313 fn from(t: BVec3A) -> Self {
314 t.0
315 }
316}
317
318impl fmt::Debug for BVec3A {
319 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
320 let arr = self.into_u32_array();
321 write!(
322 f,
323 "{}({:#x}, {:#x}, {:#x})",
324 stringify!(BVec3A),
325 arr[0],
326 arr[1],
327 arr[2]
328 )
329 }
330}
331
332impl fmt::Display for BVec3A {
333 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
334 let arr = self.into_bool_array();
335 write!(f, "[{}, {}, {}]", arr[0], arr[1], arr[2])
336 }
337}
338
339impl From<[bool; 3]> for BVec3A {
340 #[inline]
341 fn from(a: [bool; 3]) -> Self {
342 Self::from_array(a)
343 }
344}
345
346impl From<BVec3A> for [bool; 3] {
347 #[inline]
348 fn from(mask: BVec3A) -> Self {
349 mask.into_bool_array()
350 }
351}
352
353impl From<BVec3A> for [u32; 3] {
354 #[inline]
355 fn from(mask: BVec3A) -> Self {
356 mask.into_u32_array()
357 }
358}