ico_math/
vector2.rs

1// Copyright 2019 Icosahedra, LLC
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at https://mozilla.org/MPL/2.0/.
6//
7
8use crate::float_vector::FloatVector;
9use crate::raw::RawVector_f32;
10use crate::sse_extensions::*;
11use crate::structure::SIMDVector2;
12use crate::vector2_bool::Vector2Bool;
13use crate::vector2_int::Vector2Int;
14use crate::vector3::Vector3;
15use crate::vector4::Vector4;
16use core::arch::x86_64::*;
17
18/// A vector of 2 floats (x,y).
19#[derive(Copy, Clone, Debug)]
20#[repr(C, align(16))]
21pub struct Vector2 {
22    pub data: __m128,
23}
24
25impl Vector2 {
26    /// Construct a new vector from f32 components.
27    #[inline(always)]
28    pub fn new(x: f32, y: f32) -> Vector2 {
29        unsafe {
30            Vector2 {
31                data: _mm_set_ps(0.0f32, 0.0f32, y, x),
32            }
33        }
34    }
35
36    /// Set all values of the vector to the same f32 value.
37    #[inline(always)]
38    pub fn set<T: Into<FloatVector>>(value: T) -> Vector2 {
39        return Vector2 {
40            data: value.into().data,
41        };
42    }
43
44    /// Construct a new vector of zeros.
45    #[inline(always)]
46    pub fn zero() -> Vector2 {
47        unsafe {
48            Vector2 {
49                data: _mm_setzero_ps(),
50            }
51        }
52    }
53
54    /// Get the x value of the vector, broadcast to all components as a FloatVector (xxxx).
55    #[inline(always)]
56    pub fn x(self) -> FloatVector {
57        return FloatVector {
58            data: self.xxxx().data,
59        };
60    }
61
62    /// Get the y value of the vector, broadcast to all components as a FloatVector (yyyy).
63    #[inline(always)]
64    pub fn y(self) -> FloatVector {
65        return FloatVector {
66            data: self.yyyy().data,
67        };
68    }
69    /// Load a value from aligned memory.
70    #[inline(always)]
71    pub fn load(raw: &RawVector_f32) -> Vector2 {
72        unsafe {
73            // Use the sledgehammer cast here.  It's fine because RawVector is aligned and c-like.
74            return Vector2 {
75                data: _mm_load_ps(core::mem::transmute(raw)),
76            };
77        }
78    }
79
80    /// Store a value to aligned memory.
81    #[inline(always)]
82    pub fn store(self, dst: &mut RawVector_f32) {
83        unsafe {
84            // Use the sledgehammer cast here.  It's fine because RawVector is aligned and c-like.
85            _mm_store_ps(core::mem::transmute(dst), self.data);
86        }
87    }
88
89    /// Set the x value of this vector, leaving the other components unchanged.
90    #[inline(always)]
91    pub fn set_x<T: Into<FloatVector>>(&mut self, value: T) {
92        unsafe {
93            self.data = _mm_move_ss(self.data, value.into().data);
94        }
95    }
96
97    /// Set the y value of this vector, leaving the other components unchanged.
98    #[inline(always)]
99    pub fn set_y<T: Into<FloatVector>>(&mut self, value: T) {
100        unsafe {
101            let v1 = _mm_move_ss(value.into().data, self.data);
102            self.data = _mm_shuffle_ps(v1, self.data, _ico_shuffle(3, 2, 1, 0));
103        }
104    }
105
106    /// Compute the 2 element dot-product, and return it as a broadcast FloatVector.
107    #[inline(always)]
108    pub fn dot(self, v1: Vector2) -> FloatVector {
109        unsafe {
110            let tmp0 = _mm_mul_ps(self.data, v1.data);
111            let mut tmp1 = _yxzw(tmp0); // _mm_shuffle_ps(tmp0,tmp0, _ico_shuffle(3, 2, 0, 1)); //yxzw
112
113            tmp1 = _mm_add_ps(tmp0, tmp1); //xy,xy,qq,qq
114            return FloatVector {
115                data: _mm_unpacklo_ps(tmp1, tmp1),
116            }; //xy,xy.xy,xy
117        }
118    }
119
120    /// Rotate the vector by radians
121    /// Right handed system, positive rotation is counterclockwise about the axis of rotation.
122    #[inline(always)]
123    pub fn rotate<T: Into<FloatVector>>(self, radians: T) -> Vector2 {
124        let tmp = radians.into();
125        //let f = radians.sin_cos();
126
127        //let sn: f32 = f.0 as f32;
128        //let cs: f32 = f.1 as f32;
129        let sn = tmp.sin().value();
130        let mut sncs = Vector4::from(tmp.cos());
131        sncs.set_z(sn);
132        sncs.set_w(-sn);
133        unsafe {
134            // Any values below the epsilon get clamped to zero.  This fixes precision issues around zero.
135            let epsilon = _mm_set1_ps(ABSOLUTE_COMPARISON_EPSILON);
136            //let sncs = _mm_set_ps(-sn, sn, cs, cs);
137            let mask = _mm_cmpgt_ps(_ico_abs_ps(sncs.data), epsilon);
138
139            let masked_sncs = _mm_and_ps(sncs.data, mask);
140
141            //x1y1x2y2
142            let xyxy = _mm_movelh_ps(self.data, self.data);
143            //x * cs, y * cs, x*sn, y*-sn
144            let v2 = _mm_mul_ps(xyxy, masked_sncs);
145
146            //x1 + y2, y1 + x2,
147            //x = x * cs - y * sn;
148            //y = x * sn + y * cs;
149            return Vector2 {
150                data: _mm_add_ps(v2, _wzyx(v2)),
151            }; //wzyx
152        }
153    }
154
155    /// Compute the sum of two vectors and return it as a new vector.
156    #[inline(always)]
157    pub fn add(self, v2: Vector2) -> Vector2 {
158        unsafe {
159            Vector2 {
160                data: _mm_add_ps(self.data, v2.data),
161            }
162        }
163    }
164
165    /// Subtract a vector and return it as a new vector.
166    #[inline(always)]
167    pub fn sub(self, v2: Vector2) -> Vector2 {
168        unsafe {
169            Vector2 {
170                data: _mm_sub_ps(self.data, v2.data),
171            }
172        }
173    }
174
175    /// Multiply two vectors component-wise, and return it as a new vector.  
176    /// (x1 * x2, y1 * y2, z1 * z2, w1 * w2)
177    #[inline(always)]
178    pub fn mul(self, v2: Vector2) -> Vector2 {
179        unsafe {
180            Vector2 {
181                data: _mm_mul_ps(self.data, v2.data),
182            }
183        }
184    }
185
186    /// Divide two vectors component-wise, and return it as a new vector.  
187    /// (x1 / x2, y1 / y2, z1 / z2, w1 / w2)
188    #[inline(always)]
189    pub fn div(self, v2: Vector2) -> Vector2 {
190        unsafe {
191            Vector2 {
192                data: _mm_div_ps(self.data, v2.data),
193            }
194        }
195    }
196
197    /// Fused Multiply Add.  Result = (a * b) + c.
198    #[inline(always)]
199    pub fn mul_add(self, v2: Vector2, v3: Vector2) -> Vector2 {
200        unsafe {
201            return Vector2 {
202                data: _mm_fmadd_ps(self.data, v2.data, v3.data),
203            };
204        }
205    }
206
207    /// Fused Multiply Sub.  Result = (a * b) - c.
208    #[inline(always)]
209    pub fn mul_sub(self, v2: Vector2, v3: Vector2) -> Vector2 {
210        unsafe {
211            return Vector2 {
212                data: _mm_fmsub_ps(self.data, v2.data, v3.data),
213            };
214        }
215    }
216
217    /// Negated Fused Multiply Add.  Result = -(a * b) + c.
218    #[inline(always)]
219    pub fn neg_mul_add(self, v2: Vector2, v3: Vector2) -> Vector2 {
220        unsafe {
221            return Vector2 {
222                data: _mm_fnmadd_ps(self.data, v2.data, v3.data),
223            };
224        }
225    }
226
227    /// Negated Fused Multiply Sub.  Result = -(a * b) - c.
228    #[inline(always)]
229    pub fn neg_mul_sub(self, v2: Vector2, v3: Vector2) -> Vector2 {
230        unsafe {
231            return Vector2 {
232                data: _mm_fnmsub_ps(self.data, v2.data, v3.data),
233            };
234        }
235    }
236
237    /// Compute the bitwise AND of two vectors.
238    /// This function treats inputs as binary data, and doesn't perform any conversions.
239    #[inline(always)]
240    pub fn and<T: SIMDVector2>(self, v2: T) -> Vector2 {
241        unsafe {
242            Vector2 {
243                data: _mm_and_ps(self.data, v2.data()),
244            }
245        }
246    }
247
248    /// Compute the bitwise OR of two vectors.
249    /// This function treats inputs as binary data, and doesn't perform any conversions.
250    #[inline(always)]
251    pub fn or<T: SIMDVector2>(self, v2: T) -> Vector2 {
252        unsafe {
253            Vector2 {
254                data: _mm_or_ps(self.data, v2.data()),
255            }
256        }
257    }
258
259    /// Compute the bitwise ANDNOT of two vectors.
260    /// This function treats inputs as binary data, and doesn't perform any conversions.
261    #[inline(always)]
262    pub fn andnot<T: SIMDVector2>(self, v2: T) -> Vector2 {
263        unsafe {
264            Vector2 {
265                data: _mm_andnot_ps(self.data, v2.data()),
266            }
267        }
268    }
269
270    /// Compute the bitwise XOR of two vectors.
271    /// This function treats inputs as binary data, and doesn't perform any conversions.
272    #[inline(always)]
273    pub fn xor<T: SIMDVector2>(self, v2: T) -> Vector2 {
274        unsafe {
275            Vector2 {
276                data: _mm_xor_ps(self.data, v2.data()),
277            }
278        }
279    }
280
281    /// Equals, computed component-wise.  This compares bits, and is exact.
282    #[inline(always)]
283    pub fn equal(self, v2: Vector2) -> Vector2Bool {
284        unsafe {
285            Vector2Bool {
286                data: _mm_castps_si128(_mm_cmpeq_ps(self.data, v2.data)),
287            }
288        }
289    }
290    /// NotEquals, computed component-wise.  This compares bits, and is exact.
291    #[inline(always)]
292    pub fn not_equal(self, v2: Vector2) -> Vector2Bool {
293        unsafe {
294            Vector2Bool {
295                data: _mm_castps_si128(_mm_cmpneq_ps(self.data, v2.data)),
296            }
297        }
298    }
299    /// Greater than or equal to, computed component-wise.  This compares bits, and is exact.
300    #[inline(always)]
301    pub fn greater_equal(self, v2: Vector2) -> Vector2Bool {
302        unsafe {
303            Vector2Bool {
304                data: _mm_castps_si128(_mm_cmpge_ps(self.data, v2.data)),
305            }
306        }
307    }
308    /// Greater than, computed component-wise.  This compares bits, and is exact.
309    #[inline(always)]
310    pub fn greater(self, v2: Vector2) -> Vector2Bool {
311        unsafe {
312            Vector2Bool {
313                data: _mm_castps_si128(_mm_cmpgt_ps(self.data, v2.data)),
314            }
315        }
316    }
317    /// Less than or equal to, computed component-wise.  This compares bits, and is exact.
318    #[inline(always)]
319    pub fn less_equal(self, v2: Vector2) -> Vector2Bool {
320        unsafe {
321            Vector2Bool {
322                data: _mm_castps_si128(_mm_cmple_ps(self.data, v2.data)),
323            }
324        }
325    }
326    /// Less than, computed component-wise.  This compares bits, and is exact.
327    #[inline(always)]
328    pub fn less(self, v2: Vector2) -> Vector2Bool {
329        unsafe {
330            Vector2Bool {
331                data: _mm_castps_si128(_mm_cmplt_ps(self.data, v2.data)),
332            }
333        }
334    }
335    /// Relative and absolute epsilon comparison.  
336    /// Uses machine epsilon as absolute, and 4*machine epsilon for relative.
337    /// return abs(a - b) <= max(machine_epsilon, (max( abs(a), abs(b) ) * relative_epsilon);
338    /// Adapted from Knuth.  
339    /// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
340    #[inline(always)]
341    pub fn approx_equal(self, v2: Vector2) -> Vector2Bool {
342        let delta = (self - v2).abs();
343        let abs_a = self.abs();
344        let abs_b = v2.abs();
345        let epsilon_bound = (abs_a.max(abs_b) * RELATIVE_COMPARISON_EPSILON)
346            .max(Vector2::from(ABSOLUTE_COMPARISON_EPSILON));
347        return delta.less_equal(epsilon_bound);
348    }
349
350    /// Adapted from Knuth with an added absolute epsilon
351    /// return (a - b) > max(machine_epsilon, (max( abs(a), abs(b) ) * relative_epsilon);
352    #[inline(always)]
353    pub fn definitely_greater(self, v2: Vector2) -> Vector2Bool {
354        let delta = self.sub(v2);
355        let abs_a = self.abs();
356        let abs_b = v2.abs();
357        let epsilon_bound = (abs_a.max(abs_b) * RELATIVE_COMPARISON_EPSILON)
358            .max(Vector2::from(ABSOLUTE_COMPARISON_EPSILON));
359        return delta.greater(epsilon_bound);
360    }
361    /// Adapted from Knuth with an added absolute epsilon
362    /// return (a - b) > max(machine_epsilon, (max( abs(a), abs(b) ) * relative_epsilon);
363    #[inline(always)]
364    pub fn definitely_less(self, v2: Vector2) -> Vector2Bool {
365        let delta = v2.sub(self);
366        let abs_a = self.abs();
367        let abs_b = v2.abs();
368        let epsilon_bound = (abs_a.max(abs_b) * RELATIVE_COMPARISON_EPSILON)
369            .max(Vector2::from(ABSOLUTE_COMPARISON_EPSILON));
370        return delta.greater(epsilon_bound);
371    }
372    /// The absolute value of each component of the vector.
373    #[inline(always)]
374    pub fn abs(self) -> Vector2 {
375        unsafe {
376            Vector2 {
377                data: _ico_abs_ps(self.data),
378            }
379        }
380    }
381
382    /// Take the magnitude of the first argument (self), and use the sign of the second argument to produce a new vector
383    #[inline(always)]
384    pub fn copysign(self, v2: Vector2) -> Vector2 {
385        unsafe {
386            Vector2 {
387                data: _ico_copysign_ps(self.data, v2.data),
388            }
389        }
390    }
391
392    /// Floor function.  Returns signed 0 when applicable.
393    #[inline(always)]
394    pub fn floor(self) -> Vector2 {
395        unsafe {
396            Vector2 {
397                data: _mm_floor_ps(self.data),
398            }
399        }
400    }
401
402    /// Ceil function.  Returns signed 0 when applicable.
403    #[inline(always)]
404    pub fn ceil(self) -> Vector2 {
405        unsafe {
406            Vector2 {
407                data: _mm_ceil_ps(self.data),
408            }
409        }
410    }
411
412    /// Round to nearest even function. Returns signed 0 when applicable.
413    #[inline(always)]
414    pub fn round(self) -> Vector2 {
415        unsafe {
416            Vector2 {
417                data: _mm_round_ps(self.data, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC),
418            }
419        }
420    }
421
422    /// Truncate function.
423    #[inline(always)]
424    pub fn truncate(self) -> Vector2 {
425        unsafe {
426            Vector2 {
427                data: _mm_round_ps(self.data, _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC),
428            }
429        }
430    }
431
432    /// Convert to an integer vector using the floor function.
433    #[inline(always)]
434    pub fn floor_to_int(self) -> Vector2Int {
435        unsafe {
436            Vector2Int {
437                data: _mm_cvttps_epi32(self.floor().data),
438            }
439        }
440    }
441
442    /// Convert to an integer vector using the ceil function.
443    #[inline(always)]
444    pub fn ceil_to_int(self) -> Vector2Int {
445        unsafe {
446            Vector2Int {
447                data: _mm_cvttps_epi32(self.ceil().data),
448            }
449        }
450    }
451    /// Convert to an integer vector using the round function.
452    #[inline(always)]
453    pub fn round_to_int(self) -> Vector2Int {
454        unsafe {
455            Vector2Int {
456                data: _mm_cvttps_epi32(self.round().data),
457            }
458        }
459    }
460
461    /// Convert to an integer vector using the truncate function.
462    #[inline(always)]
463    pub fn truncate_to_int(self) -> Vector2Int {
464        unsafe {
465            Vector2Int {
466                data: _mm_cvttps_epi32(self.truncate().data),
467            }
468        }
469    }
470
471    /// Compute the fractional component of each component
472    /// Result = X - Floor(x)
473    #[inline(always)]
474    pub fn frac(self) -> Vector2 {
475        return Vector2::sub(self, Vector2::floor(self));
476    }
477
478    /// Compute the square root of each component
479    #[inline(always)]
480    pub fn sqrt(self) -> Vector2 {
481        unsafe {
482            Vector2 {
483                data: _mm_sqrt_ps(self.data),
484            }
485        }
486    }
487
488    /// Compute the approximate sin of each component
489    #[inline(always)]
490    pub fn sin(self) -> Vector2 {
491        unsafe {
492            Vector2 {
493                data: _ico_sin_ps(self.data),
494            }
495        }
496    }
497
498    /// Compute the approximate cos of each component
499    #[inline(always)]
500    pub fn cos(self) -> Vector2 {
501        unsafe {
502            Vector2 {
503                data: _ico_cos_ps(self.data),
504            }
505        }
506    }
507    /// Compute the approximate tan of each component
508    #[inline(always)]
509    pub fn tan(self) -> Vector2 {
510        unsafe {
511            Vector2 {
512                data: _ico_tan_ps(self.data),
513            }
514        }
515    }
516    /// Compute the approximate acos of each component
517    #[inline(always)]
518    pub fn acos(self) -> Vector2 {
519        unsafe {
520            Vector2 {
521                data: _ico_acos_ps(self.data),
522            }
523        }
524    }
525
526    /// Compute the approximate asin of each component
527    #[inline(always)]
528    pub fn asin(self) -> Vector2 {
529        unsafe {
530            Vector2 {
531                data: _ico_asin_ps(self.data),
532            }
533        }
534    }
535    #[inline(always)]
536    pub fn atan2(self, x: Vector2) -> Vector2 {
537        unsafe {
538            Vector2 {
539                data: _ico_atan2_ps(self.data, x.data),
540            }
541        }
542    }
543    /// Compute the component-wise max.
544    #[inline(always)]
545    pub fn max(self, v2: Vector2) -> Vector2 {
546        unsafe {
547            Vector2 {
548                data: _mm_max_ps(self.data, v2.data),
549            }
550        }
551    }
552
553    /// Compute the component-wise min.
554    #[inline(always)]
555    pub fn min(self, v2: Vector2) -> Vector2 {
556        unsafe {
557            Vector2 {
558                data: _mm_min_ps(self.data, v2.data),
559            }
560        }
561    }
562
563    #[inline(always)]
564    pub fn horizontal_min(self) -> FloatVector {
565        let x = self.x();
566        return FloatVector {
567            data: x.min(self.y()).data,
568        };
569    }
570
571    #[inline(always)]
572    pub fn horizontal_max(self) -> FloatVector {
573        let x = self.x();
574        return FloatVector {
575            data: x.max(self.y()).data,
576        };
577    }
578
579    /// Choose component wise between A and B based on the mask.  False = A, True = B.
580    #[inline(always)]
581    pub fn select(self, v2: Vector2, mask: Vector2Bool) -> Vector2 {
582        unsafe {
583            Vector2 {
584                data: _ico_select_ps(self.data, v2.data, _mm_castsi128_ps(mask.data)),
585            }
586        }
587    }
588    /// Linear interpolate from a to b based on a float.
589    #[inline(always)]
590    pub fn lerp<T: Into<FloatVector>>(self, v2: Vector2, t: T) -> Vector2 {
591        unsafe {
592            let t_val = t.into().data;
593            let tmp = _mm_fnmadd_ps(self.data, t_val, self.data); //a - (a*t)
594            Vector2 {
595                data: _mm_fmadd_ps(v2.data, t_val, tmp),
596            } //b * t + a
597        }
598    }
599
600    /// Normalize the vector.  Returns a zero vector if the result would be infinity or NAN.
601    #[inline(always)]
602    pub fn normalize(self) -> Vector2 {
603        let length = FloatVector::sqrt(Vector2::dot(self, self));
604        let norm = Vector2::div(self, Vector2::from(length));
605
606        unsafe {
607            // This catches infinity, NAN.  Zero vectors are possible - but that is fine - we failed
608            let result_length_sqr = Vector2::from(Vector2::dot(norm, norm));
609            let mask_less = Vector2::less(
610                result_length_sqr,
611                Vector2 {
612                    data: _ico_two_ps(),
613                },
614            );
615            return Vector2::and(norm, mask_less);
616        }
617    }
618
619    /// Normalize the vector.  Returns a zero vector if the result would be infinity or NAN.
620    /// Also returns the length of the vector prior to normalization.
621    #[inline(always)]
622    pub fn normalize_length(self) -> (Vector2, FloatVector) {
623        let length = FloatVector::sqrt(Vector2::dot(self, self));
624        let norm = Vector2::div(self, Vector2::from(length));
625
626        unsafe {
627            // This catches infinity, NAN.  Zero vectors are possible - but that is fine - we failed
628            let result_length_sqr = Vector2::from(Vector2::dot(norm, norm));
629            let mask_less = Vector2::less(
630                result_length_sqr,
631                Vector2 {
632                    data: _ico_two_ps(),
633                },
634            );
635            return (Vector2::and(norm, mask_less), length);
636        }
637    }
638
639    /// The square magnitude of the vector.  Equal to Dot(self, self).
640    #[inline(always)]
641    pub fn sqr_magnitude(self) -> FloatVector {
642        return Vector2::dot(self, self);
643    }
644
645    /// The magnitude of the vector.  Equal to Sqrt(Dot(self, self)).
646    #[inline(always)]
647    pub fn magnitude(self) -> FloatVector {
648        return FloatVector::sqrt(Vector2::dot(self, self));
649    }
650
651    #[inline(always)]
652    pub fn xxxx(self) -> Vector4 {
653        unsafe {
654            return Vector4 {
655                data: _xxxx(self.data),
656            };
657        }
658    }
659    #[inline(always)]
660    pub fn yyyy(self) -> Vector4 {
661        unsafe {
662            return Vector4 {
663                data: _yyyy(self.data),
664            };
665        }
666    }
667
668    #[inline(always)]
669    pub fn xx(self) -> Vector2 {
670        unsafe {
671            return Vector2 {
672                data: _xxzw(self.data),
673            };
674        }
675    }
676    #[inline(always)]
677    pub fn xy(self) -> Vector2 {
678        unsafe {
679            return Vector2 {
680                data: _xyzw(self.data),
681            };
682        }
683    }
684    #[inline(always)]
685    pub fn yx(self) -> Vector2 {
686        unsafe {
687            return Vector2 {
688                data: _yxzw(self.data),
689            };
690        }
691    }
692    #[inline(always)]
693    pub fn yy(self) -> Vector2 {
694        unsafe {
695            return Vector2 {
696                data: _yyzw(self.data),
697            };
698        }
699    }
700}
701
702impl From<f32> for Vector2 {
703    #[inline(always)]
704    fn from(v: f32) -> Vector2 {
705        return Vector2::set(v);
706    }
707}
708impl From<FloatVector> for Vector2 {
709    #[inline(always)]
710    fn from(v: FloatVector) -> Vector2 {
711        return Vector2 { data: v.data };
712    }
713}
714impl From<Vector3> for Vector2 {
715    #[inline(always)]
716    fn from(v: Vector3) -> Vector2 {
717        Vector2 { data: v.data }
718    }
719}
720impl From<Vector4> for Vector2 {
721    #[inline(always)]
722    fn from(v: Vector4) -> Vector2 {
723        Vector2 { data: v.data }
724    }
725}
726impl From<Vector2Int> for Vector2 {
727    #[inline(always)]
728    fn from(v: Vector2Int) -> Vector2 {
729        unsafe {
730            return Vector2 {
731                data: _mm_cvtepi32_ps(v.data),
732            };
733        }
734    }
735}
736
737impl core::ops::Add for Vector2 {
738    type Output = Vector2;
739    #[inline(always)]
740    fn add(self, _rhs: Vector2) -> Vector2 {
741        Vector2::add(self, _rhs)
742    }
743}
744impl core::ops::AddAssign for Vector2 {
745    #[inline(always)]
746    fn add_assign(&mut self, other: Vector2) {
747        *self = Vector2::add(*self, other)
748    }
749}
750impl core::ops::Sub for Vector2 {
751    type Output = Vector2;
752    #[inline(always)]
753    fn sub(self, _rhs: Vector2) -> Vector2 {
754        Vector2::sub(self, _rhs)
755    }
756}
757impl core::ops::SubAssign for Vector2 {
758    #[inline(always)]
759    fn sub_assign(&mut self, other: Vector2) {
760        *self = Vector2::sub(*self, other)
761    }
762}
763impl core::ops::Neg for Vector2 {
764    type Output = Vector2;
765    #[inline(always)]
766    fn neg(self) -> Self::Output {
767        unsafe {
768            return Vector2 {
769                data: _mm_xor_ps(_ico_signbit_ps(), self.data),
770            };
771        }
772    }
773}
774impl<T: Into<FloatVector>> core::ops::Mul<T> for Vector2 {
775    type Output = Vector2;
776    #[inline(always)]
777    fn mul(self, _rhs: T) -> Vector2 {
778        return Vector2::mul(self, Vector2::from(_rhs.into()));
779    }
780}
781impl<T: Into<FloatVector>> core::ops::MulAssign<T> for Vector2 {
782    #[inline(always)]
783    fn mul_assign(&mut self, _rhs: T) {
784        *self = Vector2::mul(*self, Vector2::from(_rhs.into()));
785    }
786}
787impl core::ops::Mul<Vector2> for FloatVector {
788    type Output = Vector2;
789    #[inline(always)]
790    fn mul(self: FloatVector, _rhs: Vector2) -> Vector2 {
791        return Vector2::mul(_rhs, Vector2::from(self));
792    }
793}
794
795impl<T: Into<FloatVector>> core::ops::Div<T> for Vector2 {
796    type Output = Vector2;
797    #[inline(always)]
798    fn div(self, _rhs: T) -> Vector2 {
799        return Vector2::div(self, Vector2::from(_rhs.into()));
800    }
801}
802impl core::ops::Div<Vector2> for FloatVector {
803    type Output = Vector2;
804    #[inline(always)]
805    fn div(self: FloatVector, _rhs: Vector2) -> Vector2 {
806        return Vector2::div(Vector2::from(self), _rhs);
807    }
808}
809impl<T: Into<FloatVector>> core::ops::DivAssign<T> for Vector2 {
810    #[inline(always)]
811    fn div_assign(&mut self, _rhs: T) {
812        *self = Vector2::div(*self, Vector2::from(_rhs.into()));
813    }
814}
815
816impl PartialEq for Vector2 {
817    #[inline(always)]
818    fn eq(&self, other: &Vector2) -> bool {
819        return Vector2::equal(*self, *other).all();
820    }
821}
822
823impl SIMDVector2 for Vector2 {
824    #[inline(always)]
825    fn data(self) -> __m128 {
826        return self.data;
827    }
828    #[inline(always)]
829    fn data_i(self) -> __m128i {
830        return unsafe { _mm_castps_si128(self.data) };
831    }
832}
833#[cfg(test)]
834mod test;