Sparkle 0.0.1
Loading...
Searching...
No Matches
spk_matrix.hpp
1#pragma once
2
3#include <array>
4#include <stdexcept>
5#include <string>
6
7#include "structure/math/spk_quaternion.hpp"
8#include "structure/math/spk_safe_comparand.hpp"
9#include "structure/math/spk_vector2.hpp"
10#include "structure/math/spk_vector3.hpp"
11#include "structure/math/spk_vector4.hpp"
12
13#include "utils/spk_math_utils.hpp"
14
15#include "spk_constants.hpp"
16
17namespace spk
18{
31 template <size_t SizeX, size_t SizeY>
32 class IMatrix
33 {
34 public:
45 class Column
46 {
47 private:
48 std::array<float, SizeY> _rows;
49
50 public:
56 float &operator[](size_t p_index)
57 {
58 if (p_index >= SizeY)
59 {
60 throw std::invalid_argument(
61 "Can't access the row " + std::to_string(p_index) + " on a matrix " + std::to_string(SizeX) + "x" + std::to_string(SizeY));
62 }
63 return (_rows[p_index]);
64 }
65
70 const float &operator[](size_t p_index) const
71 {
72 if (p_index >= SizeY)
73 {
74 throw std::invalid_argument(
75 "Can't access the row " + std::to_string(p_index) + " on a matrix " + std::to_string(SizeX) + "x" + std::to_string(SizeY));
76 }
77 return (_rows[p_index]);
78 }
79 };
80
81 private:
82 std::array<Column, SizeX> _cols;
83
84 public:
89 {
90 for (size_t i = 0; i < SizeX; i++)
91 {
92 for (size_t j = 0; j < SizeY; j++)
93 {
94 (*this)[i][j] = (i == j ? 1.0f : 0.0f);
95 }
96 }
97 }
98
103 IMatrix(float *p_values)
104 {
105 for (size_t i = 0; i < SizeX; i++)
106 {
107 for (size_t j = 0; j < SizeY; j++)
108 {
109 (*this)[i][j] = p_values[i * SizeY + j];
110 }
111 }
112 }
113
118 IMatrix(std::initializer_list<float> p_values)
119 {
120 if (p_values.size() != SizeX * SizeY)
121 {
122 throw std::invalid_argument("Initializer list size does not match the matrix dimensions.");
123 }
124
125 auto it = p_values.begin();
126 for (size_t j = 0; j < SizeY; j++)
127 {
128 for (size_t i = 0; i < SizeX; i++)
129 {
130 (*this)[i][j] = *it++;
131 }
132 }
133 }
134
143
149 Column &operator[](size_t p_index)
150 {
151 if (p_index >= SizeX)
152 {
153 throw std::invalid_argument(
154 "Can't access the column " + std::to_string(p_index) + " on a matrix " + std::to_string(SizeX) + "x" + std::to_string(SizeY));
155 }
156 return (_cols[p_index]);
157 }
158
164 const Column &operator[](size_t p_index) const
165 {
166 if (p_index >= SizeX)
167 {
168 throw std::invalid_argument(
169 "Can't access the column " + std::to_string(p_index) + " on a matrix " + std::to_string(SizeX) + "x" + std::to_string(SizeY));
170 }
171 return (_cols[p_index]);
172 }
173
179 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 3 && Y == 3), int> = 0>
180 Vector3 operator*(const Vector3 &p_vec) const
181 {
182 Vector3 result;
183 result.x = (*this)[0][0] * p_vec.x + (*this)[1][0] * p_vec.y + (*this)[2][0] * 1;
184 result.y = (*this)[0][1] * p_vec.x + (*this)[1][1] * p_vec.y + (*this)[2][1] * 1;
185 result.z = (*this)[0][2] * p_vec.x + (*this)[1][2] * p_vec.y + (*this)[2][2] * 1;
186 return result;
187 }
188
194 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 4 && Y == 4), int> = 0>
195 Vector3 operator*(const Vector3 &p_vec) const
196 {
197 Vector4 temp(p_vec.x, p_vec.y, p_vec.z, 1.0f);
198 Vector4 transformed = (*this) * temp;
199 return Vector3(transformed.x / transformed.w, transformed.y / transformed.w, transformed.z / transformed.w);
200 }
201
209 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 3 && Y == 3), int> = 0>
210 Vector2 operator*(const Vector2 &p_vec) const
211 {
212 Vector2 result;
213 result.x = (*this)[0][0] * p_vec.x + (*this)[1][0] * p_vec.y + (*this)[2][0] * 1;
214 result.y = (*this)[0][1] * p_vec.x + (*this)[1][1] * p_vec.y + (*this)[2][1] * 1;
215
216 return result;
217 }
218
224 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 4 && Y == 4), int> = 0>
225 Vector4 operator*(const Vector4 &p_vec) const
226 {
227 Vector4 result;
228 result.x = (*this)[0][0] * p_vec.x + (*this)[1][0] * p_vec.y + (*this)[2][0] * p_vec.z + (*this)[3][0] * p_vec.w;
229 result.y = (*this)[0][1] * p_vec.x + (*this)[1][1] * p_vec.y + (*this)[2][1] * p_vec.z + (*this)[3][1] * p_vec.w;
230 result.z = (*this)[0][2] * p_vec.x + (*this)[1][2] * p_vec.y + (*this)[2][2] * p_vec.z + (*this)[3][2] * p_vec.w;
231 result.w = (*this)[0][3] * p_vec.x + (*this)[1][3] * p_vec.y + (*this)[2][3] * p_vec.z + (*this)[3][3] * p_vec.w;
232 return result;
233 }
234
241 {
243
244 for (size_t i = 0; i < SizeX; ++i)
245 {
246 for (size_t j = 0; j < SizeY; ++j)
247 {
248 result[i][j] = 0;
249 for (size_t k = 0; k < SizeX; ++k)
250 {
251 result[i][j] += (*this)[i][k] * p_other[k][j];
252 }
253 }
254 }
255
256 return result;
257 }
258
264 bool operator==(const IMatrix &p_other) const
265 {
266 for (size_t i = 0; i < SizeX; ++i)
267 {
268 for (size_t j = 0; j < SizeY; ++j)
269 {
270 if (spk::SafeComparand((*this)[i][j]) != p_other[i][j])
271 {
272 return false;
273 }
274 }
275 }
276 return true;
277 }
278
285 bool operator!=(const IMatrix &p_other) const
286 {
287 return !(*this == p_other);
288 }
289
298 static IMatrix<4, 4> rotation(float p_angleX, float p_angleY, float p_angleZ)
299 {
300 IMatrix<4, 4> mat;
301
302 float cosX = std::cos(spk::MathUtils::degreeToRadian(p_angleX));
303 float sinX = std::sin(spk::MathUtils::degreeToRadian(p_angleX));
304
305 float cosY = std::cos(spk::MathUtils::degreeToRadian(p_angleY));
306 float sinY = std::sin(spk::MathUtils::degreeToRadian(p_angleY));
307
308 float cosZ = std::cos(spk::MathUtils::degreeToRadian(p_angleZ));
309 float sinZ = std::sin(spk::MathUtils::degreeToRadian(p_angleZ));
310
311 IMatrix<4, 4> rotationX = {1, 0, 0, 0, 0, cosX, -sinX, 0, 0, sinX, cosX, 0, 0, 0, 0, 1};
312
313 IMatrix<4, 4> rotationY = {cosY, 0, sinY, 0, 0, 1, 0, 0, -sinY, 0, cosY, 0, 0, 0, 0, 1};
314
315 IMatrix<4, 4> rotationZ = {cosZ, -sinZ, 0, 0, sinZ, cosZ, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
316
317 IMatrix<4, 4> rotation = rotationZ * rotationY * rotationX;
318
319 return rotation;
320 }
321
328 static IMatrix<4, 4> rotation(spk::Vector3 p_angle)
329 {
330 return (rotation(p_angle.x, p_angle.y, p_angle.z));
331 }
332
333 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 4 && Y == 4), int> = 0>
343 {
344 float xx = p_q.x * p_q.x;
345 float yy = p_q.y * p_q.y;
346 float zz = p_q.z * p_q.z;
347 float xy = p_q.x * p_q.y;
348 float xz = p_q.x * p_q.z;
349 float yz = p_q.y * p_q.z;
350 float wx = p_q.w * p_q.x;
351 float wy = p_q.w * p_q.y;
352 float wz = p_q.w * p_q.z;
353
354 IMatrix<4, 4> rotationMatrix;
355 rotationMatrix[0][0] = 1.0f - 2.0f * (yy + zz);
356 rotationMatrix[0][1] = 2.0f * (xy + wz);
357 rotationMatrix[0][2] = 2.0f * (xz - wy);
358 rotationMatrix[0][3] = 0.0f;
359
360 rotationMatrix[1][0] = 2.0f * (xy - wz);
361 rotationMatrix[1][1] = 1.0f - 2.0f * (xx + zz);
362 rotationMatrix[1][2] = 2.0f * (yz + wx);
363 rotationMatrix[1][3] = 0.0f;
364
365 rotationMatrix[2][0] = 2.0f * (xz + wy);
366 rotationMatrix[2][1] = 2.0f * (yz - wx);
367 rotationMatrix[2][2] = 1.0f - 2.0f * (xx + yy);
368 rotationMatrix[2][3] = 0.0f;
369
370 rotationMatrix[3][0] = 0.0f;
371 rotationMatrix[3][1] = 0.0f;
372 rotationMatrix[3][2] = 0.0f;
373 rotationMatrix[3][3] = 1.0f;
374
375 return rotationMatrix;
376 }
377
386 static IMatrix<4, 4> translation(float p_translateX, float p_translateY, float p_translateZ)
387 {
388 return IMatrix<4, 4>{1, 0, 0, p_translateX, 0, 1, 0, p_translateY, 0, 0, 1, p_translateZ, 0, 0, 0, 1};
389 }
390
397 static IMatrix<4, 4> translation(spk::Vector3 p_translation)
398 {
399 return (translation(p_translation.x, p_translation.y, p_translation.z));
400 }
401
402 // Scale Matrix
411 static IMatrix<4, 4> scale(float p_scaleX, float p_scaleY, float p_scaleZ)
412 {
413 return IMatrix<4, 4>{p_scaleX, 0, 0, 0, 0, p_scaleY, 0, 0, 0, 0, p_scaleZ, 0, 0, 0, 0, 1};
414 }
415
422 static IMatrix<4, 4> scale(spk::Vector3 p_scale)
423 {
424 return (scale(p_scale.x, p_scale.y, p_scale.z));
425 }
426
433 friend std::wostream &operator<<(std::wostream &p_os, const IMatrix &p_mat)
434 {
435 for (size_t j = 0; j < SizeY; ++j)
436 {
437 if (j != 0)
438 {
439 p_os << " - ";
440 }
441
442 p_os << L"[";
443 for (size_t i = 0; i < SizeX; ++i)
444 {
445 if (i != 0)
446 {
447 p_os << L" - ";
448 }
449 p_os << p_mat[i][j];
450 }
451 p_os << L"]";
452 }
453 return p_os;
454 }
455
462 friend std::ostream &operator<<(std::ostream &p_os, const IMatrix &p_mat)
463 {
464 for (size_t j = 0; j < SizeY; ++j)
465 {
466 if (j != 0)
467 {
468 p_os << " - ";
469 }
470
471 p_os << "[";
472 for (size_t i = 0; i < SizeX; ++i)
473 {
474 if (i != 0)
475 {
476 p_os << " - ";
477 }
478 p_os << p_mat[i][j];
479 }
480 p_os << "]";
481 }
482 return p_os;
483 }
484
489 std::wstring toWstring() const
490 {
491 std::wstringstream wss;
492 wss << *this;
493 return wss.str();
494 }
495
500 std::string toString() const
501 {
502 std::stringstream ss;
503 ss << *this;
504 return ss.str();
505 }
506
507 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 4 && Y == 4), int> = 0>
517 static IMatrix lookAt(const spk::Vector3 &p_from, const spk::Vector3 &p_to, const spk::Vector3 &p_up)
518 {
519 const spk::Vector3 forward = ((p_to - p_from).normalize());
520 const spk::Vector3 right = (forward != p_up && forward != p_up.inverse() ? forward.cross(p_up).normalize() : spk::Vector3(1, 0, 0));
521 const spk::Vector3 up = right.cross(forward);
522
523 IMatrix result;
524
525 result[0][0] = right.x;
526 result[0][1] = right.y;
527 result[0][2] = right.z;
528 result[1][0] = up.x;
529 result[1][1] = up.y;
530 result[1][2] = up.z;
531 result[2][0] = -forward.x;
532 result[2][1] = -forward.y;
533 result[2][2] = -forward.z;
534 result[3][0] = -right.dot(p_from);
535 result[3][1] = -up.dot(p_from);
536 result[3][2] = forward.dot(p_from);
537
538 return result;
539 }
540
541 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 4 && Y == 4), int> = 0>
550 static IMatrix rotateAroundAxis(const spk::Vector3 &p_axis, const float &p_rotationAngle)
551 {
552 IMatrix result;
553
554 const float rad = spk::MathUtils::degreeToRadian(p_rotationAngle);
555
556 Vector3 v = p_axis.normalize();
557
558 float c = cos(rad);
559 float s = sin(rad);
560
561 result[0][0] = c + v.x * v.x * (1 - c);
562 result[0][1] = v.x * v.y * (1 - c) - v.z * s;
563 result[0][2] = v.x * v.z * (1 - c) + v.y * s;
564
565 result[1][0] = v.y * v.x * (1 - c) + v.z * s;
566 result[1][1] = c + v.y * v.y * (1 - c);
567 result[1][2] = v.y * v.z * (1 - c) - v.x * s;
568
569 result[2][0] = v.z * v.x * (1 - c) - v.y * s;
570 result[2][1] = v.z * v.y * (1 - c) + v.x * s;
571 result[2][2] = c + v.z * v.z * (1 - c);
572
573 result[3][0] = 0.0f;
574 result[3][1] = 0.0f;
575 result[3][2] = 0.0f;
576 result[3][3] = 1.0f;
577
578 return result;
579 }
580
581 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 4 && Y == 4), int> = 0>
592 static IMatrix perspective(float p_fov, float p_aspectRatio, float p_nearPlane, float p_farPlane)
593 {
594 IMatrix result;
595
596 const float rad = spk::MathUtils::degreeToRadian(p_fov);
597 const float tanHalfFov = tan(rad / 2.0f);
598
599 result[0][0] = 1.0f / (tanHalfFov * p_aspectRatio);
600 result[1][1] = 1.0f / tanHalfFov;
601 result[2][2] = -(p_farPlane + p_nearPlane) / (p_farPlane - p_nearPlane);
602 result[2][3] = -1.0f;
603 result[3][2] = -(2.0f * p_farPlane * p_nearPlane) / (p_farPlane - p_nearPlane);
604 result[3][3] = 0.0f;
605
606 return result;
607 }
608
609 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 4 && Y == 4), int> = 0>
622 static IMatrix ortho(float p_left, float p_right, float p_bottom, float p_top, float p_nearPlane, float p_farPlane)
623 {
624 IMatrix result;
625
626 result[0][0] = 2.0f / (p_right - p_left);
627 result[1][1] = 2.0f / (p_top - p_bottom);
628 result[2][2] = -2.0f / (p_farPlane - p_nearPlane);
629 result[3][0] = -(p_right + p_left) / (p_right - p_left);
630 result[3][1] = -(p_top + p_bottom) / (p_top - p_bottom);
631 result[3][2] = -(p_farPlane + p_nearPlane) / (p_farPlane - p_nearPlane);
632
633 return result;
634 }
635
636 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == Y), int> = 0>
641 float determinant() const
642 {
643 const size_t N = SizeX;
644 IMatrix<SizeX, SizeY> A(*this);
645 float det = 1.0f;
646 int sign = 1;
647
648 for (size_t i = 0; i < N; ++i)
649 {
650 size_t pivotRow = i;
651 float maxElem = std::fabs(A[i][i]);
652 for (size_t r = i + 1; r < N; ++r)
653 {
654 float v = std::fabs(A[i][r]);
655 if (v > maxElem)
656 {
657 maxElem = v;
658 pivotRow = r;
659 }
660 }
661
662 if (spk::SafeComparand(maxElem) == 0.0f)
663 {
664 return 0.0f;
665 }
666
667 if (pivotRow != i)
668 {
669 for (size_t c = 0; c < N; ++c)
670 {
671 std::swap(A[c][i], A[c][pivotRow]);
672 }
673 sign = -sign;
674 }
675
676 for (size_t r = i + 1; r < N; ++r)
677 {
678 float factor = A[i][r] / A[i][i];
679 for (size_t c = i; c < N; ++c)
680 {
681 A[c][r] -= factor * A[c][i];
682 }
683 }
684
685 det *= A[i][i];
686 }
687
688 return det * static_cast<float>(sign);
689 }
690
691 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == Y), int> = 0>
696 bool isInvertible() const
697 {
698 return spk::SafeComparand(this->determinant()) != 0.0f;
699 }
700
701 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == Y), int> = 0>
708 {
709 if (SizeX != SizeY)
710 {
711 throw std::runtime_error("Matrix inversion requires a square matrix.");
712 }
713
714 const size_t N = SizeX;
715 IMatrix<SizeX, SizeY> A(*this);
717
718 for (size_t i = 0; i < N; i++)
719 {
720 float maxElem = std::fabs(A[i][i]);
721 size_t pivotRow = i;
722 for (size_t k = i + 1; k < N; k++)
723 {
724 float val = std::fabs(A[i][k]);
725 if (val > maxElem)
726 {
727 maxElem = val;
728 pivotRow = k;
729 }
730 }
731
732 if (pivotRow != i)
733 {
734 for (size_t col = 0; col < N; col++)
735 {
736 std::swap(A[col][i], A[col][pivotRow]);
737 std::swap(B[col][i], B[col][pivotRow]);
738 }
739 }
740
741 float pivotVal = A[i][i];
742 if (spk::SafeComparand(pivotVal) == 0.0f)
743 {
744 throw std::runtime_error("Matrix is not invertible (singular pivot encountered).");
745 }
746
747 for (size_t col = 0; col < N; col++)
748 {
749 A[col][i] /= pivotVal;
750 B[col][i] /= pivotVal;
751 }
752
753 for (size_t row = 0; row < N; row++)
754 {
755 if (row != i)
756 {
757 float factor = A[i][row];
758 for (size_t col = 0; col < N; col++)
759 {
760 A[col][row] -= factor * A[col][i];
761 B[col][row] -= factor * B[col][i];
762 }
763 }
764 }
765 }
766
767 return B;
768 }
769
776 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 3 && Y == 3), int> = 0>
777 static IMatrix<3, 3> translation(float p_translateX, float p_translateY)
778 {
780 m[0][0] = 1.0f;
781 m[0][1] = 0.0f;
782 m[0][2] = 0.0f;
783 m[1][0] = 0.0f;
784 m[1][1] = 1.0f;
785 m[1][2] = 0.0f;
786 m[2][0] = p_translateX;
787 m[2][1] = p_translateY;
788 m[2][2] = 1.0f;
789 return m;
790 }
791
797 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 3 && Y == 3), int> = 0>
798 static IMatrix<3, 3> translation(const spk::Vector2 &p_translation)
799 {
800 return translation(p_translation.x, p_translation.y);
801 }
802
809 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 3 && Y == 3), int> = 0>
810 static IMatrix<3, 3> scale(float p_scaleX, float p_scaleY)
811 {
813 m[0][0] = p_scaleX;
814 m[0][1] = 0.0f;
815 m[0][2] = 0.0f;
816 m[1][0] = 0.0f;
817 m[1][1] = p_scaleY;
818 m[1][2] = 0.0f;
819 m[2][0] = 0.0f;
820 m[2][1] = 0.0f;
821 m[2][2] = 1.0f;
822 return m;
823 }
824
830 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 3 && Y == 3), int> = 0>
831 static IMatrix<3, 3> scale(const spk::Vector2 &p_scale)
832 {
833 return scale(p_scale.x, p_scale.y);
834 }
835
841 template <size_t X = SizeX, size_t Y = SizeY, typename std::enable_if_t<(X == 3 && Y == 3), int> = 0>
842 static IMatrix<3, 3> rotationZ(float p_angleDegrees)
843 {
844 const float rad = spk::MathUtils::degreeToRadian(p_angleDegrees);
845 const float c = std::cos(rad);
846 const float s = std::sin(rad);
847
849 m[0][0] = c;
850 m[0][1] = s;
851 m[0][2] = 0.0f;
852 m[1][0] = -s;
853 m[1][1] = c;
854 m[1][2] = 0.0f;
855 m[2][0] = 0.0f;
856 m[2][1] = 0.0f;
857 m[2][2] = 1.0f;
858 return m;
859 }
860 };
861
862 using Matrix2x2 = IMatrix<2, 2>;
863 using Matrix3x3 = IMatrix<3, 3>;
864 using Matrix4x4 = IMatrix<4, 4>;
865}
View of the values belonging to a single matrix column.
Definition spk_matrix.hpp:46
float & operator[](size_t p_index)
Mutable row access within the column.
Definition spk_matrix.hpp:56
const float & operator[](size_t p_index) const
Read-only row access within the column.
Definition spk_matrix.hpp:70
Column-major matrix with basic arithmetic, transforms, and helpers.
Definition spk_matrix.hpp:33
static IMatrix lookAt(const spk::Vector3 &p_from, const spk::Vector3 &p_to, const spk::Vector3 &p_up)
Builds a view matrix looking from one point to another.
Definition spk_matrix.hpp:517
static IMatrix< 3, 3 > rotationZ(float p_angleDegrees)
Definition spk_matrix.hpp:842
const Column & operator[](size_t p_index) const
Accesses a column.
Definition spk_matrix.hpp:164
static IMatrix< 4, 4 > translation(spk::Vector3 p_translation)
Builds a translation matrix from a vector.
Definition spk_matrix.hpp:397
static IMatrix< 4, 4 > rotation(const spk::Quaternion &p_q)
Converts a quaternion to a 4x4 rotation matrix.
Definition spk_matrix.hpp:342
static IMatrix< 4, 4 > scale(float p_scaleX, float p_scaleY, float p_scaleZ)
Builds a scale matrix.
Definition spk_matrix.hpp:411
Vector3 operator*(const Vector3 &p_vec) const
Transforms a 3D vector with a 3x3 matrix (homogeneous w=1).
Definition spk_matrix.hpp:180
Vector2 operator*(const Vector2 &p_vec) const
Transforms a 2D vector with a 3x3 matrix (homogeneous).
Definition spk_matrix.hpp:210
bool operator==(const IMatrix &p_other) const
Compares two matrices with tolerant float comparison.
Definition spk_matrix.hpp:264
Column & operator[](size_t p_index)
Accesses a column.
Definition spk_matrix.hpp:149
IMatrix(std::initializer_list< float > p_values)
Builds from a flat initializer list (column-major).
Definition spk_matrix.hpp:118
std::string toString() const
Converts the matrix to a string representation.
Definition spk_matrix.hpp:500
static IMatrix rotateAroundAxis(const spk::Vector3 &p_axis, const float &p_rotationAngle)
Builds a rotation matrix around an arbitrary axis.
Definition spk_matrix.hpp:550
IMatrix()
Builds an identity matrix.
Definition spk_matrix.hpp:88
IMatrix< SizeX, SizeY > inverse() const
Returns the inverse of a square matrix.
Definition spk_matrix.hpp:707
static IMatrix< 4, 4 > scale(spk::Vector3 p_scale)
Builds a scale matrix from a vector.
Definition spk_matrix.hpp:422
static IMatrix< 3, 3 > translation(const spk::Vector2 &p_translation)
Creates a 2D translation matrix from a vector.
Definition spk_matrix.hpp:798
static spk::IMatrix< SizeX, SizeY > identity()
Returns an identity matrix of the same dimension.
Definition spk_matrix.hpp:139
float determinant() const
Computes determinant for square matrices.
Definition spk_matrix.hpp:641
friend std::wostream & operator<<(std::wostream &p_os, const IMatrix &p_mat)
Streams the matrix to a wide output stream.
Definition spk_matrix.hpp:433
bool isInvertible() const
Checks if the matrix is invertible (determinant non-zero).
Definition spk_matrix.hpp:696
static IMatrix< 3, 3 > scale(float p_scaleX, float p_scaleY)
Creates a 2D scale matrix.
Definition spk_matrix.hpp:810
static IMatrix< 4, 4 > rotation(float p_angleX, float p_angleY, float p_angleZ)
Builds a 4x4 rotation matrix from Euler angles in degrees.
Definition spk_matrix.hpp:298
static IMatrix ortho(float p_left, float p_right, float p_bottom, float p_top, float p_nearPlane, float p_farPlane)
Builds an orthographic projection matrix.
Definition spk_matrix.hpp:622
static IMatrix< 3, 3 > translation(float p_translateX, float p_translateY)
Creates a 2D translation matrix.
Definition spk_matrix.hpp:777
static IMatrix< 4, 4 > translation(float p_translateX, float p_translateY, float p_translateZ)
Builds a translation matrix.
Definition spk_matrix.hpp:386
std::wstring toWstring() const
Converts the matrix to a wide string representation.
Definition spk_matrix.hpp:489
IMatrix< SizeX, SizeY > operator*(const IMatrix< SizeX, SizeY > &p_other) const
Multiplies two matrices of the same dimensions.
Definition spk_matrix.hpp:240
static IMatrix perspective(float p_fov, float p_aspectRatio, float p_nearPlane, float p_farPlane)
Builds a perspective projection matrix.
Definition spk_matrix.hpp:592
Vector4 operator*(const Vector4 &p_vec) const
Transforms a 4D vector with a 4x4 matrix.
Definition spk_matrix.hpp:225
bool operator!=(const IMatrix &p_other) const
Inequality helper.
Definition spk_matrix.hpp:285
IMatrix(float *p_values)
Builds a matrix from a contiguous column-major array.
Definition spk_matrix.hpp:103
static IMatrix< 4, 4 > rotation(spk::Vector3 p_angle)
Builds a 4x4 rotation matrix from Euler components in degrees.
Definition spk_matrix.hpp:328
static IMatrix< 3, 3 > scale(const spk::Vector2 &p_scale)
Creates a 2D scale matrix from a vector.
Definition spk_matrix.hpp:831
friend std::ostream & operator<<(std::ostream &p_os, const IMatrix &p_mat)
Streams the matrix to a narrow output stream.
Definition spk_matrix.hpp:462
Represents a rotation using (x, y, z, w) and offers common conversions.
Definition spk_quaternion.hpp:19
float x
X component of the quaternion vector part.
Definition spk_quaternion.hpp:22
float w
W component representing the scalar part.
Definition spk_quaternion.hpp:28
float z
Z component of the quaternion vector part.
Definition spk_quaternion.hpp:26
float y
Y component of the quaternion vector part.
Definition spk_quaternion.hpp:24
TType x
X component.
Definition spk_vector2.hpp:44
TType y
Y component.
Definition spk_vector2.hpp:48
TType x
X component.
Definition spk_vector3.hpp:43
IVector3< float > normalize() const
Return the vector once normalized by its length.
Definition spk_vector3.hpp:521
float dot(const IVector3 &p_other) const
Computes dot product with another vector.
Definition spk_vector3.hpp:560
TType z
Z component.
Definition spk_vector3.hpp:51
TType y
Y component.
Definition spk_vector3.hpp:47
IVector3 inverse() const
Return the inverse vector.
Definition spk_vector3.hpp:344
IVector3 cross(const IVector3 &p_other) const
Computes 3D cross product.
Definition spk_vector3.hpp:576
TType z
Z component.
Definition spk_vector4.hpp:51
TType w
W component.
Definition spk_vector4.hpp:55
TType y
Y component.
Definition spk_vector4.hpp:47
TType x
X component.
Definition spk_vector4.hpp:43
Wraps arithmetic values to compare with tolerance for floating-point inputs.
Definition spk_safe_comparand.hpp:17