Ye-Song's picture
Add files using upload-large-folder tool
7b853a5 verified
/*
* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "Vector.h"
namespace Math
{
class alignas(16) Quaternion
{
public:
static Quaternion const Identity;
// Calculate the rotation required to align the source vector to the target vector (shortest path)
static Quaternion FromRotationBetweenNormalizedVectors(const Vector& sourceVector, const Vector& targetVector);
// Calculate the rotation required to align one vector onto another but also taking account a fallback rotation axis for opposite parallel vectors
static Quaternion FromRotationBetweenNormalizedVectors(const Vector& sourceVector, const Vector& targetVector, const Vector& fallbackRotationAxis);
// Calculate the rotation required to align the source vector to the target vector (shortest path)
static Quaternion FromRotationBetweenVectors(const Vector& sourceVector, const Vector& targetVector);
// Normalized LERP - not accurate - only use for really short distances
static Quaternion NLerp(const Quaternion& from, const Quaternion& to, float t);
// Standard and accurate Spherical LERP - based on DirectX Math
static Quaternion SLerp(const Quaternion& from, const Quaternion& to, float t);
// Fast approximation of a Spherical LERP - based on "A fast and accurate estimate for SLERP" by David Eberly
static Quaternion FastSLerp(const Quaternion& from, const Quaternion& to, float t);
// Spherical quadrangle/cubic interpolation for quaternions
static Quaternion SQuad(const Quaternion& q0, const Quaternion& q1, const Quaternion& q2, const Quaternion& q3, float t);
// Calculate the shortest delta quaternion needed to rotate 'from' onto 'to'
static Quaternion Delta(const Quaternion& from, const Quaternion& to);
// Simple vector dot product between two quaternions
static Vector Dot(const Quaternion& q0, const Quaternion& q1);
// Calculate the angular distance between two quaternions
static Radians Distance(const Quaternion& q0, const Quaternion& q1);
// Calculate look rotation given forward and up vectors
static Quaternion LookRotation(const Vector& forward, const Vector& up);
public:
Quaternion() = default;
explicit Quaternion(NoInit_t);
explicit Quaternion(IdentityInit_t);
explicit Quaternion(const Vector& v);
explicit Quaternion(float ix, float iy, float iz, float iw);
explicit Quaternion(const Float4& v);
explicit Quaternion(const Vector& axis, Radians angle);
explicit Quaternion(AxisAngle axisAngle);
explicit Quaternion(const EulerAngles& eulerAngles);
explicit Quaternion(Radians rotX, Radians rotY, Radians rotZ);
operator __m128& ();
operator const __m128& () const;
Float4 ToFloat4() const;
Vector ToVector() const;
Vector Length();
float GetLength() const;
// Get the angle this rotation represents around the specified axis
Radians GetAngle() const;
AxisAngle ToAxisAngle() const;
EulerAngles ToEulerAngles() const;
Vector RotateVector(const Vector& vector) const;
Vector RotateVectorInverse(const Vector& vector) const;
Quaternion& Conjugate();
Quaternion GetConjugate() const;
Quaternion& Negate();
Quaternion GetNegated() const;
Quaternion& Invert();
Quaternion GetInverse() const;
Quaternion& Normalize();
Quaternion GetNormalized() const;
Vector XAxis() const noexcept;
Vector YAxis() const noexcept;
Vector ZAxis() const noexcept;
// Ensure that this rotation is the shortest in terms of the angle (i.e. -5 instead of 355)
Quaternion& MakeShortestPath();
// Ensure that this rotation is the shortest in terms of the angle (i.e. -5 instead of 355)
Quaternion GetShortestPath() const;
// This function will return the estimated normalized quaternion, this is not super accurate but a lot faster (use with care)
Quaternion& NormalizeInaccurate();
// This function will return the estimated normalized quaternion, this is not super accurate but a lot faster (use with care)
Quaternion GetNormalizedInaccurate() const;
bool IsNormalized() const;
bool IsIdentity() const;
// Concatenate the rotation of this onto rhs and return the result i.e. first rotate by rhs then by this
// This means order of rotation is right-to-left: child-rotation * parent-rotation
Quaternion operator*(const Quaternion& rhs) const;
Quaternion& operator*=(const Quaternion& rhs);
// Is the distance between this quaternion and another one under the threshold?
bool IsNearEqual(const Quaternion& rhs, Radians const threshold = Math::DegreesToRadians) const;
// Exact equality
bool operator==(const Quaternion& rhs) const;
// Exact equality
bool operator!=(const Quaternion& rhs) const;
private:
Vector GetSplatW() const;
float GetW() const;
Quaternion& operator=(const Vector& v) = delete;
public:
__m128 m_data;
};
static_assert(sizeof(Vector) == 16, "Quaternion size must be 16 bytes!");
}
#include "Quaternion.inl"