3#include <Foundation/Math/Mat4.h>
4#include <Foundation/Math/Vec3.h>
6template <
typename Type>
9#if PL_ENABLED(PL_MATH_CHECK_FOR_NAN)
19template <
typename Type>
28template <
typename Type>
34template <
typename Type>
40template <
typename Type>
49template <
typename Type>
52 const plAngle halfAngle = angle * 0.5f;
60template <
typename Type>
65 Type n = x * x + y * y + z * z + w * w;
75template <
typename Type>
86 out_vAxis.
Set(1, 0, 0);
90 const float ds = 1.0f / s;
97template <
typename Type>
102 *
this = GetInverse();
105template <
typename Type>
113template <
typename Type>
121template <
typename Type>
130template <
typename Type>
136template <
typename Type>
143template <
typename Type>
148 q.w = q1.w * q2.w - (q1.x * q2.x + q1.y * q2.y + q1.z * q2.z);
161template <
typename Type>
164 if (!GetVectorPart().IsValid())
166 if (!plMath::IsFinite(w))
169 Type n = x * x + y * y + z * z + w * w;
174template <
typename Type>
177 return plMath::IsNaN(x) || plMath::IsNaN(y) || plMath::IsNaN(z) || plMath::IsNaN(w);
180template <
typename Type>
191 GetRotationAxisAndAngle(vA1, A1);
203template <
typename Type>
210 const Type fTx = x + x;
211 const Type fTy = y + y;
212 const Type fTz = z + z;
213 const Type fTwx = fTx * w;
214 const Type fTwy = fTy * w;
215 const Type fTwz = fTz * w;
216 const Type fTxx = fTx * x;
217 const Type fTxy = fTy * x;
218 const Type fTxz = fTz * x;
219 const Type fTyy = fTy * y;
220 const Type fTyz = fTz * y;
221 const Type fTzz = fTz * z;
223 m.Element(0, 0) = (Type)1 - (fTyy + fTzz);
224 m.Element(1, 0) = fTxy - fTwz;
225 m.Element(2, 0) = fTxz + fTwy;
226 m.Element(0, 1) = fTxy + fTwz;
227 m.Element(1, 1) = (Type)1 - (fTxx + fTzz);
228 m.Element(2, 1) = fTyz - fTwx;
229 m.Element(0, 2) = fTxz - fTwy;
230 m.Element(1, 2) = fTyz + fTwx;
231 m.Element(2, 2) = (Type)1 - (fTxx + fTyy);
235template <
typename Type>
242 const Type fTx = x + x;
243 const Type fTy = y + y;
244 const Type fTz = z + z;
245 const Type fTwx = fTx * w;
246 const Type fTwy = fTy * w;
247 const Type fTwz = fTz * w;
248 const Type fTxx = fTx * x;
249 const Type fTxy = fTy * x;
250 const Type fTxz = fTz * x;
251 const Type fTyy = fTy * y;
252 const Type fTyz = fTz * y;
253 const Type fTzz = fTz * z;
255 m.Element(0, 0) = (Type)1 - (fTyy + fTzz);
256 m.Element(1, 0) = fTxy - fTwz;
257 m.Element(2, 0) = fTxz + fTwy;
258 m.Element(3, 0) = (Type)0;
259 m.Element(0, 1) = fTxy + fTwz;
260 m.Element(1, 1) = (Type)1 - (fTxx + fTzz);
261 m.Element(2, 1) = fTyz - fTwx;
262 m.Element(3, 1) = (Type)0;
263 m.Element(0, 2) = fTxz - fTwy;
264 m.Element(1, 2) = fTyz + fTwx;
265 m.Element(2, 2) = (Type)1 - (fTxx + fTyy);
266 m.Element(3, 2) = (Type)0;
267 m.Element(0, 3) = (Type)0;
268 m.Element(1, 3) = (Type)0;
269 m.Element(2, 3) = (Type)0;
270 m.Element(3, 3) = (Type)1;
274template <
typename Type>
279 const Type trace = m.Element(0, 0) + m.Element(1, 1) + m.Element(2, 2);
280 const Type half = (Type)0.5;
289 val[0] = (m.Element(1, 2) - m.Element(2, 1)) * t;
290 val[1] = (m.Element(2, 0) - m.Element(0, 2)) * t;
291 val[2] = (m.Element(0, 1) - m.Element(1, 0)) * t;
297 const plInt32 next[] = {1, 2, 0};
300 if (m.Element(1, 1) > m.Element(0, 0))
303 if (m.Element(2, 2) > m.Element(i, i))
309 Type s =
plMath::Sqrt(m.Element(i, i) - (m.Element(j, j) + m.Element(k, k)) + (Type)1);
313 val[3] = (m.Element(j, k) - m.Element(k, j)) * t;
314 val[j] = (m.Element(i, j) + m.Element(j, i)) * t;
315 val[k] = (m.Element(i, k) + m.Element(k, i)) * t;
326template <
typename Type>
329 const plVec3 x = (mMat *
plVec3(1, 0, 0)).GetNormalized();
330 const plVec3 y = (mMat *
plVec3(0, 1, 0)).GetNormalized();
341template <
typename Type>
362template <
typename Type>
368 const Type fDot = v0.
Dot(v1);
373 return MakeIdentity();
385 const Type d = v0.
Dot(v1);
388 PL_ASSERT_DEBUG(c.
IsValid(),
"SetShortestRotation failed.");
390 const Type fOneDivS = 1.0f / s;
393 q.x = c.x * fOneDivS;
394 q.y = c.y * fOneDivS;
395 q.z = c.z * fOneDivS;
402template <
typename Type>
405 PL_ASSERT_DEBUG((t >= (Type)0) && (t <= (Type)1),
"Invalid lerp factor.");
408 const Type qdelta = (Type)1 - (Type)0.001;
410 const Type fDot = (qFrom.x * qTo.x + qFrom.y * qTo.y + qFrom.z * qTo.z + qFrom.w * qTo.w);
412 Type cosTheta = fDot;
414 bool bFlipSign =
false;
415 if (cosTheta < (Type)0)
418 cosTheta = -cosTheta;
423 if (cosTheta < qdelta)
428 const Type iSinTheta = (Type)1 /
plMath::Sqrt(one - (cosTheta * cosTheta));
429 const plAngle tTheta =
static_cast<float>(t) * theta;
464template <
typename Type>
467 return q1.x == q2.x && q1.y == q2.y && q1.z == q2.z && q1.w == q2.w;
470template <
typename Type>
476template <
typename Type>
487 const double fSingularityTest = w * y - z * x;
488 const double fSingularityThreshold = 0.4999995;
490 if (fSingularityTest > fSingularityThreshold)
496 else if (fSingularityTest < -fSingularityThreshold)
505 const double siny = 2.0 * (w * z + x * y);
506 const double cosy = 1.0 - 2.0 * (y * y + z * z);
513 const double sinr = 2.0 * (w * x + y * z);
514 const double cosr = 1.0 - 2.0 * (x * x + y * y);
519template <
typename Type>
525 const auto& pitch = y;
526 const auto& roll = x;
535 q.w = (float)(cy * cp * cr + sy * sp * sr);
536 q.x = (float)(cy * cp * sr - sy * sp * cr);
537 q.y = (float)(cy * sp * cr + sy * cp * sr);
538 q.z = (float)(sy * cp * cr - cy * sp * sr);
Float wrapper struct for a safe usage and conversions of angles.
Definition Angle.h:10
bool IsEqualSimple(plAngle rhs, plAngle epsilon) const
Equality check with epsilon. Simple check without normalization. 360 degree will equal 0 degree,...
Definition Angle_inl.h:60
static constexpr plAngle MakeFromDegree(float fDegree)
Creates an instance of plAngle that was initialized from degree. (Performs a conversion)
Definition Angle_inl.h:33
static constexpr plAngle MakeFromRadian(float fRadian)
Creates an instance of plAngle that was initialized from radian. (No need for any conversion)
Definition Angle_inl.h:38
A 3x3 component matrix class.
Definition Mat3.h:9
void SetColumn(plUInt32 uiColumn, const plVec3Template< Type > &vColumn)
Sets all 3 components of the i-th column.
Definition Mat3_inl.h:218
A 4x4 component matrix class.
Definition Mat4.h:11
const plVec3Template< Type > TransformDirection(const plVec3Template< Type > &v) const
Matrix-vector multiplication, assuming the 4th component of the vector is zero. So,...
Definition Mat4_inl.h:374
Quaternions can be used to represent rotations in 3D space.
Definition Quat.h:19
void ReconstructFromMat4(const plMat4Template< Type > &m)
Reconstructs a rotation quaternion from a matrix that may contain scaling and mirroring.
Definition Quat_inl.h:342
void SetIdentity()
Sets the Quaternion to the identity.
Definition Quat_inl.h:41
plVec3Template< Type > GetVectorPart() const
Returns the x,y,z components as a vector.
Definition Quat.h:102
static plQuatTemplate< Type > MakeSlerp(const plQuatTemplate &qFrom, const plQuatTemplate &qTo, Type t)
Returns a quaternion that is the spherical linear interpolation of the other two.
Definition Quat_inl.h:403
static plQuatTemplate< Type > MakeFromMat3(const plMat3Template< Type > &m)
Creates a quaternion from the given matrix.
Definition Quat_inl.h:275
const plQuatTemplate< Type > GetInverse() const
Returns a quaternion that represents the negative / inverted rotation. E.g. the one that would rotate...
Definition Quat_inl.h:106
const plQuatTemplate< Type > GetNegated() const
Returns the Quaternion with all 4 components negated. This is not the same as the inverted rotation!
Definition Quat_inl.h:114
void Normalize()
Normalizes the quaternion to unit length. ALL rotation-quaternions should be normalized at all times ...
Definition Quat_inl.h:61
bool IsEqualRotation(const plQuatTemplate &qOther, Type fEpsilon) const
Determines whether this and qOther represent the same rotation. This is a rather slow operation.
Definition Quat_inl.h:181
static plQuatTemplate< Type > MakeFromElements(Type x, Type y, Type z, Type w)
Sets the individual elements of the quaternion directly. Note that x,y,z do NOT represent a rotation ...
Definition Quat_inl.h:35
void GetRotationAxisAndAngle(plVec3Template< Type > &out_vAxis, plAngle &out_angle, Type fEpsilon=plMath::DefaultEpsilon< Type >()) const
Returns the rotation-axis and angle, that this quaternion rotates around.
Definition Quat_inl.h:76
static plQuatTemplate< Type > MakeFromEulerAngles(const plAngle &x, const plAngle &y, const plAngle &z)
Sets the quaternion from Euler angles.
Definition Quat_inl.h:520
plVec3Template< Type > Rotate(const plVec3Template< Type > &v) const
Returns v rotated by the quaternion. Same as operator*.
Definition Quat_inl.h:131
bool IsNaN() const
Checks whether any component is NaN.
Definition Quat_inl.h:175
const plMat4Template< Type > GetAsMat4() const
Returns the Quaternion as a matrix.
Definition Quat_inl.h:236
static const plQuatTemplate< Type > MakeIdentity()
Static function that returns a quaternion that represents the identity rotation (none).
Definition Quat_inl.h:29
void ReconstructFromMat3(const plMat3Template< Type > &m)
Reconstructs a rotation quaternion from a matrix that may contain scaling and mirroring.
Definition Quat_inl.h:327
static plQuatTemplate< Type > MakeShortestRotation(const plVec3Template< Type > &vDirFrom, const plVec3Template< Type > &vDirTo)
Creates a quaternion, that rotates through the shortest arc from "vDirFrom" to "vDirTo".
Definition Quat_inl.h:363
const plMat3Template< Type > GetAsMat3() const
Returns the Quaternion as a matrix.
Definition Quat_inl.h:204
static plQuatTemplate< Type > MakeFromAxisAndAngle(const plVec3Template< Type > &vRotationAxis, plAngle angle)
Creates a quaternion from a rotation-axis and an angle.
Definition Quat_inl.h:50
Type Dot(const plQuatTemplate &rhs) const
Returns the dot-product of the two quaternions (commutative, order does not matter).
Definition Quat_inl.h:122
void GetAsEulerAngles(plAngle &out_x, plAngle &out_y, plAngle &out_z) const
Converts the quaternion to Euler angles.
Definition Quat_inl.h:477
bool IsValid(Type fEpsilon=plMath::DefaultEpsilon< Type >()) const
Checks whether all components are neither NaN nor infinite and that the quaternion is normalized.
Definition Quat_inl.h:162
void Invert()
Inverts the rotation, so instead of rotating N degrees around an axis, the quaternion will rotate -N ...
Definition Quat_inl.h:98
A 3-component vector class.
Definition Vec3.h:9
void Set(Type xyz)
Sets all 3 components to this value.
Definition Vec3_inl.h:32
const plVec3Template< Type > CrossRH(const plVec3Template< Type > &rhs) const
Returns the Cross-product of the two vectors (NOT commutative, order DOES matter)
Definition Vec3_inl.h:299
bool IsValid() const
Checks that all components are finite numbers.
Definition Vec3_inl.h:157
bool IsEqual(const plVec3Template< Type > &rhs, Type fEpsilon) const
Equality Check with epsilon.
Definition Vec3_inl.h:431
PL_DECLARE_IF_FLOAT_TYPE const plVec3Template< Type > GetNormalized() const
Returns a normalized version of this vector, leaves the vector itself unchanged.
Definition Vec3_inl.h:86
Type Dot(const plVec3Template< Type > &rhs) const
Returns the Dot-product of the two vectors (commutative, order does not matter)
Definition Vec3_inl.h:290
constexpr TYPE Pi()
Returns the natural constant Pi.
PL_ALWAYS_INLINE plAngle ASin(float f)
Returns the arcus sinus of f.
Definition MathFloat_inl.h:77
PL_ALWAYS_INLINE plAngle ACos(float f)
Returns the arcus cosinus of f.
Definition MathFloat_inl.h:82
PL_ALWAYS_INLINE float Sin(plAngle a)
***** Trigonometric Functions *****
Definition MathFloat_inl.h:62
PL_ALWAYS_INLINE plAngle ATan2(float y, float x)
Returns the atan2 of x and y.
Definition MathFloat_inl.h:92
constexpr Type Invert(Type f)
Returns 1 / f.
Definition Math_inl.h:63
constexpr TYPE NaN()
Returns the value for NaN as the template type. Returns zero, if the type does not support NaN.
Definition Constants_inl.h:58
PL_ALWAYS_INLINE double Sqrt(double f)
Returns the square root of f.
Definition MathDouble_inl.h:99
constexpr bool IsEqual(Type lhs, Type rhs, Type fEpsilon)
Checks, whether fValue is in the range [fDesired - fMaxImprecision; fDesired + fMaxImprecision].
Definition Math_inl.h:276
constexpr PL_ALWAYS_INLINE T Abs(T f)
Returns the absolute value of f.
Definition Math_inl.h:21
PL_ALWAYS_INLINE float Cos(plAngle a)
Takes an angle, returns its cosine.
Definition MathFloat_inl.h:67