LkEngine 0.1.2
 
Loading...
Searching...
No Matches
Vector3.h
1#pragma once
2
3#include <type_traits>
4#include <ostream>
5
6#include <glm/glm.hpp>
7
9
10namespace LkEngine {
11
18 template<typename SizeType>
19 struct TVector3;
20
21 namespace Math::Internal::Vector3Impl
22 {
27 template<typename SizeType, typename VectorTypeA, typename VectorTypeB, typename ReturnType>
28 struct Min
29 {
30 FORCEINLINE static ReturnType Calculate(const VectorTypeA& A, const VectorTypeB& B)
31 {
32 static_assert((sizeof(VectorTypeA) > 0) && (sizeof(VectorTypeB) > 0), "Unsupported vector type");
33 return ReturnType();
34 }
35 };
36
43 template<typename SizeType>
44 struct Min<SizeType, TVector3<SizeType> /*== A*/, TVector3<SizeType> /*== B*/, TVector3<SizeType> /*== ReturnType*/>
45 {
46 FORCEINLINE static TVector3<SizeType> Calculate(const TVector3<SizeType>& A, const TVector3<SizeType>& B)
47 {
48 return TVector3<SizeType>(std::min(A.X, B.X),
49 std::min(A.Y, B.Y),
50 std::min(A.Z, B.Z));
51 }
52 };
53
60 template<typename SizeType>
61 struct Min<SizeType, TVector3<SizeType> /*== A*/, glm::vec3 /*== B*/, TVector3<SizeType> /*== ReturnType*/>
62 {
63 FORCEINLINE static TVector3<SizeType> Calculate(const TVector3<SizeType>& A, const glm::vec3& B)
64 {
65 return TVector3<SizeType>(std::min(A.X, B.x),
66 std::min(A.Y, B.y),
67 std::min(A.Z, B.z));
68 }
69 };
70
77 template<typename SizeType>
78 struct Min<SizeType, TVector3<SizeType> /*== A*/, glm::vec3 /*== B*/, SizeType /*== ReturnType*/>
79 {
80 FORCEINLINE static SizeType Calculate(const TVector3<SizeType>& A, const glm::vec3& B)
81 {
82 return std::min({
83 A.X, A.Y, A.Z,
84 B.x, B.y, B.z
85 });
86 }
87 };
88
95 template<typename SizeType>
96 struct Min<SizeType, glm::vec3 /*== A*/, TVector3<SizeType> /*== B*/, TVector3<SizeType> /*== ReturnType*/>
97 {
98 FORCEINLINE static TVector3<SizeType> Calculate(const glm::vec3& A, const TVector3<SizeType>& B)
99 {
100 return TVector3<SizeType>(std::min(A.x, B.X),
101 std::min(A.y, B.Y),
102 std::min(A.z, B.Z));
103 }
104 };
105
112 template<typename SizeType>
113 struct Min<SizeType, glm::vec3 /*== A*/, glm::vec3 /*== B*/, TVector3<SizeType> /*== ReturnType*/>
114 {
115 FORCEINLINE static TVector3<SizeType> Calculate(const glm::vec3& A, const glm::vec3& B)
116 {
117 return TVector3<SizeType>(std::min(A.x, B.x),
118 std::min(A.y, B.y),
119 std::min(A.z, B.z));
120 }
121 };
122
123
127 template<typename SizeType, typename VectorTypeA, typename VectorTypeB, typename ReturnType>
128 struct Max
129 {
130 FORCEINLINE static ReturnType Calculate(const VectorTypeA& A, const VectorTypeB& B)
131 {
132 static_assert((sizeof(VectorTypeA) > 0) && (sizeof(VectorTypeB) > 0), "Unsupported vector type");
133 return ReturnType();
134 }
135 };
136
143 template<typename SizeType>
144 struct Max<SizeType, TVector3<SizeType> /*== A*/, TVector3<SizeType> /*== B*/, TVector3<SizeType> /*== ReturnType*/>
145 {
146 FORCEINLINE static TVector3<SizeType> Calculate(const TVector3<SizeType>& A, const TVector3<SizeType>& B)
147 {
148 return TVector3<SizeType>(std::max(A.X, B.X),
149 std::max(A.Y, B.Y),
150 std::max(A.Z, B.Z));
151 }
152 };
153
160 template<typename SizeType>
161 struct Max<SizeType, TVector3<SizeType> /*== A*/, glm::vec3 /*== B*/, TVector3<SizeType> /*== ReturnType*/>
162 {
163 FORCEINLINE static TVector3<SizeType> Calculate(const TVector3<SizeType>& A, glm::vec3& B)
164 {
165 return TVector3<SizeType>(
166 std::max(A.X, B.x),
167 std::max(A.Y, B.y),
168 std::max(A.Z, B.z)
169 );
170 }
171 };
172
179 template<typename SizeType>
180 struct Max<SizeType, glm::vec3 /*== A*/, TVector3<SizeType> /*== B*/, TVector3<SizeType> /*== ReturnType*/>
181 {
182 FORCEINLINE static TVector3<SizeType> Calculate(const glm::vec3& A, const TVector3<SizeType>& B)
183 {
184 return TVector3<SizeType>(std::max(A.x, B.X),
185 std::max(A.y, B.Y),
186 std::max(A.z, B.Z));
187 }
188 };
189
196 template<typename SizeType>
197 struct Max<SizeType, glm::vec3 /*== A*/, glm::vec3 /*== B*/, TVector3<SizeType> /*== ReturnType*/>
198 {
199 FORCEINLINE static TVector3<SizeType> Calculate(const glm::vec3& A, const glm::vec3& B)
200 {
201 return TVector3<SizeType>(std::max(A.x, B.x),
202 std::max(A.y, B.y),
203 std::max(A.z, B.z));
204 }
205 };
206
207
211 template<typename SizeType, typename VectorTypeA, typename VectorTypeB, typename ReturnType>
212 struct Dot
213 {
214 static_assert(!std::conjunction_v<
215 std::is_same<ReturnType, VectorTypeA>,
216 std::is_same<ReturnType, VectorTypeB>
217 >, "Dot failed, invalid return type");
218 FORCEINLINE static ReturnType Calculate(const VectorTypeA& A, const VectorTypeB& B)
219 {
220 static_assert((sizeof(VectorTypeA) > 0) && (sizeof(VectorTypeB) > 0), "Unsupported vector type");
221 return ReturnType();
222 }
223 };
224
230 template<typename SizeType>
231 struct Dot<SizeType, TVector3<SizeType> /*== A*/, TVector3<SizeType> /*== B*/, SizeType /*== ReturnType*/>
232 {
233 FORCEINLINE static SizeType Calculate(const TVector3<SizeType>& A, const TVector3<SizeType>& B)
234 {
235 return (A.X * B.X) + (A.Y * B.Y) + (A.Z * B.Z);
236 }
237 };
238
244 template<typename SizeType>
245 struct Dot<SizeType, TVector3<SizeType> /*== A*/, glm::vec3 /*== B*/, SizeType /*== ReturnType*/>
246 {
247 FORCEINLINE static SizeType Calculate(const TVector3<SizeType>& A, const glm::vec3& B)
248 {
249 return (A.X * B.x) + (A.Y * B.y) + (A.Z * B.z);
250 }
251 };
252
258 template<typename SizeType>
259 struct Dot<SizeType, glm::vec3 /*== A*/, TVector3<SizeType> /*== B*/, SizeType /*== ReturnType*/>
260 {
261 FORCEINLINE static SizeType Calculate(const glm::vec3& A, const TVector3<SizeType>& B)
262 {
263 return (A.x * B.X) + (A.y * B.Y) + (A.z * B.Z);
264 }
265 };
266
272 template<typename SizeType>
273 struct Dot<SizeType, glm::vec3 /*== A*/, glm::vec3 /*== B*/, SizeType /*== ReturnType*/>
274 {
275 FORCEINLINE static SizeType Calculate(const glm::vec3& A, const glm::vec3& B)
276 {
277 return (A.x * B.x) + (A.y * B.y) + (A.z * B.z);
278 }
279 };
280
281
285 template<typename SizeType, typename VectorType, typename ReturnType, bool DivisionByZeroGuard>
286 struct Inverse
287 {
288 FORCEINLINE static ReturnType Calculate(const VectorType& Vector)
289 {
290 static_assert((sizeof(VectorType) > 0), "Unsupported vector type");
291 return ReturnType();
292 }
293 };
294
302 template<typename SizeType>
303 struct Inverse<SizeType, TVector3<SizeType> /*== Target*/, TVector3<SizeType> /*== ReturnType*/, true /*== Safe*/>
304 {
305 FORCEINLINE static TVector3<SizeType> Calculate(const TVector3<SizeType>& Vector)
306 {
307 return TVector3<SizeType>(
308 (Vector.X != static_cast<SizeType>(0)) ? (static_cast<SizeType>(1) / Vector.X) : static_cast<SizeType>(0),
309 (Vector.Y != static_cast<SizeType>(0)) ? (static_cast<SizeType>(1) / Vector.Y) : static_cast<SizeType>(0),
310 (Vector.Z != static_cast<SizeType>(0)) ? (static_cast<SizeType>(1) / Vector.Z) : static_cast<SizeType>(0)
311 );
312 }
313 };
314
322 template<typename SizeType>
323 struct Inverse<SizeType, TVector3<SizeType> /*== Target*/, TVector3<SizeType> /*== ReturnType*/, false /*== Safe*/>
324 {
325 FORCEINLINE static TVector3<SizeType> Calculate(const TVector3<SizeType>& Vector)
326 {
327 return TVector3<SizeType>(
328 (static_cast<SizeType>(1) / Vector.X),
329 (static_cast<SizeType>(1) / Vector.Y),
330 (static_cast<SizeType>(1) / Vector.Z)
331 );
332 }
333 };
334
338 template<typename SizeType, typename VectorType, typename ReturnType, bool Safe>
340 {
341 FORCEINLINE static ReturnType Calculate(const VectorType& Vector)
342 {
343 static_assert((sizeof(VectorType) > 0), "Unsupported vector type");
344 return ReturnType();
345 }
346 };
347
354 template<typename SizeType>
355 struct Normalize<SizeType, TVector3<SizeType> /*== Target*/, TVector3<SizeType> /*== ReturnType*/, false /*== Safe*/>
356 {
357 FORCEINLINE static TVector3<SizeType> Calculate(const TVector3<SizeType>& Vector)
358 {
359 const SizeType Magnitude = std::sqrt((Vector.X * Vector.X) + (Vector.Y * Vector.Y) + (Vector.Z * Vector.Z));
360 return TVector3<SizeType>(Vector / Magnitude);
361 }
362 };
363
370 template<typename SizeType>
371 struct Normalize<SizeType, glm::vec3 /*== Target*/, TVector3<SizeType> /*== ReturnType*/, false /*== Safe*/>
372 {
373 FORCEINLINE static TVector3<SizeType> Calculate(const glm::vec3& Vector)
374 {
375 const SizeType Magnitude = std::sqrt((Vector.x * Vector.x) + (Vector.y * Vector.y) + (Vector.z * Vector.z));
376 return TVector3<SizeType>(Vector / Magnitude);
377 }
378 };
379
386 template<typename SizeType>
387 struct Normalize<SizeType, TVector3<SizeType> /*== Target*/, TVector3<SizeType> /*== ReturnType*/, true /*== Safe*/>
388 {
389 FORCEINLINE static TVector3<SizeType> Calculate(const TVector3<SizeType>& Vector)
390 {
391 const SizeType Magnitude = std::sqrt((Vector.X * Vector.X) + (Vector.Y * Vector.Y) + (Vector.Z * Vector.Z));
392 if (Magnitude > static_cast<SizeType>(0))
393 {
394 return TVector3<SizeType>(Vector / Magnitude);
395 }
396
397 return Vector;
398 }
399 };
400
407 template<typename SizeType>
408 struct Normalize<SizeType, glm::vec3 /*== Target*/, TVector3<SizeType> /*== ReturnType*/, true /*== Safe*/>
409 {
410 FORCEINLINE static TVector3<SizeType> Calculate(const glm::vec3& Vector)
411 {
412 const SizeType Magnitude = std::sqrt((Vector.x * Vector.x) + (Vector.y * Vector.y) + (Vector.z * Vector.z));
413 if (Magnitude > static_cast<SizeType>(0))
414 {
415 return TVector3<SizeType>(Vector / Magnitude);
416 }
417
418 return TVector3<SizeType>(Vector);
419 }
420 };
421
422
426 template<typename SizeType, typename VectorTypeA, typename VectorTypeB, typename ReturnType = TVector3<SizeType>>
427 struct Cross
428 {
429 FORCEINLINE static ReturnType Calculate(const TVector3<SizeType>& A, const TVector3<SizeType>& B)
430 {
431 static_assert((sizeof(VectorTypeA) > 0) && (sizeof(VectorTypeB) > 0), "Unsupported vector type");
432 return ReturnType();
433 }
434 };
435
441 template<typename SizeType>
442 struct Cross<SizeType, TVector3<SizeType> /*== A*/, TVector3<SizeType> /*== B*/, TVector3<SizeType> /*== ReturnType*/>
443 {
444 FORCEINLINE static TVector3<SizeType> Calculate(const TVector3<SizeType>& A, const TVector3<SizeType>& B)
445 {
446 return TVector3<SizeType>((A.Y * B.Z - A.Z * B.Y), /* X */
447 (A.Z * B.X - A.X * B.Z), /* Y */
448 (A.X * B.Y - A.Y * B.X)); /* Z */
449 }
450 };
451
457 template<typename SizeType>
458 struct Cross<SizeType, TVector3<SizeType> /*== A*/, glm::vec3 /*== B*/, TVector3<SizeType> /*== ReturnType*/>
459 {
460 FORCEINLINE static TVector3<SizeType> Calculate(const TVector3<SizeType>& A, const glm::vec3& B)
461 {
462 return TVector3<SizeType>(
463 (A.Y * B.z - A.Z * B.y), /* X */
464 (A.Z * B.x - A.X * B.z), /* Y */
465 (A.X * B.y - A.Y * B.x) /* Z */
466 );
467 }
468 };
469
475 template<typename SizeType>
476 struct Cross<SizeType, glm::vec3 /*== A*/, TVector3<SizeType> /*== B*/, TVector3<SizeType> /*== ReturnType*/>
477 {
478 FORCEINLINE static TVector3<SizeType> Calculate(const glm::vec3& A, const TVector3<SizeType>& B)
479 {
480 return TVector3<SizeType>(
481 (A.y * B.Z - A.z * B.Y), /* X */
482 (A.z * B.X - A.x * B.Z), /* Y */
483 (A.x * B.Y - A.y * B.X) /* Z */
484 );
485 }
486 };
487
493 template<typename SizeType>
494 struct Cross<SizeType, glm::vec3 /*== A*/, glm::vec3 /*== B*/, TVector3<SizeType> /*== ReturnType*/>
495 {
496 FORCEINLINE static TVector3<SizeType> Calculate(const glm::vec3& A, const glm::vec3& B)
497 {
498 return TVector3<SizeType>((A.y * B.z - A.z * B.y), /* X */
499 (A.z * B.x - A.x * B.z), /* Y */
500 (A.x * B.y - A.y * B.x)); /* Z */
501 }
502 };
503
504
508 template<typename SizeType, typename VectorTypeA, typename VectorTypeB, typename ReturnType = SizeType>
509 struct Distance
510 {
511 //FORCEINLINE static ReturnType Calculate(const TVector3<SizeType>& A, const TVector3<SizeType>& B)
512 FORCEINLINE static ReturnType Calculate(const VectorTypeA& A, const VectorTypeB& B)
513 {
514 static_assert((sizeof(VectorTypeA) > 0) && (sizeof(VectorTypeB) > 0), "Unsupported vector type");
515 return ReturnType();
516 }
517 };
518
524 template<typename SizeType>
525 struct Distance<SizeType, TVector3<SizeType> /*== A*/, TVector3<SizeType> /*== B*/, SizeType /*== ReturnType*/>
526 {
527 FORCEINLINE static SizeType Calculate(const TVector3<SizeType>& A, const TVector3<SizeType>& B)
528 {
529 const float DX = B.X - A.X;
530 const float DY = B.Y - A.Y;
531 const float DZ = B.Z - A.Z;
532 return std::sqrt((DX * DX) + (DY * DY) + (DZ * DZ));
533 }
534 };
535
541 template<typename SizeType>
542 struct Distance<SizeType, TVector3<SizeType> /*== A*/, glm::vec3 /*== B*/, SizeType /*== ReturnType*/>
543 {
544 FORCEINLINE static SizeType Calculate(const TVector3<SizeType>& A, const glm::vec3& B)
545 {
546 const float DX = B.x - A.X;
547 const float DY = B.y - A.Y;
548 const float DZ = B.z - A.Z;
549 return std::sqrt((DX * DX) + (DY * DY) + (DZ * DZ));
550 }
551 };
552
558 template<typename SizeType>
559 struct Distance<SizeType, glm::vec3 /*== A*/, TVector3<SizeType> /*== B*/, SizeType /*== ReturnType*/>
560 {
561 FORCEINLINE static SizeType Calculate(const glm::vec3& A, const TVector3<SizeType>& B)
562 {
563 const float DX = B.X - A.x;
564 const float DY = B.Y - A.y;
565 const float DZ = B.Z - A.z;
566 return std::sqrt((DX * DX) + (DY * DY) + (DZ * DZ));
567 }
568 };
569
575 template<typename SizeType>
576 struct Distance<SizeType, glm::vec3 /*== A*/, glm::vec3 /*== B*/, SizeType /*== ReturnType*/>
577 {
578 FORCEINLINE static SizeType Calculate(const glm::vec3& A, const glm::vec3& B)
579 {
580 const float DX = B.x - A.x;
581 const float DY = B.y - A.y;
582 const float DZ = B.z - A.z;
583 return std::sqrt((DX * DX) + (DY * DY) + (DZ * DZ));
584 }
585 };
586
587
591 template<typename SizeType, typename VectorTypeA, typename VectorTypeB, typename ReturnType = SizeType>
593 {
594 FORCEINLINE static ReturnType Calculate(const VectorTypeA& A, const VectorTypeB& B)
595 {
596 static_assert((sizeof(VectorTypeA) > 0) && (sizeof(VectorTypeB) > 0), "Unsupported vector type");
597 return ReturnType();
598 }
599 };
600
606 template<typename SizeType>
607 struct DistanceSquared<SizeType, TVector3<SizeType> /*== A*/, TVector3<SizeType> /*== B*/, SizeType /*== ReturnType*/>
608 {
609 FORCEINLINE static SizeType Calculate(const TVector3<SizeType>& A, const TVector3<SizeType>& B)
610 {
611 const float DX = B.X - A.X;
612 const float DY = B.Y - A.Y;
613 const float DZ = B.Z - A.Z;
614 return ((DX * DX) + (DY * DY) + (DZ * DZ));
615 }
616 };
617
623 template<typename SizeType>
624 struct DistanceSquared<SizeType, TVector3<SizeType> /*== A*/, glm::vec3 /*== B*/, SizeType /*== ReturnType*/>
625 {
626 FORCEINLINE static SizeType Calculate(const TVector3<SizeType>& A, const glm::vec3& B)
627 {
628 const float DX = B.x - A.X;
629 const float DY = B.y - A.Y;
630 const float DZ = B.z - A.Z;
631 return ((DX * DX) + (DY * DY) + (DZ * DZ));
632 }
633 };
634
640 template<typename SizeType>
641 struct DistanceSquared<SizeType, glm::vec3 /*== A*/, TVector3<SizeType> /*== B*/, SizeType /*== ReturnType*/>
642 {
643 FORCEINLINE static SizeType Calculate(const glm::vec3& A, const TVector3<SizeType>& B)
644 {
645 const float DX = B.X - A.x;
646 const float DY = B.Y - A.y;
647 const float DZ = B.Z - A.z;
648 return ((DX * DX) + (DY * DY) + (DZ * DZ));
649 }
650 };
651
657 template<typename SizeType>
658 struct DistanceSquared<SizeType, glm::vec3 /*== A*/, glm::vec3 /*== B*/, SizeType /*== ReturnType*/>
659 {
660 FORCEINLINE static SizeType Calculate(const glm::vec3& A, const glm::vec3& B)
661 {
662 const float DX = B.x - A.x;
663 const float DY = B.y - A.y;
664 const float DZ = B.z - A.z;
665 return ((DX * DX) + (DY * DY) + (DZ * DZ));
666 }
667 };
668
669 }
670
674 template<typename SizeType>
675 struct TVector3
676 {
677 public:
678 TVector3()
679 : X(SizeType())
680 , Y(SizeType())
681 , Z(SizeType())
682 {
683 }
684
685 TVector3(const SizeType InX, const SizeType InY, const SizeType InZ)
686 : X(InX)
687 , Y(InY)
688 , Z(InZ)
689 {
690 }
691
692 TVector3(const SizeType InXYZ)
693 : X(InXYZ)
694 , Y(InXYZ)
695 , Z(InXYZ)
696 {
697 }
698
699 #if LK_MATH_VECTOR3_EXPLICIT_GLM_CONSTRUCTOR
700 explicit TVector3(const glm::vec3& InVec)
701 #else
702 TVector3(const glm::vec3& InVec)
703 #endif
704 : X(static_cast<SizeType>(InVec.x))
705 , Y(static_cast<SizeType>(InVec.y))
706 , Z(static_cast<SizeType>(InVec.z))
707 {
708 }
709
710 ~TVector3() = default;
711
712 #if LK_MATH_VECTOR3_EXPLICIT_GLM_CONSTRUCTOR
713 TVector3& operator=(const TVector3& Other)
714 {
715 X = static_cast<SizeType>(Other.X);
716 Y = static_cast<SizeType>(Other.Y);
717 Z = static_cast<SizeType>(Other.Z);
718 return *this;
719 }
720
721 TVector3& operator=(const glm::vec3& Other)
722 {
723 X = static_cast<SizeType>(Other.x);
724 Y = static_cast<SizeType>(Other.y);
725 Z = static_cast<SizeType>(Other.z);
726 return *this;
727 }
728 #endif
729
730 TVector3& operator+=(const TVector3& Other)
731 {
732 X += Other.X;
733 Y += Other.Y;
734 Z += Other.Z;
735 return *this;
736 }
737
738 TVector3& operator+=(const glm::vec3& Other)
739 {
740 X += Other.x;
741 Y += Other.y;
742 Z += Other.z;
743 return *this;
744 }
745
746 TVector3& operator-=(const TVector3& Other)
747 {
748 X -= Other.X;
749 Y -= Other.Y;
750 Z -= Other.Z;
751 return *this;
752 }
753
754 TVector3& operator-=(const glm::vec3& Other)
755 {
756 X -= Other.x;
757 Y -= Other.y;
758 Z -= Other.z;
759 return *this;
760 }
761
762 TVector3 operator+(const TVector3& Other) const
763 {
764 return TVector3((X + Other.X), (Y + Other.Y), (Z + Other.Z));
765 }
766
767 TVector3 operator+(const glm::vec3& Other) const
768 {
769 return TVector3((X + Other.x), (Y + Other.y), (Z + Other.z));
770 }
771
772 TVector3 operator-(const TVector3& Other) const
773 {
774 return TVector3((X - Other.X), (Y - Other.Y), (Z - Other.Z));
775 }
776
777 TVector3 operator-(const glm::vec3& Other) const
778 {
779 return TVector3((X - Other.x), (Y - Other.y), (Z - Other.z));
780 }
781
782 TVector3 operator/(const float Value) const
783 {
784 LK_CORE_ASSERT(Value != 0.0f, "Division by zero");
785 return TVector3((X / Value), (Y / Value), (Z / Value));
786 }
787
788 TVector3 operator/(const TVector3& Other) const
789 {
790 LK_CORE_ASSERT((Other.X != 0.0f) && (Other.Y != 0.0f) && (Other.Z != 0.0f), "Division by zero");
791 return TVector3((X / Other.X), (Y / Other.Y), (Z / Other.Z));
792 }
793
794 TVector3 operator/(const glm::vec3& Other) const
795 {
796 LK_CORE_ASSERT((Other.x != 0.0f) && (Other.y != 0.0f) && (Other.z != 0.0f), "Division by zero");
797 return TVector3((X / Other.x), (Y / Other.y), (Z / Other.z));
798 }
799
800 TVector3 operator*(const float Value) const
801 {
802 /*
803 * TODO: Might do some warning for multiplication by zero since
804 * it is not that usual that outcome is desired.
805 */
806 return TVector3((X * Value), (Y * Value), (Z * Value));
807 }
808
809 TVector3 operator*(const TVector3& Other) const
810 {
811 return TVector3((X * Other.X), (Y * Other.Y), (Z * Other.Z));
812 }
813
814 TVector3 operator*(const glm::vec3& Other) const
815 {
816 return TVector3((X * Other.x), (Y * Other.y), (Z * Other.z));
817 }
818
819 bool operator==(const TVector3& Other) const
820 {
821 #if defined(LK_MATH_VECTOR3_BOOL_OPERATOR_USE_EPSILON)
822 static constexpr SizeType Epsilon = static_cast<SizeType>(1e-5);
823 return ((std::abs(X - Other.X) < Epsilon)
824 && (std::abs(Y - Other.Y)) < Epsilon)
825 && (std::abs(Z - Other.Z) < Epsilon));
826 #else
827 return ((X == Other.X) && (Y == Other.Y) && (Z == Other.Z));
828 #endif
829 }
830
831 bool operator!=(const TVector3& Other) const
832 {
833 return !(*this == Other);
834 }
835
836 bool operator==(const glm::vec3& Other) const
837 {
838 #if defined(LK_MATH_VECTOR3_BOOL_OPERATOR_USE_EPSILON)
839 static constexpr SizeType Epsilon = static_cast<SizeType>(1e-5);
840 return ((std::abs(X - Other.X) < Epsilon)
841 && (std::abs(Y - Other.Y)) < Epsilon)
842 && (std::abs(Z - Other.Z) < Epsilon));
843 #else
844 return ((X == Other.x) && (Y == Other.y) && (Z == Other.z));
845 #endif
846 }
847
848 bool operator!=(const glm::vec3& Other) const
849 {
850 return !(*this == Other);
851 }
852
856 template<typename VectorTypeA, typename VectorTypeB>
857 static SizeType Dot(const VectorTypeA& A, const VectorTypeB& B)
858 {
859 using ReturnType = SizeType;
861 }
862
866 template<typename VectorTypeA, typename VectorTypeB>
867 static SizeType Distance(const VectorTypeA& A, const VectorTypeB& B)
868 {
869 using ReturnType = SizeType;
871 }
872
878 template<typename VectorTypeA, typename VectorTypeB>
879 static SizeType DistanceSquared(const VectorTypeA& A, const VectorTypeB& B)
880 {
881 using ReturnType = SizeType;
883 }
884
885 template<typename VectorTypeA, typename VectorTypeB>
886 static TVector3<SizeType> Cross(const VectorTypeA& A, const VectorTypeB& B)
887 {
888 using ReturnType = TVector3<SizeType>;
890 }
891
892 FORCEINLINE void Normalize()
893 {
894 const SizeType Magnitude = std::sqrt((X * X) + (Y * Y) + (Z * Z));
895 X /= Magnitude;
896 Y /= Magnitude;
897 Z /= Magnitude;
898 }
899
900 FORCEINLINE void NormalizeSafe()
901 {
902 const SizeType Magnitude = std::sqrt((X * X) + (Y * Y) + (Z * Z));
903 if (Magnitude > static_cast<SizeType>(0))
904 {
905 X /= Magnitude;
906 Y /= Magnitude;
907 Z /= Magnitude;
908 }
909 else
910 {
911 LK_CORE_WARN_TAG("Vector3", "Vector could not be normalized with magnitude: {}", Magnitude);
912 }
913 }
914
915 template<typename VectorType>
916 static TVector3<SizeType> Normalize(const VectorType& Vector)
917 {
918 using ReturnType = TVector3<SizeType>;
919 return Math::Internal::Vector3Impl::Normalize<SizeType, VectorType, ReturnType, false>::Calculate(Vector);
920 }
921
922 template<typename VectorType>
923 static TVector3<SizeType> NormalizeSafe(const VectorType& Vector)
924 {
925 using ReturnType = TVector3<SizeType>;
926 return Math::Internal::Vector3Impl::Normalize<SizeType, VectorType, ReturnType, true>::Calculate(Vector);
927 }
928
929 template<typename VectorTypeA, typename VectorTypeB, typename ReturnType = TVector3<SizeType>>
930 static ReturnType Min(const VectorTypeA& A, const VectorTypeB& B)
931 {
932 return Math::Internal::Vector3Impl::Min<SizeType, VectorTypeA, VectorTypeB, ReturnType>::Calculate(A, B);
933 }
934
935 template<typename VectorTypeA, typename VectorTypeB, typename ReturnType = TVector3<SizeType>>
936 static ReturnType Max(const VectorTypeA& A, const VectorTypeB& B)
937 {
938 return Math::Internal::Vector3Impl::Max<SizeType, VectorTypeA, VectorTypeB, ReturnType>::Calculate(A, B);
939 }
940
941 template<typename VectorType>
942 static VectorType Inverse(const VectorType& Vector)
943 {
944 return Math::Internal::Vector3Impl::Inverse<SizeType, VectorType, VectorType, false>::Calculate(Vector);
945 }
946
947 template<typename VectorType>
948 static VectorType InverseSafe(const VectorType& Vector)
949 {
950 return Math::Internal::Vector3Impl::Inverse<SizeType, VectorType, VectorType, true>::Calculate(Vector);
951 }
952
953 FORCEINLINE std::string ToString() const
954 {
955 return LK_FMT_LIB::format("({:.2f}, {:.2f}, {:.2f})", X, Y, Z);
956 }
957
958 FORCEINLINE friend std::ostream& operator<<(std::ostream& os, const TVector3& Vector)
959 {
960 os << *Vector.ToString();
961 return os;
962 }
963
964 #if 0
965 template<typename VectorType>
966 VectorType As() const
967 {
968 return VectorType(X, Y, Z);
969 }
970 #else
971 template<typename VectorType, typename = std::enable_if_t<std::is_same_v<VectorType, glm::vec3>>>
972 VectorType As() const
973 {
974 return glm::vec3(X, Y, Z);
975 }
976 #endif
977
978 static_assert(std::disjunction_v<
979 std::is_same<SizeType, int>,
980 std::is_same<SizeType, uint16_t>,
981 std::is_same<SizeType, uint32_t>,
982 std::is_same<SizeType, uint64_t>,
983 std::is_same<SizeType, int16_t>,
984 std::is_same<SizeType, int32_t>,
985 std::is_same<SizeType, int64_t>,
986 std::is_same<SizeType, float>,
987 std::is_same<SizeType, double>
988 >, "TVector3 can only be instantiated with int, float or double types");
989
990 public:
991 #if LK_MATH_VECTOR_ANONYMOUS_STRUCT
992 union
993 {
994 struct { SizeType X, Y, Z; };
995 struct { SizeType R, G, B; };
996 struct { SizeType S, T, P; };
997 };
998 #else
999 union { SizeType X, R, S; };
1000 union { SizeType Y, G, T; };
1001 union { SizeType Z, B, P; };
1002 #endif
1003 };
1004
1005#if 0
1006 template<typename SizeType>
1007 template<>
1008 inline glm::vec3 TVector3<SizeType>::As<glm::vec3>() const
1009 {
1010 return glm::vec3(X, Y, Z);
1011 }
1012#endif
1013
1016}
Core macros used by the entire engine.
Definition Asset.h:11
Helper for calculating minimum values.
Definition Vector3.h:29
Definition Vector3.h:676
static SizeType DistanceSquared(const VectorTypeA &A, const VectorTypeB &B)
Calculate the squared distance between two vectors.
Definition Vector3.h:879
static SizeType Dot(const VectorTypeA &A, const VectorTypeB &B)
Calculate the dot product of two vectors.
Definition Vector3.h:857
static SizeType Distance(const VectorTypeA &A, const VectorTypeB &B)
Calculate the distance between two vectors.
Definition Vector3.h:867