1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef API_BASE_MATH_VECTOR_H
17 #define API_BASE_MATH_VECTOR_H
18 
19 #include <cstddef>
20 #include <cstdint>
21 
22 #include <base/math/mathf.h>
23 #include <base/namespace.h>
24 
BASE_BEGIN_NAMESPACE()25 BASE_BEGIN_NAMESPACE()
26 namespace Math {
27 #include <base/math/disable_warning_4201_heading.h>
28 
29 class Vec2;
30 class Vec3;
31 class Vec4;
32 
33 /** @ingroup group_math_vector */
34 /** Vector2 presentation */
35 class Vec2 final {
36 public:
37     union {
38         struct {
39             float x;
40             float y;
41         };
42         float data[2];
43     };
44     /** Subscript operator */
45     constexpr float& operator[](size_t index)
46     {
47         return data[index];
48     }
49 
50     /** Subscript operator */
51     constexpr const float& operator[](size_t index) const
52     {
53         return data[index];
54     }
55 
56     // Constructors
57     /** Default constructor */
58     inline constexpr Vec2() noexcept : data {} {}
59     /** Constructor for using floats as input */
60     inline constexpr Vec2(float xParameter, float yParameter) noexcept : x(xParameter), y(yParameter) {}
61     /** Constructor for using array of floats as input */
62     inline constexpr Vec2(const float parameter[2]) noexcept : x(parameter[0]), y(parameter[1]) {}
63     ~Vec2() = default;
64 
65     /** Add operator */
66     inline constexpr Vec2 operator+(const Vec2& v2) const
67     {
68         return Vec2(x + v2.x, y + v2.y);
69     }
70     /** Add operator */
71     inline constexpr Vec2& operator+=(const Vec2& rhs)
72     {
73         x += rhs.x;
74         y += rhs.y;
75         return *this;
76     }
77 
78     /** Negate operator */
79     inline constexpr Vec2 operator-() const
80     {
81         return Vec2(-x, -y);
82     }
83 
84     /** Subtract operator */
85     inline constexpr Vec2 operator-(const Vec2& v2) const
86     {
87         return Vec2(x - v2.x, y - v2.y);
88     }
89     /** Subtract operator */
90     inline constexpr Vec2& operator-=(const Vec2& rhs)
91     {
92         x -= rhs.x;
93         y -= rhs.y;
94         return *this;
95     }
96 
97     /** Multiply operator */
98     inline constexpr Vec2 operator*(const Vec2& v2) const
99     {
100         return Vec2(x * v2.x, y * v2.y);
101     }
102     /** Multiply operator */
103     inline constexpr Vec2& operator*=(const Vec2& rhs)
104     {
105         x *= rhs.x;
106         y *= rhs.y;
107         return *this;
108     }
109 
110     /** Divide operator */
111     inline constexpr Vec2 operator/(const Vec2& v2) const
112     {
113         return Vec2(x / v2.x, y / v2.y);
114     }
115     /** Divide operator */
116     inline constexpr Vec2& operator/=(const Vec2& rhs)
117     {
118         x /= rhs.x;
119         y /= rhs.y;
120         return *this;
121     }
122 
123     /** Multiplies vector by float value */
124     inline constexpr Vec2 operator*(float d) const
125     {
126         return Vec2(x * d, y * d);
127     }
128     /** Multiplies vector by float value */
129     inline constexpr Vec2& operator*=(float d)
130     {
131         x *= d;
132         y *= d;
133         return *this;
134     }
135 
136     /** Divides vector by float value */
137     inline constexpr Vec2 operator/(float d) const
138     {
139         return Vec2(x / d, y / d);
140     }
141     /** Divides vector by float value */
142     inline constexpr Vec2& operator/=(float d)
143     {
144         x /= d;
145         y /= d;
146         return *this;
147     }
148 
149     /** Add float from vector */
150     inline constexpr Vec2 operator+(float d) const
151     {
152         return Vec2(x + d, y + d);
153     }
154 
155     /** Subtract float from vector */
156     inline constexpr Vec2 operator-(float d) const
157     {
158         return Vec2(x - d, y - d);
159     }
160     /** Subtract float from vector */
161     inline constexpr Vec2& operator-=(float d)
162     {
163         x -= d;
164         y -= d;
165         return *this;
166     }
167 
168     // Equality operators
169     /** Equality operator, returns true if the vectors are equal */
170     constexpr bool operator==(const Vec2& rhs) const
171     {
172         const Vec2 temp = *this - rhs;
173         const float sqmgt = temp.x * temp.x + temp.y * temp.y;
174 
175         // Returns false in the presence of NaN values
176         return sqmgt < Math::EPSILON * Math::EPSILON;
177     }
178 
179     /** Inequality operator, returns true if vectors are different */
180     constexpr bool operator!=(const Vec2& rhs) const
181     {
182         // Returns true in the presence of NaN values
183         return !(*this == rhs);
184     }
185 };
186 
187 // Assert that Vec2 is the same as 2 floats
188 static_assert(sizeof(Vec2) == 2 * sizeof(float));
189 
190 /** @ingroup group_math_vector */
191 /** Vector3 presentation */
192 class Vec3 final {
193 public:
194     union {
195         struct {
196             float x;
197             float y;
198             float z;
199         };
200         float data[3];
201     };
202     /** Subscript operator */
203     constexpr float& operator[](size_t index);
204     /** Subscript operator */
205     constexpr const float& operator[](size_t index) const;
206 
207     // Constructors
208     /** Default constructor */
209     inline constexpr Vec3() noexcept;
210     /** Constructor for using floats as input */
211     inline constexpr Vec3(float xParameter, float yParameter, float zParameter) noexcept;
212     /** Constructor for using array of floats as input */
213     inline constexpr Vec3(const float d[]) noexcept;
214     /** Constructor for using vector4 as input, discards w component */
215     inline constexpr Vec3(const Vec4& vec) noexcept;
216     ~Vec3() = default;
217 
218     // Vec3 to Vec3 operations
219     /** Add operator */
220     inline constexpr Vec3 operator+(const Vec3& v2) const;
221     /** Add operator */
222     inline constexpr Vec3& operator+=(const Vec3& rhs);
223 
224     /** Negate operator */
225     inline constexpr Vec3 operator-() const;
226 
227     /** Subtract operator */
228     inline constexpr Vec3 operator-(const Vec3& v2) const;
229     /** Subtract operator */
230     inline constexpr Vec3& operator-=(const Vec3& rhs);
231 
232     /** Multiply operator */
233     inline constexpr Vec3 operator*(const Vec3& v2) const;
234     /** Multiply operator */
235     inline constexpr Vec3& operator*=(const Vec3& rhs);
236 
237     /** Divide operator */
238     inline constexpr Vec3 operator/(const Vec3& v2) const;
239     /** Divide operator */
240     inline constexpr Vec3& operator/=(const Vec3& rhs);
241 
242     // Equality operators
243     /** Equality operator, returns true if the vectors are equal */
244     constexpr bool operator==(const Vec3& rhs) const;
245 
246     /** Inequality operator, returns true if vectors are inequal */
247     constexpr bool operator!=(const Vec3& rhs) const;
248 
249     // Vec3 to float operations
250     /** Multiplies vector by float value */
251     inline constexpr Vec3 operator*(float d) const;
252     /** Multiplies vector by float value */
253     inline constexpr Vec3& operator*=(float d);
254 
255     /** Divides vector by float value */
256     inline constexpr Vec3 operator/(float d) const;
257     /** Divides vector by float value */
258     inline constexpr Vec3& operator/=(float d);
259 };
260 
261 // Assert that Vec3 is the same as 3 floats
262 static_assert(sizeof(Vec3) == 3 * sizeof(float));
263 
264 /** @ingroup group_math_vector */
265 /** Vector4 presentation */
266 class Vec4 final {
267 public:
268     union {
269         struct {
270             float x;
271             float y;
272             float z;
273             float w;
274         };
275         float data[4];
276     };
277     /** Subscript operator */
278     constexpr float& operator[](size_t index);
279     /** Subscript operator */
280     constexpr const float& operator[](size_t index) const;
281 
282     // Constructors
283     /** Default constructor */
284     inline constexpr Vec4() noexcept;
285     /** Constructor for using floats as input */
286     inline constexpr Vec4(float xParameter, float yParameter, float zParameter, float wParameter) noexcept;
287     /** Constructor for using array of floats as input */
288     inline constexpr Vec4(const float d[4]) noexcept;
289     /** Constructor for using vector3 and float as input (float as w component) */
290     inline constexpr Vec4(const Vec3& vec, float w) noexcept;
291     ~Vec4() = default;
292 
293     /** Add operator */
294     inline constexpr Vec4 operator+(const Vec4& v2) const;
295     /** Add operator */
296     inline constexpr Vec4& operator+=(const Vec4& rhs);
297 
298     /** Negate operator */
299     inline constexpr Vec4 operator-() const;
300 
301     /** Subtract operator */
302     inline constexpr Vec4 operator-(const Vec4& v2) const;
303     /** Subtract operator */
304     inline constexpr Vec4& operator-=(const Vec4& rhs);
305 
306     /** Multiply operator */
307     inline constexpr Vec4 operator*(const Vec4& v2) const;
308     /** Multiply operator */
309     inline constexpr Vec4& operator*=(const Vec4& rhs);
310 
311     /** Divide operator */
312     inline constexpr Vec4 operator/(const Vec4& v2) const;
313     /** Divide operator */
314     inline constexpr Vec4& operator/=(const Vec4& rhs);
315 
316     /** Multiplies a vector by a float value */
317     inline constexpr Vec4 operator*(float d) const;
318     /** Multiplies a vector by a float value */
319     inline constexpr Vec4& operator*=(float d);
320 
321     /** Divides a vector by a float value */
322     inline constexpr Vec4 operator/(float d) const;
323     /** Divides a vector by a float value */
324     inline constexpr Vec4& operator/=(float d);
325 
326     // Equality operators
327     /** Equality operator, returns true if the vectors are equal */
328     constexpr bool operator==(const Vec4& rhs) const;
329 
330     /** Inequality operator, returns true if vectors are different */
331     constexpr bool operator!=(const Vec4& rhs) const;
332 };
333 
334 // Assert that Vec4 is the same as 4 floats
335 static_assert(sizeof(Vec4) == 4 * sizeof(float));
336 
337 /** @ingroup group_math_vector */
338 /** Unsigned integer vector2 presentation */
339 class UVec2 final {
340 public:
341     union {
342         struct {
343             uint32_t x;
344             uint32_t y;
345         };
346         uint32_t data[2];
347     };
348 
349     /** Subscript operator */
350     constexpr uint32_t& operator[](size_t index)
351     {
352         return data[index];
353     }
354     /** Subscript operator */
355     constexpr const uint32_t& operator[](size_t index) const
356     {
357         return data[index];
358     }
359 
360     // Constructors
361     /** Default constructor */
362     inline constexpr UVec2() : data {} {}
363     /** Constructor for using two uint32_t's as input */
364     inline constexpr UVec2(uint32_t xParameter, uint32_t yParameter) : x(xParameter), y(yParameter) {}
365     ~UVec2() = default;
366 
367     /** Add operator */
368     inline constexpr UVec2 operator+(const UVec2& v2) const
369     {
370         return UVec2(x + v2.x, y + v2.y);
371     }
372     /** Add operator */
373     inline constexpr UVec2& operator+=(const UVec2& rhs)
374     {
375         x += rhs.x;
376         y += rhs.y;
377         return *this;
378     }
379 
380     /** Subtract operator */
381     inline constexpr UVec2 operator-(const UVec2& v2) const
382     {
383         return UVec2(x - v2.x, y - v2.y);
384     }
385     /** Subtract operator */
386     inline constexpr UVec2& operator-=(const UVec2& rhs)
387     {
388         x -= rhs.x;
389         y -= rhs.y;
390         return *this;
391     }
392 
393     /** Multiply operator */
394     inline constexpr UVec2 operator*(const UVec2& v2) const
395     {
396         return UVec2(x * v2.x, y * v2.y);
397     }
398     /** Multiply operator */
399     inline constexpr UVec2& operator*=(const UVec2& rhs)
400     {
401         x *= rhs.x;
402         y *= rhs.y;
403         return *this;
404     }
405 
406     /** Divide operator */
407     inline constexpr UVec2 operator/(const UVec2& v2) const
408     {
409         return UVec2(x / v2.x, y / v2.y);
410     }
411     /** Divide operator */
412     inline constexpr UVec2& operator/=(const UVec2& rhs)
413     {
414         x /= rhs.x;
415         y /= rhs.y;
416         return *this;
417     }
418 
419     /** Multiplies vector by float value */
420     inline constexpr UVec2 operator*(uint32_t d) const
421     {
422         return UVec2(x * d, y * d);
423     }
424     /** Multiplies vector by float value */
425     inline constexpr UVec2& operator*=(uint32_t d)
426     {
427         x *= d;
428         y *= d;
429         return *this;
430     }
431 
432     /** Divides vector by float value */
433     inline constexpr UVec2 operator/(uint32_t d) const
434     {
435         return UVec2(x / d, y / d);
436     }
437     /** Divides vector by float value */
438     inline constexpr UVec2& operator/=(uint32_t d)
439     {
440         if (d == 0) {
441             x = y = UINT32_MAX;
442             return *this;
443         }
444 
445         x /= d;
446         y /= d;
447         return *this;
448     }
449 
450     /** Subtract uint32_t from uvector2 */
451     inline constexpr UVec2 operator-(uint32_t d) const
452     {
453         return UVec2(x - d, y - d);
454     }
455     /** Subtract uint32_t from uvector2 */
456     inline constexpr UVec2& operator-=(uint32_t d)
457     {
458         x -= d;
459         y -= d;
460         return *this;
461     }
462 
463     /** Equality operator, returns true if the vectors are equal */
464     constexpr bool operator==(const UVec2& rhs) const
465     {
466         if (x != rhs.x) {
467             return false;
468         }
469         if (y != rhs.y) {
470             return false;
471         }
472         return true;
473     }
474 
475     /** Inequality operator, returns true if vectors are different */
476     constexpr bool operator!=(const UVec2& rhs) const
477     {
478         // Returns true in the presence of NaN values
479         return !(*this == rhs);
480     }
481 };
482 
483 // Assert that UVec2 is the same as 2 uint32_t's
484 static_assert(sizeof(UVec2) == 2 * sizeof(uint32_t));
485 
486 /** @ingroup group_math_vector */
487 /** Unsigned integer vector3 presentation */
488 class UVec3 {
489 public:
490     union {
491         struct {
492             uint32_t x;
493             uint32_t y;
494             uint32_t z;
495         };
496         uint32_t data[3];
497     };
498 
499     // Constructors
500     /** Default constructor */
501     inline constexpr UVec3() : data {} {}
502     /** Constructor for using three uint32_t's as input */
503     inline constexpr UVec3(uint32_t x, uint32_t y, uint32_t z) : x(x), y(y), z(z) {}
504     ~UVec3() = default;
505 
506     /** Subscript operator */
507     constexpr uint32_t& operator[](size_t index)
508     {
509         return data[index];
510     }
511 
512     /** Subscript operator */
513     constexpr const uint32_t& operator[](size_t index) const
514     {
515         return data[index];
516     }
517 
518     /** Equality operator, returns true if the vectors are equal */
519     constexpr bool operator==(const UVec3& rhs) const
520     {
521         if (x != rhs.x) {
522             return false;
523         }
524         if (y != rhs.y) {
525             return false;
526         }
527         if (z != rhs.z) {
528             return false;
529         }
530         return true;
531     }
532 
533     /** Inequality operator, returns true if vectors are different */
534     constexpr bool operator!=(const UVec3& rhs) const
535     {
536         // Returns true in the presence of NaN values
537         return !(*this == rhs);
538     }
539 };
540 
541 // Assert that UVec3 is the same as 3 uint32_t's
542 static_assert(sizeof(UVec3) == 3 * sizeof(uint32_t));
543 
544 /** @ingroup group_math_vector */
545 /** Unsigned integer vector4 presentation */
546 class UVec4 {
547 public:
548     union {
549         struct {
550             uint32_t x;
551             uint32_t y;
552             uint32_t z;
553             uint32_t w;
554         };
555         uint32_t data[4];
556     };
557     // Constructors
558     /** Default constructor */
559     inline constexpr UVec4() : data {} {}
560     /** Constructor for using four uint32_t's as input */
561     inline constexpr UVec4(uint32_t x, uint32_t y, uint32_t z, uint32_t w) : x(x), y(y), z(z), w(w) {}
562     ~UVec4() = default;
563 
564     /** Subscript operator */
565     constexpr uint32_t& operator[](size_t index)
566     {
567         return data[index];
568     }
569 
570     /** Subscript operator */
571     constexpr const uint32_t& operator[](size_t index) const
572     {
573         return data[index];
574     }
575 
576     /** Equality operator, returns true if the vectors are equal */
577     constexpr bool operator==(const UVec4& rhs) const
578     {
579         if (x != rhs.x) {
580             return false;
581         }
582         if (y != rhs.y) {
583             return false;
584         }
585         if (z != rhs.z) {
586             return false;
587         }
588         if (w != rhs.w) {
589             return false;
590         }
591         return true;
592     }
593 
594     /** Inequality operator, returns true if vectors are different */
595     constexpr bool operator!=(const UVec4& rhs) const
596     {
597         // Returns true in the presence of NaN values
598         return !(*this == rhs);
599     }
600 };
601 
602 // Assert that UVec4 is the same as 4 uint32_t's
603 static_assert(sizeof(UVec4) == 4 * sizeof(uint32_t));
604 
605 /** @ingroup group_math_vector */
606 /** Signed integer vector2 presentation */
607 class IVec2 final {
608 public:
609     union {
610         struct {
611             int32_t x;
612             int32_t y;
613         };
614         int32_t data[2];
615     };
616 
617     /** Subscript operator */
618     constexpr int32_t& operator[](size_t index)
619     {
620         return data[index];
621     }
622     /** Subscript operator */
623     constexpr const int32_t& operator[](size_t index) const
624     {
625         return data[index];
626     }
627 
628     // Constructors
629     /** Default constructor */
630     inline constexpr IVec2() : data {} {}
631     /** Constructor for using two int32_t's as input */
632     inline constexpr IVec2(int32_t xParameter, int32_t yParameter) : x(xParameter), y(yParameter) {}
633     ~IVec2() = default;
634 
635     /** Add operator */
636     inline constexpr IVec2 operator+(const IVec2& v2) const
637     {
638         return IVec2(x + v2.x, y + v2.y);
639     }
640     /** Add operator */
641     inline constexpr IVec2& operator+=(const IVec2& rhs)
642     {
643         x += rhs.x;
644         y += rhs.y;
645         return *this;
646     }
647 
648     /** Subtract operator */
649     inline constexpr IVec2 operator-(const IVec2& v2) const
650     {
651         return IVec2(x - v2.x, y - v2.y);
652     }
653     /** Subtract operator */
654     inline constexpr IVec2& operator-=(const IVec2& rhs)
655     {
656         x -= rhs.x;
657         y -= rhs.y;
658         return *this;
659     }
660 
661     /** Multiply operator */
662     inline constexpr IVec2 operator*(const IVec2& v2) const
663     {
664         return IVec2(x * v2.x, y * v2.y);
665     }
666     /** Multiply operator */
667     inline constexpr IVec2& operator*=(const IVec2& rhs)
668     {
669         x *= rhs.x;
670         y *= rhs.y;
671         return *this;
672     }
673 
674     /** Divide operator */
675     inline constexpr IVec2 operator/(const IVec2& v2) const
676     {
677         return IVec2(x / v2.x, y / v2.y);
678     }
679     /** Divide operator */
680     inline constexpr IVec2& operator/=(const IVec2& rhs)
681     {
682         x /= rhs.x;
683         y /= rhs.y;
684         return *this;
685     }
686 
687     /** Multiplies vector by float value */
688     inline constexpr IVec2 operator*(int32_t d) const
689     {
690         return IVec2(x * d, y * d);
691     }
692     /** Multiplies vector by float value */
693     inline constexpr IVec2& operator*=(int32_t d)
694     {
695         x *= d;
696         y *= d;
697         return *this;
698     }
699 
700     /** Divides vector by float value */
701     inline constexpr IVec2 operator/(int32_t d) const
702     {
703         return IVec2(x / d, y / d);
704     }
705     /** Divides vector by float value */
706     inline constexpr IVec2& operator/=(int32_t d)
707     {
708         if (d == 0) {
709             x = y = INT32_MAX;
710             return *this;
711         }
712 
713         x /= d;
714         y /= d;
715         return *this;
716     }
717 
718     /** Subtract int32_t from IVector2 */
719     inline constexpr IVec2 operator-(int32_t d) const
720     {
721         return IVec2(x - d, y - d);
722     }
723     /** Subtract int32_t from IVector2 */
724     inline constexpr IVec2& operator-=(int32_t d)
725     {
726         x -= d;
727         y -= d;
728         return *this;
729     }
730 
731     /** Equality operator, returns true if the vectors are equal */
732     constexpr bool operator==(const IVec2& rhs) const
733     {
734         if (x != rhs.x) {
735             return false;
736         }
737         if (y != rhs.y) {
738             return false;
739         }
740         return true;
741     }
742 
743     /** Inequality operator, returns true if vectors are different */
744     constexpr bool operator!=(const IVec2& rhs) const
745     {
746         // Returns true in the presence of NaN values
747         return !(*this == rhs);
748     }
749 };
750 
751 // Assert that IVec2 is the same as 2 int32_t's
752 static_assert(sizeof(IVec2) == 2 * sizeof(int32_t));
753 
754 /** @ingroup group_math_vector */
755 /** Signed integer vector3 presentation */
756 class IVec3 {
757 public:
758     union {
759         struct {
760             int32_t x;
761             int32_t y;
762             int32_t z;
763         };
764         int32_t data[3];
765     };
766 
767     // Constructors
768     /** Default constructor */
769     inline constexpr IVec3() : data {} {}
770     /** Constructor for using three int32_t's as input */
771     inline constexpr IVec3(int32_t x, int32_t y, int32_t z) : x(x), y(y), z(z) {}
772     ~IVec3() = default;
773 
774     /** Subscript operator */
775     constexpr int32_t& operator[](size_t index)
776     {
777         return data[index];
778     }
779 
780     /** Subscript operator */
781     constexpr const int32_t& operator[](size_t index) const
782     {
783         return data[index];
784     }
785 
786     /** Equality operator, returns true if the vectors are equal */
787     constexpr bool operator==(const IVec3& rhs) const
788     {
789         if (x != rhs.x) {
790             return false;
791         }
792         if (y != rhs.y) {
793             return false;
794         }
795         if (z != rhs.z) {
796             return false;
797         }
798         return true;
799     }
800 
801     /** Inequality operator, returns true if vectors are different */
802     constexpr bool operator!=(const IVec3& rhs) const
803     {
804         // Returns true in the presence of NaN values
805         return !(*this == rhs);
806     }
807 };
808 
809 // Assert that IVec3 is the same as 3 int32_t's
810 static_assert(sizeof(IVec3) == 3 * sizeof(int32_t));
811 
812 /** @ingroup group_math_vector */
813 /** Signed integer vector4 presentation */
814 class IVec4 {
815 public:
816     union {
817         struct {
818             int32_t x;
819             int32_t y;
820             int32_t z;
821             int32_t w;
822         };
823         int32_t data[4];
824     };
825     // Constructors
826     /** Default constructor */
827     inline constexpr IVec4() : data {} {}
828     /** Constructor for using four int32_t's as input */
829     inline constexpr IVec4(int32_t x, int32_t y, int32_t z, int32_t w) : x(x), y(y), z(z), w(w) {}
830     ~IVec4() = default;
831 
832     /** Subscript operator */
833     constexpr int32_t& operator[](size_t index)
834     {
835         return data[index];
836     }
837 
838     /** Subscript operator */
839     constexpr const int32_t& operator[](size_t index) const
840     {
841         return data[index];
842     }
843 
844     /** Equality operator, returns true if the vectors are equal */
845     constexpr bool operator==(const IVec4& rhs) const
846     {
847         if (x != rhs.x) {
848             return false;
849         }
850         if (y != rhs.y) {
851             return false;
852         }
853         if (z != rhs.z) {
854             return false;
855         }
856         if (w != rhs.w) {
857             return false;
858         }
859         return true;
860     }
861 
862     /** Inequality operator, returns true if vectors are different */
863     constexpr bool operator!=(const IVec4& rhs) const
864     {
865         // Returns true in the presence of NaN values
866         return !(*this == rhs);
867     }
868 };
869 
870 // Assert that IVec4 is the same as 4 int32_t's
871 static_assert(sizeof(IVec4) == 4 * sizeof(int32_t));
872 
873 constexpr float& Vec3::operator[](size_t index)
874 {
875     return data[index];
876 }
877 constexpr const float& Vec3::operator[](size_t index) const
878 {
879     return data[index];
880 }
881 
882 // Constructors
883 inline constexpr Vec3::Vec3() noexcept : data {} {}
884 inline constexpr Vec3::Vec3(float xParameter, float yParameter, float zParameter) noexcept
885     : x(xParameter), y(yParameter), z(zParameter)
886 {}
887 inline constexpr Vec3::Vec3(const float d[]) noexcept : x(d[0]), y(d[1]), z(d[2]) {}
888 inline constexpr Vec3::Vec3(const Vec4& vec) noexcept : x(vec.x), y(vec.y), z(vec.z) {}
889 
890 // Vec3 to Vec3 operations
891 // Add
892 inline constexpr Vec3 Vec3::operator+(const Vec3& v2) const
893 {
894     return Vec3(x + v2.x, y + v2.y, z + v2.z);
895 }
896 // Add
897 inline constexpr Vec3& Vec3::operator+=(const Vec3& rhs)
898 {
899     x += rhs.x;
900     y += rhs.y;
901     z += rhs.z;
902     return *this;
903 }
904 
905 // Negate
906 inline constexpr Vec3 Vec3::operator-() const
907 {
908     return Vec3(-x, -y, -z);
909 }
910 
911 // Subtract
912 inline constexpr Vec3 Vec3::operator-(const Vec3& v2) const
913 {
914     return Vec3(x - v2.x, y - v2.y, z - v2.z);
915 }
916 // Subtract
917 inline constexpr Vec3& Vec3::operator-=(const Vec3& rhs)
918 {
919     x -= rhs.x;
920     y -= rhs.y;
921     z -= rhs.z;
922     return *this;
923 }
924 
925 // Multiply
926 inline constexpr Vec3 Vec3::operator*(const Vec3& v2) const
927 {
928     return Vec3(x * v2.x, y * v2.y, z * v2.z);
929 }
930 // Multiply
931 inline constexpr Vec3& Vec3::operator*=(const Vec3& rhs)
932 {
933     x *= rhs.x;
934     y *= rhs.y;
935     z *= rhs.z;
936     return *this;
937 }
938 
939 // Divide
940 inline constexpr Vec3 Vec3::operator/(const Vec3& v2) const
941 {
942     return Vec3(x / v2.x, y / v2.y, z / v2.z);
943 }
944 // Divide
945 inline constexpr Vec3& Vec3::operator/=(const Vec3& rhs)
946 {
947     x /= rhs.x;
948     y /= rhs.y;
949     z /= rhs.z;
950     return *this;
951 }
952 
953 // Equality operators
954 // Returns true if the vectors are equal
955 constexpr bool Vec3::operator==(const Vec3& rhs) const
956 {
957     const Vec3 temp = *this - rhs;
958     const float sqmgt = temp.x * temp.x + temp.y * temp.y + temp.z * temp.z;
959 
960     // Returns false in the presence of NaN values
961     return sqmgt < Math::EPSILON * Math::EPSILON;
962 }
963 
964 // Returns true if vectors are different.
965 constexpr bool Vec3::operator!=(const Vec3& rhs) const
966 {
967     // Returns true in the presence of NaN values
968     return !(*this == rhs);
969 }
970 
971 // Vec3 to float operations
972 // Multiplies vector by float value
973 inline constexpr Vec3 Vec3::operator*(float d) const
974 {
975     return Vec3(x * d, y * d, z * d);
976 }
977 inline constexpr Vec3& Vec3::operator*=(float d)
978 {
979     x *= d;
980     y *= d;
981     z *= d;
982     return *this;
983 }
984 
985 // Divides vector by float value
986 inline constexpr Vec3 Vec3::operator/(float d) const
987 {
988     return Vec3(x / d, y / d, z / d);
989 }
990 inline constexpr Vec3& Vec3::operator/=(float d)
991 {
992     x /= d;
993     y /= d;
994     z /= d;
995     return *this;
996 }
997 
998 constexpr float& Vec4::operator[](size_t index)
999 {
1000     return data[index];
1001 }
1002 constexpr const float& Vec4::operator[](size_t index) const
1003 {
1004     return data[index];
1005 }
1006 
1007 // Constructors
1008 inline constexpr Vec4::Vec4() noexcept : data {} {}
1009 inline constexpr Vec4::Vec4(float xParameter, float yParameter, float zParameter, float wParameter) noexcept
1010     : x(xParameter), y(yParameter), z(zParameter), w(wParameter)
1011 {}
1012 inline constexpr Vec4::Vec4(const float d[4]) noexcept : x(d[0]), y(d[1]), z(d[2]), w(d[3]) {}
1013 inline constexpr Vec4::Vec4(const Vec3& vec, float w) noexcept : x(vec.x), y(vec.y), z(vec.z), w(w) {}
1014 
1015 // Add
1016 inline constexpr Vec4 Vec4::operator+(const Vec4& v2) const
1017 {
1018     return Vec4(x + v2.x, y + v2.y, z + v2.z, w + v2.w);
1019 }
1020 
1021 inline constexpr Vec4& Vec4::operator+=(const Vec4& rhs)
1022 {
1023     x += rhs.x;
1024     y += rhs.y;
1025     z += rhs.z;
1026     w += rhs.w;
1027     return *this;
1028 }
1029 
1030 // Negate
1031 inline constexpr Vec4 Vec4::operator-() const
1032 {
1033     return Vec4(-x, -y, -z, -w);
1034 }
1035 
1036 // Subtract
1037 inline constexpr Vec4 Vec4::operator-(const Vec4& v2) const
1038 {
1039     return Vec4(x - v2.x, y - v2.y, z - v2.z, w - v2.w);
1040 }
1041 
1042 inline constexpr Vec4& Vec4::operator-=(const Vec4& rhs)
1043 {
1044     x -= rhs.x;
1045     y -= rhs.y;
1046     z -= rhs.z;
1047     w -= rhs.w;
1048     return *this;
1049 }
1050 
1051 // Multiply
1052 inline constexpr Vec4 Vec4::operator*(const Vec4& v2) const
1053 {
1054     return Vec4(x * v2.x, y * v2.y, z * v2.z, w * v2.w);
1055 }
1056 
1057 inline constexpr Vec4& Vec4::operator*=(const Vec4& rhs)
1058 {
1059     x *= rhs.x;
1060     y *= rhs.y;
1061     z *= rhs.z;
1062     w *= rhs.w;
1063     return *this;
1064 }
1065 
1066 // Divide
1067 inline constexpr Vec4 Vec4::operator/(const Vec4& v2) const
1068 {
1069     return Vec4(x / v2.x, y / v2.y, z / v2.z, w / v2.w);
1070 }
1071 
1072 inline constexpr Vec4& Vec4::operator/=(const Vec4& rhs)
1073 {
1074     x /= rhs.x;
1075     y /= rhs.y;
1076     z /= rhs.z;
1077     w /= rhs.w;
1078     return *this;
1079 }
1080 
1081 // Multiplies a vector by a float value
1082 inline constexpr Vec4 Vec4::operator*(float d) const
1083 {
1084     return Vec4(x * d, y * d, z * d, w * d);
1085 }
1086 inline constexpr Vec4& Vec4::operator*=(float d)
1087 {
1088     x *= d;
1089     y *= d;
1090     z *= d;
1091     w *= d;
1092     return *this;
1093 }
1094 
1095 // Divides a vector by a float value
1096 inline constexpr Vec4 Vec4::operator/(float d) const
1097 {
1098     return Vec4(x / d, y / d, z / d, w / d);
1099 }
1100 inline constexpr Vec4& Vec4::operator/=(float d)
1101 {
1102     x /= d;
1103     y /= d;
1104     z /= d;
1105     w /= d;
1106     return *this;
1107 }
1108 
1109 // Equality operators
1110 // Returns true if the vectors are equal.
1111 constexpr bool Vec4::operator==(const Vec4& rhs) const
1112 {
1113     const Vec4 temp = *this - rhs;
1114     const float sqmgt = temp.x * temp.x + temp.y * temp.y + temp.z * temp.z + temp.w * temp.w;
1115 
1116     // Returns false in the presence of NaN values
1117     return sqmgt < Math::EPSILON * Math::EPSILON;
1118 }
1119 
1120 // Returns true if vectors are different.
1121 constexpr bool Vec4::operator!=(const Vec4& rhs) const
1122 {
1123     // Returns true in the presence of NaN values
1124     return !(*this == rhs);
1125 }
1126 
1127 #include <base/math/disable_warning_4201_footer.h>
1128 } // namespace Math
1129 BASE_END_NAMESPACE()
1130 
1131 #endif // API_BASE_MATH_VECTOR_H
1132