5#include "../BasicTypes.h"
11
12
13
14
15
16
17
18
19
20
40 static const FQuat Identity;
45 FORCEINLINE FQuat() { }
48
49
50
51
55
56
57
58
59
60
61
62 FORCEINLINE FQuat(
float InX,
float InY,
float InZ,
float InW);
65
66
67
68
69 FORCEINLINE FQuat(
const FQuat& Q);
72
73
74
75
79
80
81
82
83
84 FQuat(
FVector Axis,
float AngleRad);
88#ifdef IMPLEMENT_ASSIGNMENT_OPERATOR_MANUALLY
90
91
92
93
94 FORCEINLINE FQuat& operator=(
const FQuat& Other);
98
99
100
101
102
103
104 FORCEINLINE FQuat operator+(
const FQuat& Q)
const;
107
108
109
110
111
112
113 FORCEINLINE FQuat operator+=(
const FQuat& Q);
116
117
118
119
120
121
122 FORCEINLINE FQuat operator-(
const FQuat& Q)
const;
125
126
127
128
129
130
134
135
136
137
138
139
140 FORCEINLINE
bool IsIdentity(
float Tolerance=
SMALL_NUMBER)
const;
143
144
145
146
147
148
149 FORCEINLINE FQuat operator-=(
const FQuat& Q);
152
153
154
155
156
157
161
162
163
164
165
166 FORCEINLINE FQuat operator*=(
const float Scale);
169
170
171
172
173
174 FORCEINLINE FQuat operator*(
const float Scale)
const;
177
178
179
180
181
182 FORCEINLINE FQuat operator/=(
const float Scale);
185
186
187
188
189
190 FORCEINLINE FQuat operator/(
const float Scale)
const;
193
194
195
196
197
198
199
200
201 bool operator==(
const FQuat& Q)
const;
204
205
206
207
208
209 bool operator!=(
const FQuat& Q)
const;
212
213
214
215
216
217 float operator|(
const FQuat& Q)
const;
222
223
224
225
226
227 static FQuat MakeFromEuler(
const FVector& Euler);
233
234
235
236
237
238 FORCEINLINE
void Normalize(
float Tolerance =
SMALL_NUMBER);
241
242
243
244
245
246 FORCEINLINE FQuat GetNormalized(
float Tolerance =
SMALL_NUMBER)
const;
249 bool IsNormalized()
const;
252
253
254
255
256 FORCEINLINE
float Size()
const;
259
260
261
262
263 FORCEINLINE
float SizeSquared()
const;
267 FORCEINLINE
float GetAngle()
const;
270
271
272
273
274
275
276 void ToAxisAndAngle(
FVector& Axis,
float& Angle)
const;
279
280
281
282
283
284
285
286 void ToSwingTwist(
const FVector& InTwistAxis, FQuat& OutSwing, FQuat& OutTwist)
const;
289
290
291
292
293
297
298
299
300
301
305
306
310
311
312
313
317
318
319 FORCEINLINE FQuat Inverse()
const;
322
323
324
325 void EnforceShortestArcWith(
const FQuat& OtherQuat);
328 FORCEINLINE
FVector GetAxisX()
const;
331 FORCEINLINE
FVector GetAxisY()
const;
334 FORCEINLINE
FVector GetAxisZ()
const;
337 FORCEINLINE
FVector GetForwardVector()
const;
340 FORCEINLINE
FVector GetRightVector()
const;
343 FORCEINLINE
FVector GetUpVector()
const;
346 FORCEINLINE
FVector Vector()
const;
352
353
354
355
356 FORCEINLINE
FVector GetRotationAxis()
const;
359 FORCEINLINE
float AngularDistance(
const FQuat& Q)
const;
362
363
364
365
366 bool ContainsNaN()
const;
369
370
371
372
376
377
378
379
380
381
382
383 bool InitFromString(
const FString& InSourceString);
388 FORCEINLINE
void DiagnosticCheckNaN()
const
392 logOrEnsureNanError(TEXT(
"FQuat contains NaN: %s"), *ToString());
393 *
const_cast<FQuat*>(
this) = FQuat::Identity;
397 FORCEINLINE
void DiagnosticCheckNaN(
const TCHAR* Message)
const
401 logOrEnsureNanError(TEXT(
"%s: FQuat contains NaN: %s"), Message, *ToString());
402 *
const_cast<FQuat*>(
this) = FQuat::Identity;
406 FORCEINLINE
void DiagnosticCheckNaN()
const {}
407 FORCEINLINE
void DiagnosticCheckNaN(
const TCHAR* Message)
const {}
413
414
415 static FORCEINLINE FQuat FindBetween(
const FVector& Vector1,
const FVector& Vector2)
417 return FindBetweenVectors(Vector1, Vector2);
421
422
423 static FQuat FindBetweenNormals(
const FVector& Normal1,
const FVector& Normal2);
426
427
428 static FQuat FindBetweenVectors(
const FVector& Vector1,
const FVector& Vector2);
431
432
433
434
435 static FORCEINLINE
float Error(
const FQuat& Q1,
const FQuat& Q2);
438
439
440 static FORCEINLINE
float ErrorAutoNormalize(
const FQuat& A,
const FQuat& B);
443
444
445
446 static FORCEINLINE FQuat FastLerp(
const FQuat& A,
const FQuat& B,
const float Alpha);
449
450
451
452 static FORCEINLINE FQuat FastBilerp(
const FQuat& P00,
const FQuat& P10,
const FQuat& P01,
const FQuat& P11,
float FracX,
float FracY);
456 static FQuat Slerp_NotNormalized(
const FQuat &Quat1,
const FQuat &Quat2,
float Slerp);
459 static FORCEINLINE FQuat Slerp(
const FQuat &Quat1,
const FQuat &Quat2,
float Slerp)
461 return Slerp_NotNormalized(Quat1, Quat2, Slerp).GetNormalized();
465
466
467
468
469 static FQuat SlerpFullPath_NotNormalized(
const FQuat &quat1,
const FQuat &quat2,
float Alpha);
472
473
474
475
476 static FORCEINLINE FQuat SlerpFullPath(
const FQuat &quat1,
const FQuat &quat2,
float Alpha)
478 return SlerpFullPath_NotNormalized(quat1, quat2, Alpha).GetNormalized();
482
483
484
485 static FQuat Squad(
const FQuat& quat1,
const FQuat& tang1,
const FQuat& quat2,
const FQuat& tang2,
float Alpha);
488
489
490
491 static FQuat SquadFullPath(
const FQuat& quat1,
const FQuat& tang1,
const FQuat& quat2,
const FQuat& tang2,
float Alpha);
494
495
496
497
498
499
500
501
502 static void CalcTangents(
const FQuat& PrevP,
const FQuat& P,
const FQuat& NextP,
float Tension, FQuat& OutTan);
508
510FORCEINLINE FQuat::FQuat(
const FRotator& R)
513 DiagnosticCheckNaN();
519 return RotateVector(V);
523
530FORCEINLINE FQuat::FQuat(
float InX,
float InY,
float InZ,
float InW)
536 DiagnosticCheckNaN();
540FORCEINLINE FQuat::FQuat(
const FQuat& Q)
547#ifdef IMPLEMENT_ASSIGNMENT_OPERATOR_MANUALLY
548FORCEINLINE FQuat& FQuat::operator=(
const FQuat& Other)
560FORCEINLINE FQuat::FQuat(
FVector Axis,
float AngleRad)
562 const float half_a = 0.5f * AngleRad;
571 DiagnosticCheckNaN();
575FORCEINLINE FQuat FQuat::operator+(
const FQuat& Q)
const
577 return FQuat(X + Q.X, Y + Q.Y, Z + Q.Z, W + Q.W);
581FORCEINLINE FQuat FQuat::operator+=(
const FQuat& Q)
588 DiagnosticCheckNaN();
594FORCEINLINE FQuat FQuat::operator-(
const FQuat& Q)
const
596 return FQuat(X - Q.X, Y - Q.Y, Z - Q.Z, W - Q.W);
600FORCEINLINE
bool FQuat::Equals(
const FQuat& Q,
float Tolerance)
const
602#if PLATFORM_ENABLE_VECTORINTRINSICS
603 const VectorRegister ToleranceV = VectorLoadFloat1(&Tolerance);
604 const VectorRegister A = VectorLoadAligned(
this);
605 const VectorRegister B = VectorLoadAligned(&Q);
607 const VectorRegister RotationSub = VectorAbs(VectorSubtract(A, B));
608 const VectorRegister RotationAdd = VectorAbs(VectorAdd(A, B));
609 return !VectorAnyGreaterThan(RotationSub, ToleranceV) || !VectorAnyGreaterThan(RotationAdd, ToleranceV);
616FORCEINLINE
bool FQuat::IsIdentity(
float Tolerance)
const
618 return Equals(FQuat::Identity, Tolerance);
621FORCEINLINE FQuat FQuat::operator-=(
const FQuat& Q)
628 DiagnosticCheckNaN();
634FORCEINLINE FQuat FQuat::operator*=(
const float Scale)
641 DiagnosticCheckNaN();
647FORCEINLINE FQuat FQuat::operator*(
const float Scale)
const
649 return FQuat(Scale * X, Scale * Y, Scale * Z, Scale * W);
653FORCEINLINE FQuat FQuat::operator/=(
const float Scale)
655 const float Recip = 1.0f / Scale;
661 DiagnosticCheckNaN();
667FORCEINLINE FQuat FQuat::operator/(
const float Scale)
const
669 const float Recip = 1.0f / Scale;
670 return FQuat(X * Recip, Y * Recip, Z * Recip, W * Recip);
674FORCEINLINE
bool FQuat::operator==(
const FQuat& Q)
const
676#if PLATFORM_ENABLE_VECTORINTRINSICS
677 const VectorRegister A = VectorLoadAligned(
this);
678 const VectorRegister B = VectorLoadAligned(&Q);
679 return VectorMaskBits(VectorCompareEQ(A, B)) == 0x0F;
681 return X == Q.X && Y == Q.Y && Z == Q.Z && W == Q.W;
686FORCEINLINE
bool FQuat::operator!=(
const FQuat& Q)
const
688#if PLATFORM_ENABLE_VECTORINTRINSICS
689 const VectorRegister A = VectorLoadAligned(
this);
690 const VectorRegister B = VectorLoadAligned(&Q);
691 return VectorMaskBits(VectorCompareNE(A, B)) != 0x00;
693 return X != Q.X || Y != Q.Y || Z != Q.Z || W != Q.W;
698FORCEINLINE
float FQuat::operator|(
const FQuat& Q)
const
700 return X * Q.X + Y * Q.Y + Z * Q.Z + W * Q.W;
704FORCEINLINE
void FQuat::Normalize(
float Tolerance)
706#if PLATFORM_ENABLE_VECTORINTRINSICS
707 const VectorRegister Vector = VectorLoadAligned(
this);
709 const VectorRegister SquareSum = VectorDot4(Vector, Vector);
710 const VectorRegister NonZeroMask = VectorCompareGE(SquareSum, VectorLoadFloat1(&Tolerance));
711 const VectorRegister InvLength = VectorReciprocalSqrtAccurate(SquareSum);
712 const VectorRegister NormalizedVector = VectorMultiply(InvLength, Vector);
713 VectorRegister Result = VectorSelect(NonZeroMask, NormalizedVector, GlobalVectorConstants::Float0001);
715 VectorStoreAligned(Result,
this);
717 const float SquareSum = X * X + Y * Y + Z * Z + W * W;
719 if (SquareSum >= Tolerance)
730 *
this = FQuat::Identity;
736FORCEINLINE FQuat FQuat::GetNormalized(
float Tolerance)
const
739 Result.Normalize(Tolerance);
743FORCEINLINE
bool FQuat::IsNormalized()
const
749FORCEINLINE
float FQuat::Size()
const
755FORCEINLINE
float FQuat::SizeSquared()
const
757 return (X * X + Y * Y + Z * Z + W * W);
760FORCEINLINE
float FQuat::GetAngle()
const
766FORCEINLINE
void FQuat::ToAxisAndAngle(
FVector& Axis,
float& Angle)
const
769 Axis = GetRotationAxis();
772FORCEINLINE
FVector FQuat::GetRotationAxis()
const
785float FQuat::AngularDistance(
const FQuat& Q)
const
787 float InnerProd = X*Q.X + Y*Q.Y + Z*Q.Z + W*Q.W;
796 VectorQuaternionVector3Rotate(&Result, &V,
this);
819 VectorQuaternionVector3InverseRotate(&Result, &V,
this);
832FORCEINLINE FQuat FQuat::Inverse()
const
836 return FQuat(-X, -Y, -Z, W);
840FORCEINLINE
void FQuat::EnforceShortestArcWith(
const FQuat& OtherQuat)
842 const float DotResult = (OtherQuat | *
this);
852FORCEINLINE
FVector FQuat::GetAxisX()
const
858FORCEINLINE
FVector FQuat::GetAxisY()
const
864FORCEINLINE
FVector FQuat::GetAxisZ()
const
870FORCEINLINE
FVector FQuat::GetForwardVector()
const
875FORCEINLINE
FVector FQuat::GetRightVector()
const
880FORCEINLINE
FVector FQuat::GetUpVector()
const
885FORCEINLINE
FVector FQuat::Vector()
const
891FORCEINLINE
float FQuat::Error(
const FQuat& Q1,
const FQuat& Q2)
893 const float cosom =
FMath::Abs(Q1.X * Q2.X + Q1.Y * Q2.Y + Q1.Z * Q2.Z + Q1.W * Q2.W
);
898FORCEINLINE
float FQuat::ErrorAutoNormalize(
const FQuat& A,
const FQuat& B)
906 return FQuat::Error(Q1, Q2);
910
911
912
913FORCEINLINE FQuat FQuat::FastLerp(
const FQuat& A,
const FQuat& B,
const float Alpha)
916 const float DotResult = (A | B);
918 return (B * Alpha) + (A * (Bias * (1.f - Alpha)));
922FORCEINLINE FQuat FQuat::FastBilerp(
const FQuat& P00,
const FQuat& P10,
const FQuat& P01,
const FQuat& P11,
float FracX,
float FracY)
924 return FQuat::FastLerp(
925 FQuat::FastLerp(P00,P10,FracX),
926 FQuat::FastLerp(P01,P11,FracX),
932FORCEINLINE
bool FQuat::ContainsNaN()
const
#define ENABLE_NAN_DIAGNOSTIC
#define THRESH_QUAT_NORMALIZED
#define KINDA_SMALL_NUMBER
FORCEINLINE FVector operator*(float Scale, const FVector &V)
static FORCEINLINE void SinCos(float *ScalarSin, float *ScalarCos, float Value)
static FORCEINLINE FVector CrossProduct(const FVector &A, const FVector &B)
FORCEINLINE FVector operator+(const FVector &V) const
FORCEINLINE CONSTEXPR FVector(float InX, float InY, float InZ)