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 #[track_caller]
96 pub fn test(self, index: usize) -> bool {
97 match index {
98 0 => (self.bitmask() & (1 << 0)) != 0,
99 1 => (self.bitmask() & (1 << 1)) != 0,
100 2 => (self.bitmask() & (1 << 2)) != 0,
101 _ => panic!("index out of bounds"),
102 }
103 }
104
105 #[inline]
109 #[track_caller]
110 pub fn set(&mut self, index: usize, value: bool) {
111 use crate::Vec3A;
112 let mut v = Vec3A(self.0);
113 v[index] = f32::from_bits(MASK[value as usize]);
114 self.0 = v.0;
115 }
116
117 #[inline]
118 #[must_use]
119 fn into_bool_array(self) -> [bool; 3] {
120 let bitmask = self.bitmask();
121 [(bitmask & 1) != 0, (bitmask & 2) != 0, (bitmask & 4) != 0]
122 }
123
124 #[inline]
125 #[must_use]
126 fn into_u32_array(self) -> [u32; 3] {
127 let bitmask = self.bitmask();
128 [
129 MASK[(bitmask & 1) as usize],
130 MASK[((bitmask >> 1) & 1) as usize],
131 MASK[((bitmask >> 2) & 1) as usize],
132 ]
133 }
134}
135
136impl Default for BVec3A {
137 #[inline]
138 fn default() -> Self {
139 Self::FALSE
140 }
141}
142
143impl PartialEq for BVec3A {
144 #[inline]
145 fn eq(&self, rhs: &Self) -> bool {
146 self.bitmask().eq(&rhs.bitmask())
147 }
148}
149
150impl Eq for BVec3A {}
151
152impl core::hash::Hash for BVec3A {
153 #[inline]
154 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
155 self.bitmask().hash(state);
156 }
157}
158
159impl BitAnd for BVec3A {
160 type Output = Self;
161 #[inline]
162 fn bitand(self, rhs: Self) -> Self {
163 Self(unsafe { _mm_and_ps(self.0, rhs.0) })
164 }
165}
166
167impl BitAnd<&Self> for BVec3A {
168 type Output = Self;
169 #[inline]
170 fn bitand(self, rhs: &Self) -> Self {
171 self.bitand(*rhs)
172 }
173}
174
175impl BitAnd<&BVec3A> for &BVec3A {
176 type Output = BVec3A;
177 #[inline]
178 fn bitand(self, rhs: &BVec3A) -> BVec3A {
179 (*self).bitand(*rhs)
180 }
181}
182
183impl BitAnd<BVec3A> for &BVec3A {
184 type Output = BVec3A;
185 #[inline]
186 fn bitand(self, rhs: BVec3A) -> BVec3A {
187 (*self).bitand(rhs)
188 }
189}
190
191impl BitAndAssign for BVec3A {
192 #[inline]
193 fn bitand_assign(&mut self, rhs: Self) {
194 *self = self.bitand(rhs);
195 }
196}
197
198impl BitAndAssign<&Self> for BVec3A {
199 #[inline]
200 fn bitand_assign(&mut self, rhs: &Self) {
201 self.bitand_assign(*rhs);
202 }
203}
204
205impl BitOr for BVec3A {
206 type Output = Self;
207 #[inline]
208 fn bitor(self, rhs: Self) -> Self {
209 Self(unsafe { _mm_or_ps(self.0, rhs.0) })
210 }
211}
212
213impl BitOr<&Self> for BVec3A {
214 type Output = Self;
215 #[inline]
216 fn bitor(self, rhs: &Self) -> Self {
217 self.bitor(*rhs)
218 }
219}
220
221impl BitOr<&BVec3A> for &BVec3A {
222 type Output = BVec3A;
223 #[inline]
224 fn bitor(self, rhs: &BVec3A) -> BVec3A {
225 (*self).bitor(*rhs)
226 }
227}
228
229impl BitOr<BVec3A> for &BVec3A {
230 type Output = BVec3A;
231 #[inline]
232 fn bitor(self, rhs: BVec3A) -> BVec3A {
233 (*self).bitor(rhs)
234 }
235}
236
237impl BitOrAssign for BVec3A {
238 #[inline]
239 fn bitor_assign(&mut self, rhs: Self) {
240 *self = self.bitor(rhs);
241 }
242}
243
244impl BitOrAssign<&Self> for BVec3A {
245 #[inline]
246 fn bitor_assign(&mut self, rhs: &Self) {
247 self.bitor_assign(*rhs);
248 }
249}
250
251impl BitXor for BVec3A {
252 type Output = Self;
253 #[inline]
254 fn bitxor(self, rhs: Self) -> Self {
255 Self(unsafe { _mm_xor_ps(self.0, rhs.0) })
256 }
257}
258
259impl BitXor<&Self> for BVec3A {
260 type Output = Self;
261 #[inline]
262 fn bitxor(self, rhs: &Self) -> Self {
263 self.bitxor(*rhs)
264 }
265}
266
267impl BitXor<&BVec3A> for &BVec3A {
268 type Output = BVec3A;
269 #[inline]
270 fn bitxor(self, rhs: &BVec3A) -> BVec3A {
271 (*self).bitxor(*rhs)
272 }
273}
274
275impl BitXor<BVec3A> for &BVec3A {
276 type Output = BVec3A;
277 #[inline]
278 fn bitxor(self, rhs: BVec3A) -> BVec3A {
279 (*self).bitxor(rhs)
280 }
281}
282
283impl BitXorAssign for BVec3A {
284 #[inline]
285 fn bitxor_assign(&mut self, rhs: Self) {
286 *self = self.bitxor(rhs);
287 }
288}
289
290impl BitXorAssign<&Self> for BVec3A {
291 #[inline]
292 fn bitxor_assign(&mut self, rhs: &Self) {
293 self.bitxor_assign(*rhs);
294 }
295}
296
297impl Not for BVec3A {
298 type Output = Self;
299 #[inline]
300 fn not(self) -> Self {
301 Self(unsafe { _mm_andnot_ps(self.0, _mm_set_ps1(f32::from_bits(0xff_ff_ff_ff))) })
302 }
303}
304
305impl Not for &BVec3A {
306 type Output = BVec3A;
307 #[inline]
308 fn not(self) -> BVec3A {
309 (*self).not()
310 }
311}
312
313impl From<BVec3A> for __m128 {
314 #[inline]
315 fn from(t: BVec3A) -> Self {
316 t.0
317 }
318}
319
320impl fmt::Debug for BVec3A {
321 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
322 let arr = self.into_u32_array();
323 write!(
324 f,
325 "{}({:#x}, {:#x}, {:#x})",
326 stringify!(BVec3A),
327 arr[0],
328 arr[1],
329 arr[2]
330 )
331 }
332}
333
334impl fmt::Display for BVec3A {
335 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
336 let arr = self.into_bool_array();
337 write!(f, "[{}, {}, {}]", arr[0], arr[1], arr[2])
338 }
339}
340
341impl From<[bool; 3]> for BVec3A {
342 #[inline]
343 fn from(a: [bool; 3]) -> Self {
344 Self::from_array(a)
345 }
346}
347
348impl From<BVec3A> for [bool; 3] {
349 #[inline]
350 fn from(mask: BVec3A) -> Self {
351 mask.into_bool_array()
352 }
353}
354
355impl From<BVec3A> for [u32; 3] {
356 #[inline]
357 fn from(mask: BVec3A) -> Self {
358 mask.into_u32_array()
359 }
360}