Audio/AudioDevice: Improve GetListenerRotation

This commit is contained in:
Jérôme Leclercq 2022-03-17 13:34:47 +01:00
parent 6165b3a101
commit 01061380ee
6 changed files with 56 additions and 7 deletions

View File

@ -35,7 +35,7 @@ namespace Nz
virtual float GetGlobalVolume() const = 0;
virtual Vector3f GetListenerDirection(Vector3f* up = nullptr) const = 0;
virtual Vector3f GetListenerPosition() const = 0;
virtual Quaternionf GetListenerRotation(Vector3f* up = nullptr) const = 0;
virtual Quaternionf GetListenerRotation() const = 0;
virtual Vector3f GetListenerVelocity() const = 0;
virtual float GetSpeedOfSound() const = 0;

View File

@ -55,6 +55,9 @@ namespace Nz
constexpr Angle& operator=(const Angle&) = default;
constexpr const Angle& operator+() const;
constexpr Angle operator-() const;
constexpr Angle operator+(const Angle& other) const;
constexpr Angle operator-(const Angle& other) const;
constexpr Angle operator*(T scalar) const;

View File

@ -381,6 +381,27 @@ namespace Nz
return ToRadianAngle();
}*/
/*!
* \brief Helps to represent the sign of the angle
* \return A constant reference to this angle
*/
template<AngleUnit Unit, typename T>
constexpr const Angle<Unit, T>& Angle<Unit, T>::operator+() const
{
return *this;
}
/*!
* \brief Negates the angle
* \return An angle with a negated value
*/
template<AngleUnit Unit, typename T>
constexpr Angle<Unit, T> Angle<Unit, T>::operator-() const
{
return Angle(-value);
}
/*!
* \brief Addition operator
* \return Adds two angles together

View File

@ -83,6 +83,7 @@ namespace Nz
static Quaternion Identity();
static Quaternion Lerp(const Quaternion& from, const Quaternion& to, T interpolation);
static Quaternion LookAt(const Vector3<T>& forward, const Vector3<T>& up);
static Quaternion Normalize(const Quaternion& quat, T* length = nullptr);
static Quaternion RotationBetween(const Vector3<T>& from, const Vector3<T>& to);
static Quaternion Slerp(const Quaternion& from, const Quaternion& to, T interpolation);

View File

@ -705,7 +705,6 @@ namespace Nz
*
* \see Lerp, Slerp
*/
template<typename T>
Quaternion<T> Quaternion<T>::Lerp(const Quaternion& from, const Quaternion& to, T interpolation)
{
@ -726,6 +725,33 @@ namespace Nz
return interpolated;
}
template<typename T>
Quaternion<T> Quaternion<T>::LookAt(const Vector3<T>& forward, const Vector3<T>& up)
{
// From https://gamedev.stackexchange.com/questions/53129/quaternion-look-at-with-up-vector
Vector3<T> forward_w(1, 0, 0);
Vector3<T> axis = Vector3<T>::CrossProduct(forward, forward_w);
RadianAngle<T> angle = std::acos(Vector3<T>::DotProduct(forward, forward_w));
Vector3<T> third = Vector3<T>::CrossProduct(axis, forward_w);
if (Vector3<T>::DotProduct(third, forward) < 0)
angle = -angle;
Quaternion<T> q1 = Quaternion(angle, axis);
Vector3<T> up_l = q1 * up;
Vector3<T> right = Vector3<T>::Normalize(Vector3<T>::CrossProduct(forward, up));
Vector3<T> up_w = Vector3<T>::Normalize(Vector3<T>::CrossProduct(right, forward));
Vector3<T> axis2 = Vector3<T>::CrossProduct(up_l, up_w);
RadianAngle<T> angle2 = std::acos(Vector3<T>::DotProduct(forward, forward_w));
Quaternion<T> q2 = Quaternion(angle2, axis2);
return q2 * q1;
}
/*!
* \brief Gives the normalized quaternion
* \return A normalized quaternion from the quat

View File

@ -157,7 +157,7 @@ namespace Nz
*
* \see GetListenerDirection
*/
Quaternionf OpenALDevice::GetListenerRotation(Vector3f* up) const
Quaternionf OpenALDevice::GetListenerRotation() const
{
MakeContextCurrent();
@ -165,11 +165,9 @@ namespace Nz
m_library.alGetListenerfv(AL_ORIENTATION, orientation);
Vector3f forward(orientation[0], orientation[1], orientation[2]);
Vector3f up(orientation[3], orientation[4], orientation[5]);
if (up)
up->Set(orientation[3], orientation[4], orientation[5]);
return Quaternionf::RotationBetween(Vector3f::Forward(), forward);
return Quaternionf::LookAt(forward, up);
}
/*!