11 #ifndef TurtleBrains_Quaternion_hpp
12 #define TurtleBrains_Quaternion_hpp
14 #include <turtle_brains/math/tb_math.hpp>
15 #include <turtle_brains/math/tb_interpolation.hpp>
16 #include <turtle_brains/core/tb_configuration.hpp>
17 #include <turtle_brains/core/tb_error.hpp>
18 #include <turtle_brains/core/tb_defines.hpp>
19 #include <turtle_brains/math/tb_vector.hpp>
20 #include <turtle_brains/math/tb_angle.hpp>
26 template<
typename Type>
class TypedMatrix3;
27 template<
typename Type>
class TypedMatrix4;
28 template<
typename Type>
class TypedQuaternion;
30 typedef TypedQuaternion<float> Quaternion;
32 template<
typename Type> TypedVector3<Type> MultiplyVector3Quaternion(
const TypedVector3<Type>& left,
const TypedQuaternion<Type>& right);
33 template<
typename Type> TypedQuaternion<Type>*
QuaternionMultiply(TypedQuaternion<Type>* result,
34 const TypedQuaternion<Type>* left,
const TypedQuaternion<Type>* right);
52 #if defined(tb_visual_cpp)
54 #pragma warning(disable: 4201)
55 struct { Type x, y, z, w; };
58 struct { Type x, y, z, w; };
92 inline TypedQuaternion(
const Type valueX,
const Type valueY,
const Type valueZ,
const Type valueW) :
112 tb_error(
"Probably useful to explicitly convert (not copy value) see HAXE: from_angle_axis function");
121 x(componentArray[0]),
122 y(componentArray[1]),
123 z(componentArray[2]),
174 return (
true ==
IsEqual(x, other.x) &&
true ==
IsEqual(y, other.y) &&
175 true ==
IsEqual(z, other.z) &&
true ==
IsEqual(w, other.w)) ? true :
false;
184 return (
true ==
operator==(other)) ? false :
true;
190 inline operator const Type*(void)
const
199 inline operator Type*(void)
210 static_cast<ToType
>(z),
static_cast<ToType
>(w));
218 return mComponents[index];
227 return mComponents[index];
230 #if defined(tb_with_math_operators)
237 return TypedQuaternion(x + rightSide.x, y + rightSide.y, z + rightSide.z, w + rightSide.w);
246 x += rightSide.x; y += rightSide.y; z += rightSide.z; w += rightSide.w;
255 return TypedQuaternion(x - rightSide.x, y - rightSide.y, z - rightSide.z, w - rightSide.w);
263 x -= rightSide.x; y -= rightSide.y; z -= rightSide.z; w -= rightSide.w;
294 return TypedQuaternion(x * scalar, y * scalar, z * scalar, w * scalar);
303 return TypedQuaternion(scalar * rightSide.x, scalar * rightSide.y, scalar * rightSide.z, scalar * rightSide.w);
312 x *= scalar; y *= scalar; z *= scalar; w *= scalar;
321 return TypedQuaternion(x / scalar, y / scalar, z / scalar, w / scalar);
353 return sqrt((x * x) + (y * y) + (z * z) + (w * w));
362 return (x * x) + (y * y) + (z * z) + (w * w);
373 return TypedQuaternion(x / magnitude, y / magnitude, z / magnitude, w / magnitude);
383 if (
true ==
IsZero(magnitude))
402 return MultiplyVector3Quaternion(forward, *
this);
442 TypedAngle<Type>(std::atan2(Type(2) * mComponents[0] * mComponents[3] - Type(2) * mComponents[1] * mComponents[2],
443 Type(1) - Type(2) * std::pow(mComponents[0], Type(2)) - Type(2) * std::pow(mComponents[2], Type(2))),
446 TypedAngle<Type>(std::atan2(Type(2) * mComponents[1] * mComponents[3] - Type(2) * mComponents[0] * mComponents[2],
447 Type(1) - Type(2) * std::pow(mComponents[1], Type(2)) - Type(2) * std::pow(mComponents[2], Type(2))),
450 TypedAngle<Type>(std::asin(Type(2) * mComponents[0] * mComponents[1] + 2 * mComponents[2] * mComponents[3]),
462 const Type s = std::sqrt(Type(1.0) - normalizedSelf.w * normalizedSelf.w);
464 axis = (s < Type(0.995)) ?
Vector3(normalizedSelf.x, normalizedSelf.y, normalizedSelf.z) :
465 Vector3(normalizedSelf.x / s, normalizedSelf.y / s, normalizedSelf.z / s);
473 const Type s = std::sin(angle.
AsRadians() * Type(0.5));
474 const Type c = std::cos(angle.
AsRadians() * Type(0.5));
487 Vector3 axis(SkipInitialization::kSkipInitialization);
501 const Type c1 = std::cos(halfHeading);
502 const Type s1 = std::sin(halfHeading);
503 const Type c2 = std::cos(halfPitch);
504 const Type s2 = std::sin(halfPitch);
505 const Type c3 = std::cos(halfRoll);
506 const Type s3 = std::sin(halfRoll);
507 const Type c1c2 = c1*c2;
508 const Type s1s2 = s1*s2;
540 tb_error_if(
nullptr == left,
"tbExternalError: Invalid parameter for left, expected valid pointer.");
541 tb_error_if(
nullptr == right,
"tbExternalError: Invalid parameter for right, expected valid pointer.");
542 tb_error_if(
nullptr == result,
"tbExternalError: Invalid parameter for result, expected valid pointer.");
544 result->x = left->x + right->x;
545 result->y = left->y + right->y;
546 result->z = left->z + right->z;
547 result->w = left->w + right->w;
564 tb_error_if(
nullptr == left,
"tbExternalError: Invalid parameter for left, expected valid pointer.");
565 tb_error_if(
nullptr == right,
"tbExternalError: Invalid parameter for right, expected valid pointer.");
566 tb_error_if(
nullptr == result,
"tbExternalError: Invalid parameter for result, expected valid pointer.");
568 result->x = left->x - right->x;
569 result->y = left->y - right->y;
570 result->z = left->z - right->z;
571 result->w = left->w - right->w;
587 tb_error_if(
nullptr == left,
"tbExternalError: Invalid parameter for left, expected valid pointer.");
588 tb_error_if(
nullptr == right,
"tbExternalError: Invalid parameter for right, expected valid pointer.");
589 tb_error_if(
nullptr == result,
"tbExternalError: Invalid parameter for result, expected valid pointer.");
590 tb_error_if(result == left || result == right,
"tbExternalError: Invalid parameter for result, expected different location than left or right.")
599 result->x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;
600 result->y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;
601 result->z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;
602 result->w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;
618 tb_error_if(
nullptr == result,
"tbExternalError: Invalid parameter for result, expected valid pointer.");
619 tb_error_if(
nullptr == input,
"tbExternalError: Invalid parameter for input, expected valid pointer.");
621 result->x = input->x * scalar;
622 result->y = input->y * scalar;
623 result->z = input->z * scalar;
624 result->w = input->w * scalar;
640 tb_error_if(
nullptr == result,
"tbExternalError: Invalid parameter for result, expected valid pointer.");
641 tb_error_if(
nullptr == input,
"tbExternalError: Invalid parameter for input, expected valid pointer.");
643 result->x = input->x / scalar;
644 result->y = input->y / scalar;
645 result->z = input->z / scalar;
646 result->w = input->w / scalar;
661 tb_error_if(
nullptr == input,
"tbExternalError: Invalid parameter for input, expected valid pointer.");
662 tb_error_if(
nullptr == result,
"tbExternalError: Invalid parameter for result, expected valid pointer.");
664 result->x = -input->x;
665 result->y = -input->y;
666 result->z = -input->z;
667 result->w = -input->w;
676 return std::sqrt((input->x * input->x) + (input->y * input->y) + (input->z * input->z) + (input->w * input->w));
685 return (input->x * input->x) + (input->y * input->y) + (input->z * input->z) + (input->w * input->w);
698 tb_error_if(
nullptr == result,
"tbExternalError: Invalid parameter for result, expected valid pointer.");
699 tb_error_if(
nullptr == input,
"tbExternalError: Invalid parameter for input, expected valid pointer.");
702 if (
true ==
IsZero(magnitude))
704 result->x = Type(0.0);
705 result->y = Type(0.0);
706 result->z = Type(0.0);
707 result->w = Type(1.0);
711 result->x = input->x / magnitude;
712 result->y = input->y / magnitude;
713 result->z = input->z / magnitude;
714 result->w = input->w / magnitude;
733 tb_error_if(
nullptr == result,
"tbExternalError: Invalid parameter for result, expected valid pointer.");
734 tb_error_if(
nullptr == input,
"tbExternalError: Invalid parameter for input, expected valid pointer.");
737 if (
true ==
IsZero(magnitude))
746 result->x = input->x / magnitude;
747 result->y = input->y / magnitude;
748 result->z = input->z / magnitude;
749 result->w = input->w / magnitude;
765 tb_error_if(
nullptr == input,
"tbExternalError: Invalid parameter for input, expected valid pointer.");
766 tb_error_if(
nullptr == result,
"tbExternalError: Invalid parameter for result, expected valid pointer.");
768 result->x = -input->x;
769 result->y = -input->y;
770 result->z = -input->z;
771 result->w = input->w;
775 template<
typename Type> Type QuaternionDotProduct(
const TypedQuaternion<Type>* leftSide,
const TypedQuaternion<Type>* rightSide)
777 tb_error_if(
nullptr == leftSide,
"tbExternalError: Invalid parameter for leftSide, expected valid pointer.");
778 tb_error_if(
nullptr == rightSide,
"tbExternalError: Invalid parameter for rightSide, expected valid pointer.");
779 return (leftSide->x * rightSide->x) + (leftSide->y * rightSide->y) + (leftSide->z * rightSide->z) + (leftSide->w * rightSide->w);
783 template<
typename Type> TypedQuaternion<Type>* QuaternionLerp(TypedQuaternion<Type>* result,
784 const TypedQuaternion<Type>* start,
const TypedQuaternion<Type>*
final,
const Type time)
786 tb_error_if(
nullptr == start,
"tbExternalError: Invalid parameter for start, expected valid pointer.");
787 tb_error_if(
nullptr ==
final,
"tbExternalError: Invalid parameter for final, expected valid pointer.");
788 tb_error_if(
nullptr == result,
"tbExternalError: Invalid parameter for result, expected valid pointer.");
789 tb_error_if(result == start || result ==
final,
"tbExternalError: Invalid parameter for result, expected different location than start or final.")
798 TypedQuaternion<Type> resultB;
806 template<typename Type> TypedQuaternion<Type> QuaternionSlerp(const TypedQuaternion<Type>& start,
807 const TypedQuaternion<Type>& final, const Type time)
846 Type dot = QuaternionDotProduct(&start, &
final);
848 TypedQuaternion<Type> a(start);
855 if (dot > Type(0.995))
857 TypedQuaternion<Type> result;
858 QuaternionLerp(&result, &start, &
final, time);
865 TypedQuaternion<Type> temporary;
868 temporary.Normalize();
870 const Type theta = std::acos(dot) * time;
875 TypedQuaternion<Type> result(SkipInitialization::kSkipInitialization);
880 template<
typename Type> TypedVector3<Type> MultiplyVector3Quaternion(
const TypedVector3<Type>& left,
881 const TypedQuaternion<Type>& right)
883 TypedVector3<Type> uv(SkipInitialization::kSkipInitialization);
884 TypedVector3<Type> uuv(SkipInitialization::kSkipInitialization);
885 TypedVector3<Type> quat3(right[0], right[1], right[2]);
889 return left + ((uv * right.w) + uuv) * Type(2.0);
894 output <<
"{ " << data.x <<
", " << data.y <<
", " << data.z <<
", " << data.w <<
" }";
Definition: tb_angle.hpp:38
Type AsRadians(void) const
Definition: tb_angle.hpp:87
Definition: tb_matrix.hpp:156
Definition: tb_matrix.hpp:596
Definition: tb_quaternion.hpp:41
const Type & operator[](const int index) const
Definition: tb_quaternion.hpp:216
static TypedQuaternion FromEuler(const TypedVector3< Type > &euler, const tbMath::AngleUnit &angleUnits)
Definition: tb_quaternion.hpp:495
Type & operator[](const int index)
Definition: tb_quaternion.hpp:225
static TypedQuaternion Identity(void)
Definition: tb_quaternion.hpp:46
TypedQuaternion(const Type *componentArray)
Definition: tb_quaternion.hpp:120
TypedVector3< Type > ApplyForward(const TypedVector3< Type > &forward) const
Definition: tb_quaternion.hpp:400
TypedQuaternion(void)
Definition: tb_quaternion.hpp:76
Type Magnitude(void) const
Definition: tb_quaternion.hpp:351
void ToAngleAxis(TypedAngle< Type > &angle, TypedVector3< Type > &axis) const
Definition: tb_quaternion.hpp:458
Type MagnitudeSquared(void) const
Definition: tb_quaternion.hpp:360
~TypedQuaternion(void)
Definition: tb_quaternion.hpp:145
TypedQuaternion(const SkipInitialization &fastAndStupid)
Definition: tb_quaternion.hpp:68
Type Normalize(void)
Definition: tb_quaternion.hpp:380
bool operator==(const TypedQuaternion &other) const
Definition: tb_quaternion.hpp:172
TypedQuaternion(const TypedVector3< Type > &other, const Type valueW)
Definition: tb_quaternion.hpp:106
bool operator!=(const TypedQuaternion &other) const
Definition: tb_quaternion.hpp:182
TypedQuaternion & operator=(const TypedQuaternion &other)
Definition: tb_quaternion.hpp:154
TypedVector3< Type > ToEuler(const AngleUnit &angleUnits) const
Definition: tb_quaternion.hpp:413
TypedQuaternion(const Type valueX, const Type valueY, const Type valueZ, const Type valueW)
Definition: tb_quaternion.hpp:92
TypedQuaternion GetNormalized(void) const
Definition: tb_quaternion.hpp:369
static TypedQuaternion FromForward(const TypedVector3< Type > &forward, const TypedVector3< Type > *up=nullptr)
Definition: tb_quaternion.hpp:481
TypedQuaternion(const TypedQuaternion &other)
Definition: tb_quaternion.hpp:134
static TypedQuaternion FromAngleAxis(const TypedAngle< Type > angle, const TypedVector3< Type > &axis)
Definition: tb_quaternion.hpp:471
Definition: tb_vector.hpp:472
#define tb_unused(parameter)
Definition: tb_defines.hpp:25
#define tb_error(message,...)
Definition: tb_error.hpp:23
#define tb_error_if(errorTest, message,...)
Definition: tb_error.hpp:42
Contains objects and functions for dealing with Vector and Matrix math.
TypedQuaternion< Type > * QuaternionMultiply(TypedQuaternion< Type > *result, const TypedQuaternion< Type > *left, const TypedQuaternion< Type > *right)
Definition: tb_quaternion.hpp:584
Type Vector3DotProduct(const TypedVector3< Type > *leftSide, const TypedVector3< Type > *rightSide)
Definition: tb_vector.hpp:1618
Type QuaternionMagnitudeSquared(const TypedQuaternion< Type > *input)
Definition: tb_quaternion.hpp:683
TypedQuaternion< Type > * QuaternionNormalize(TypedQuaternion< Type > *result, const TypedQuaternion< Type > *input)
Definition: tb_quaternion.hpp:696
std::ostream & operator<<(std::ostream &output, const tbMath::TypedAngle< Type > &angle)
Definition: tb_angle.hpp:203
bool IsZero(const Type &value, const Type tolerance=tbMath::kTolerance)
Definition: tb_math.hpp:74
bool IsEqual(const Type &leftValue, const Type &rightValue, const Type tolerance=tbMath::kTolerance)
Definition: tb_math.hpp:56
TypedQuaternion< Type > * QuaternionNormalizeMagnitude(TypedQuaternion< Type > *result, const TypedQuaternion< Type > *input, Type &magnitude)
Definition: tb_quaternion.hpp:730
TypedQuaternion< Type > * QuaternionInverse(TypedQuaternion< Type > *result, const TypedQuaternion< Type > *input)
Definition: tb_quaternion.hpp:763
TypedQuaternion< Type > * QuaternionSubtract(TypedQuaternion< Type > *result, const TypedQuaternion< Type > *left, const TypedQuaternion< Type > *right)
Definition: tb_quaternion.hpp:561
TypedQuaternion< Type > * QuaternionAdd(TypedQuaternion< Type > *result, const TypedQuaternion< Type > *left, const TypedQuaternion< Type > *right)
Definition: tb_quaternion.hpp:537
SkipInitialization
Definition: tb_vector.hpp:80
Type QuaternionMagnitude(const TypedQuaternion< Type > *input)
Definition: tb_quaternion.hpp:674
AngleUnit
Definition: tb_angle.hpp:27
@ Radians
Specifies the angle input value is in units of Radians.
TypedQuaternion< Type > * QuaternionScaleDivide(TypedQuaternion< Type > *result, const TypedQuaternion< Type > *input, const Type scalar)
Definition: tb_quaternion.hpp:637
TypedQuaternion< Type > * QuaternionScale(TypedQuaternion< Type > *result, const TypedQuaternion< Type > *input, const Type scalar)
Definition: tb_quaternion.hpp:615
TypedVector3< Type > * Vector3CrossProduct(TypedVector3< Type > *result, const TypedVector3< Type > *leftSide, const TypedVector3< Type > *rightSide)
Definition: tb_vector.hpp:1648
TypedQuaternion< Type > * QuaternionNegate(TypedQuaternion< Type > *result, const TypedQuaternion< Type > *input)
Definition: tb_quaternion.hpp:659
constexpr const Type & Clamp(const Type &value, const Type &minimumValue, const Type &maximumValue) noexcept
Definition: tb_math.hpp:91
Here is some information about the primary namespace.
Definition: tb_application_dialog.hpp:22