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