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