mirror of
https://github.com/minetest/irrlicht.git
synced 2025-07-02 00:00:26 +02:00
Reformat the code, using:
find -type f | # list all regular files grep -E '\.(h|cpp|mm)$' | # filter for source files grep -v '/mt_' | # filter out generated files grep -v '/vendor/' | # and vendored GL grep -v '/test/image_loader_test.cpp' | # and this file (has giant literals arrays) xargs -n 1 -P $(nproc) clang-format -i # reformat everything Co-authored-by: numzero <numzer0@yandex.ru>
This commit is contained in:
@ -29,202 +29,201 @@ namespace core
|
||||
Also useful for interpolations. */
|
||||
class quaternion
|
||||
{
|
||||
public:
|
||||
public:
|
||||
//! Default Constructor
|
||||
constexpr quaternion() :
|
||||
X(0.0f), Y(0.0f), Z(0.0f), W(1.0f) {}
|
||||
|
||||
//! Default Constructor
|
||||
constexpr quaternion() : X(0.0f), Y(0.0f), Z(0.0f), W(1.0f) {}
|
||||
//! Constructor
|
||||
constexpr quaternion(f32 x, f32 y, f32 z, f32 w) :
|
||||
X(x), Y(y), Z(z), W(w) {}
|
||||
|
||||
//! Constructor
|
||||
constexpr quaternion(f32 x, f32 y, f32 z, f32 w) : X(x), Y(y), Z(z), W(w) { }
|
||||
//! Constructor which converts Euler angles (radians) to a quaternion
|
||||
quaternion(f32 x, f32 y, f32 z);
|
||||
|
||||
//! Constructor which converts Euler angles (radians) to a quaternion
|
||||
quaternion(f32 x, f32 y, f32 z);
|
||||
|
||||
//! Constructor which converts Euler angles (radians) to a quaternion
|
||||
quaternion(const vector3df& vec);
|
||||
//! Constructor which converts Euler angles (radians) to a quaternion
|
||||
quaternion(const vector3df &vec);
|
||||
|
||||
#ifndef IRR_TEST_BROKEN_QUATERNION_USE
|
||||
//! Constructor which converts a matrix to a quaternion
|
||||
quaternion(const matrix4& mat);
|
||||
//! Constructor which converts a matrix to a quaternion
|
||||
quaternion(const matrix4 &mat);
|
||||
#endif
|
||||
|
||||
//! Equality operator
|
||||
constexpr bool operator==(const quaternion& other) const
|
||||
{
|
||||
return ((X == other.X) &&
|
||||
//! Equality operator
|
||||
constexpr bool operator==(const quaternion &other) const
|
||||
{
|
||||
return ((X == other.X) &&
|
||||
(Y == other.Y) &&
|
||||
(Z == other.Z) &&
|
||||
(W == other.W));
|
||||
}
|
||||
}
|
||||
|
||||
//! inequality operator
|
||||
constexpr bool operator!=(const quaternion& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
//! inequality operator
|
||||
constexpr bool operator!=(const quaternion &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
#ifndef IRR_TEST_BROKEN_QUATERNION_USE
|
||||
//! Matrix assignment operator
|
||||
inline quaternion& operator=(const matrix4& other);
|
||||
//! Matrix assignment operator
|
||||
inline quaternion &operator=(const matrix4 &other);
|
||||
#endif
|
||||
|
||||
//! Add operator
|
||||
quaternion operator+(const quaternion& other) const;
|
||||
//! Add operator
|
||||
quaternion operator+(const quaternion &other) const;
|
||||
|
||||
//! Multiplication operator
|
||||
//! Be careful, unfortunately the operator order here is opposite of that in CMatrix4::operator*
|
||||
quaternion operator*(const quaternion& other) const;
|
||||
//! Multiplication operator
|
||||
//! Be careful, unfortunately the operator order here is opposite of that in CMatrix4::operator*
|
||||
quaternion operator*(const quaternion &other) const;
|
||||
|
||||
//! Multiplication operator with scalar
|
||||
quaternion operator*(f32 s) const;
|
||||
//! Multiplication operator with scalar
|
||||
quaternion operator*(f32 s) const;
|
||||
|
||||
//! Multiplication operator with scalar
|
||||
quaternion& operator*=(f32 s);
|
||||
//! Multiplication operator with scalar
|
||||
quaternion &operator*=(f32 s);
|
||||
|
||||
//! Multiplication operator
|
||||
vector3df operator*(const vector3df& v) const;
|
||||
//! Multiplication operator
|
||||
vector3df operator*(const vector3df &v) const;
|
||||
|
||||
//! Multiplication operator
|
||||
quaternion& operator*=(const quaternion& other);
|
||||
//! Multiplication operator
|
||||
quaternion &operator*=(const quaternion &other);
|
||||
|
||||
//! Calculates the dot product
|
||||
inline f32 dotProduct(const quaternion& other) const;
|
||||
//! Calculates the dot product
|
||||
inline f32 dotProduct(const quaternion &other) const;
|
||||
|
||||
//! Sets new quaternion
|
||||
inline quaternion& set(f32 x, f32 y, f32 z, f32 w);
|
||||
//! Sets new quaternion
|
||||
inline quaternion &set(f32 x, f32 y, f32 z, f32 w);
|
||||
|
||||
//! Sets new quaternion based on Euler angles (radians)
|
||||
inline quaternion& set(f32 x, f32 y, f32 z);
|
||||
//! Sets new quaternion based on Euler angles (radians)
|
||||
inline quaternion &set(f32 x, f32 y, f32 z);
|
||||
|
||||
//! Sets new quaternion based on Euler angles (radians)
|
||||
inline quaternion& set(const core::vector3df& vec);
|
||||
//! Sets new quaternion based on Euler angles (radians)
|
||||
inline quaternion &set(const core::vector3df &vec);
|
||||
|
||||
//! Sets new quaternion from other quaternion
|
||||
inline quaternion& set(const core::quaternion& quat);
|
||||
//! Sets new quaternion from other quaternion
|
||||
inline quaternion &set(const core::quaternion &quat);
|
||||
|
||||
//! returns if this quaternion equals the other one, taking floating point rounding errors into account
|
||||
inline bool equals(const quaternion& other,
|
||||
const f32 tolerance = ROUNDING_ERROR_f32 ) const;
|
||||
//! returns if this quaternion equals the other one, taking floating point rounding errors into account
|
||||
inline bool equals(const quaternion &other,
|
||||
const f32 tolerance = ROUNDING_ERROR_f32) const;
|
||||
|
||||
//! Normalizes the quaternion
|
||||
inline quaternion& normalize();
|
||||
//! Normalizes the quaternion
|
||||
inline quaternion &normalize();
|
||||
|
||||
#ifndef IRR_TEST_BROKEN_QUATERNION_USE
|
||||
//! Creates a matrix from this quaternion
|
||||
matrix4 getMatrix() const;
|
||||
//! Creates a matrix from this quaternion
|
||||
matrix4 getMatrix() const;
|
||||
#endif
|
||||
//! Faster method to create a rotation matrix, you should normalize the quaternion before!
|
||||
void getMatrixFast(matrix4 &dest) const;
|
||||
//! Faster method to create a rotation matrix, you should normalize the quaternion before!
|
||||
void getMatrixFast(matrix4 &dest) const;
|
||||
|
||||
//! Creates a matrix from this quaternion
|
||||
void getMatrix( matrix4 &dest, const core::vector3df &translation=core::vector3df() ) const;
|
||||
//! Creates a matrix from this quaternion
|
||||
void getMatrix(matrix4 &dest, const core::vector3df &translation = core::vector3df()) const;
|
||||
|
||||
/*!
|
||||
Creates a matrix from this quaternion
|
||||
Rotate about a center point
|
||||
shortcut for
|
||||
core::quaternion q;
|
||||
q.rotationFromTo ( vin[i].Normal, forward );
|
||||
q.getMatrixCenter ( lookat, center, newPos );
|
||||
/*!
|
||||
Creates a matrix from this quaternion
|
||||
Rotate about a center point
|
||||
shortcut for
|
||||
core::quaternion q;
|
||||
q.rotationFromTo ( vin[i].Normal, forward );
|
||||
q.getMatrixCenter ( lookat, center, newPos );
|
||||
|
||||
core::matrix4 m2;
|
||||
m2.setInverseTranslation ( center );
|
||||
lookat *= m2;
|
||||
core::matrix4 m2;
|
||||
m2.setInverseTranslation ( center );
|
||||
lookat *= m2;
|
||||
|
||||
core::matrix4 m3;
|
||||
m2.setTranslation ( newPos );
|
||||
lookat *= m3;
|
||||
core::matrix4 m3;
|
||||
m2.setTranslation ( newPos );
|
||||
lookat *= m3;
|
||||
|
||||
*/
|
||||
void getMatrixCenter( matrix4 &dest, const core::vector3df ¢er, const core::vector3df &translation ) const;
|
||||
*/
|
||||
void getMatrixCenter(matrix4 &dest, const core::vector3df ¢er, const core::vector3df &translation) const;
|
||||
|
||||
//! Creates a matrix from this quaternion
|
||||
inline void getMatrix_transposed( matrix4 &dest ) const;
|
||||
//! Creates a matrix from this quaternion
|
||||
inline void getMatrix_transposed(matrix4 &dest) const;
|
||||
|
||||
//! Inverts this quaternion
|
||||
quaternion& makeInverse();
|
||||
//! Inverts this quaternion
|
||||
quaternion &makeInverse();
|
||||
|
||||
//! Set this quaternion to the linear interpolation between two quaternions
|
||||
/** NOTE: lerp result is *not* a normalized quaternion. In most cases
|
||||
you will want to use lerpN instead as most other quaternion functions expect
|
||||
to work with a normalized quaternion.
|
||||
\param q1 First quaternion to be interpolated.
|
||||
\param q2 Second quaternion to be interpolated.
|
||||
\param time Progress of interpolation. For time=0 the result is
|
||||
q1, for time=1 the result is q2. Otherwise interpolation
|
||||
between q1 and q2. Result is not normalized.
|
||||
*/
|
||||
quaternion& lerp(quaternion q1, quaternion q2, f32 time);
|
||||
//! Set this quaternion to the linear interpolation between two quaternions
|
||||
/** NOTE: lerp result is *not* a normalized quaternion. In most cases
|
||||
you will want to use lerpN instead as most other quaternion functions expect
|
||||
to work with a normalized quaternion.
|
||||
\param q1 First quaternion to be interpolated.
|
||||
\param q2 Second quaternion to be interpolated.
|
||||
\param time Progress of interpolation. For time=0 the result is
|
||||
q1, for time=1 the result is q2. Otherwise interpolation
|
||||
between q1 and q2. Result is not normalized.
|
||||
*/
|
||||
quaternion &lerp(quaternion q1, quaternion q2, f32 time);
|
||||
|
||||
//! Set this quaternion to the linear interpolation between two quaternions and normalize the result
|
||||
/**
|
||||
\param q1 First quaternion to be interpolated.
|
||||
\param q2 Second quaternion to be interpolated.
|
||||
\param time Progress of interpolation. For time=0 the result is
|
||||
q1, for time=1 the result is q2. Otherwise interpolation
|
||||
between q1 and q2. Result is normalized.
|
||||
*/
|
||||
quaternion& lerpN(quaternion q1, quaternion q2, f32 time);
|
||||
//! Set this quaternion to the linear interpolation between two quaternions and normalize the result
|
||||
/**
|
||||
\param q1 First quaternion to be interpolated.
|
||||
\param q2 Second quaternion to be interpolated.
|
||||
\param time Progress of interpolation. For time=0 the result is
|
||||
q1, for time=1 the result is q2. Otherwise interpolation
|
||||
between q1 and q2. Result is normalized.
|
||||
*/
|
||||
quaternion &lerpN(quaternion q1, quaternion q2, f32 time);
|
||||
|
||||
//! Set this quaternion to the result of the spherical interpolation between two quaternions
|
||||
/** \param q1 First quaternion to be interpolated.
|
||||
\param q2 Second quaternion to be interpolated.
|
||||
\param time Progress of interpolation. For time=0 the result is
|
||||
q1, for time=1 the result is q2. Otherwise interpolation
|
||||
between q1 and q2.
|
||||
\param threshold To avoid inaccuracies at the end (time=1) the
|
||||
interpolation switches to linear interpolation at some point.
|
||||
This value defines how much of the remaining interpolation will
|
||||
be calculated with lerp. Everything from 1-threshold up will be
|
||||
linear interpolation.
|
||||
*/
|
||||
quaternion& slerp(quaternion q1, quaternion q2,
|
||||
f32 time, f32 threshold=.05f);
|
||||
//! Set this quaternion to the result of the spherical interpolation between two quaternions
|
||||
/** \param q1 First quaternion to be interpolated.
|
||||
\param q2 Second quaternion to be interpolated.
|
||||
\param time Progress of interpolation. For time=0 the result is
|
||||
q1, for time=1 the result is q2. Otherwise interpolation
|
||||
between q1 and q2.
|
||||
\param threshold To avoid inaccuracies at the end (time=1) the
|
||||
interpolation switches to linear interpolation at some point.
|
||||
This value defines how much of the remaining interpolation will
|
||||
be calculated with lerp. Everything from 1-threshold up will be
|
||||
linear interpolation.
|
||||
*/
|
||||
quaternion &slerp(quaternion q1, quaternion q2,
|
||||
f32 time, f32 threshold = .05f);
|
||||
|
||||
//! Set this quaternion to represent a rotation from angle and axis.
|
||||
/** Axis must be unit length.
|
||||
The quaternion representing the rotation is
|
||||
q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k).
|
||||
\param angle Rotation Angle in radians.
|
||||
\param axis Rotation axis. */
|
||||
quaternion& fromAngleAxis (f32 angle, const vector3df& axis);
|
||||
//! Set this quaternion to represent a rotation from angle and axis.
|
||||
/** Axis must be unit length.
|
||||
The quaternion representing the rotation is
|
||||
q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k).
|
||||
\param angle Rotation Angle in radians.
|
||||
\param axis Rotation axis. */
|
||||
quaternion &fromAngleAxis(f32 angle, const vector3df &axis);
|
||||
|
||||
//! Fills an angle (radians) around an axis (unit vector)
|
||||
void toAngleAxis (f32 &angle, core::vector3df& axis) const;
|
||||
//! Fills an angle (radians) around an axis (unit vector)
|
||||
void toAngleAxis(f32 &angle, core::vector3df &axis) const;
|
||||
|
||||
//! Output this quaternion to an Euler angle (radians)
|
||||
void toEuler(vector3df& euler) const;
|
||||
//! Output this quaternion to an Euler angle (radians)
|
||||
void toEuler(vector3df &euler) const;
|
||||
|
||||
//! Set quaternion to identity
|
||||
quaternion& makeIdentity();
|
||||
//! Set quaternion to identity
|
||||
quaternion &makeIdentity();
|
||||
|
||||
//! Set quaternion to represent a rotation from one vector to another.
|
||||
quaternion& rotationFromTo(const vector3df& from, const vector3df& to);
|
||||
//! Set quaternion to represent a rotation from one vector to another.
|
||||
quaternion &rotationFromTo(const vector3df &from, const vector3df &to);
|
||||
|
||||
//! Quaternion elements.
|
||||
f32 X; // vectorial (imaginary) part
|
||||
f32 Y;
|
||||
f32 Z;
|
||||
f32 W; // real part
|
||||
//! Quaternion elements.
|
||||
f32 X; // vectorial (imaginary) part
|
||||
f32 Y;
|
||||
f32 Z;
|
||||
f32 W; // real part
|
||||
};
|
||||
|
||||
|
||||
// Constructor which converts Euler angles to a quaternion
|
||||
inline quaternion::quaternion(f32 x, f32 y, f32 z)
|
||||
{
|
||||
set(x,y,z);
|
||||
set(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
// Constructor which converts Euler angles to a quaternion
|
||||
inline quaternion::quaternion(const vector3df& vec)
|
||||
inline quaternion::quaternion(const vector3df &vec)
|
||||
{
|
||||
set(vec.X,vec.Y,vec.Z);
|
||||
set(vec.X, vec.Y, vec.Z);
|
||||
}
|
||||
|
||||
#ifndef IRR_TEST_BROKEN_QUATERNION_USE
|
||||
// Constructor which converts a matrix to a quaternion
|
||||
inline quaternion::quaternion(const matrix4& mat)
|
||||
inline quaternion::quaternion(const matrix4 &mat)
|
||||
{
|
||||
(*this) = mat;
|
||||
}
|
||||
@ -232,12 +231,11 @@ inline quaternion::quaternion(const matrix4& mat)
|
||||
|
||||
#ifndef IRR_TEST_BROKEN_QUATERNION_USE
|
||||
// matrix assignment operator
|
||||
inline quaternion& quaternion::operator=(const matrix4& m)
|
||||
inline quaternion &quaternion::operator=(const matrix4 &m)
|
||||
{
|
||||
const f32 diag = m[0] + m[5] + m[10] + 1;
|
||||
|
||||
if( diag > 0.0f )
|
||||
{
|
||||
if (diag > 0.0f) {
|
||||
const f32 scale = sqrtf(diag) * 2.0f; // get scale from diagonal
|
||||
|
||||
// TODO: speed this up
|
||||
@ -245,11 +243,8 @@ inline quaternion& quaternion::operator=(const matrix4& m)
|
||||
Y = (m[8] - m[2]) / scale;
|
||||
Z = (m[1] - m[4]) / scale;
|
||||
W = 0.25f * scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m[0]>m[5] && m[0]>m[10])
|
||||
{
|
||||
} else {
|
||||
if (m[0] > m[5] && m[0] > m[10]) {
|
||||
// 1st element of diag is greatest value
|
||||
// find scale according to 1st element, and double it
|
||||
const f32 scale = sqrtf(1.0f + m[0] - m[5] - m[10]) * 2.0f;
|
||||
@ -259,9 +254,7 @@ inline quaternion& quaternion::operator=(const matrix4& m)
|
||||
Y = (m[4] + m[1]) / scale;
|
||||
Z = (m[2] + m[8]) / scale;
|
||||
W = (m[6] - m[9]) / scale;
|
||||
}
|
||||
else if (m[5]>m[10])
|
||||
{
|
||||
} else if (m[5] > m[10]) {
|
||||
// 2nd element of diag is greatest value
|
||||
// find scale according to 2nd element, and double it
|
||||
const f32 scale = sqrtf(1.0f + m[5] - m[0] - m[10]) * 2.0f;
|
||||
@ -271,9 +264,7 @@ inline quaternion& quaternion::operator=(const matrix4& m)
|
||||
Y = 0.25f * scale;
|
||||
Z = (m[9] + m[6]) / scale;
|
||||
W = (m[8] - m[2]) / scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// 3rd element of diag is greatest value
|
||||
// find scale according to 3rd element, and double it
|
||||
const f32 scale = sqrtf(1.0f + m[10] - m[0] - m[5]) * 2.0f;
|
||||
@ -290,9 +281,8 @@ inline quaternion& quaternion::operator=(const matrix4& m)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// multiplication operator
|
||||
inline quaternion quaternion::operator*(const quaternion& other) const
|
||||
inline quaternion quaternion::operator*(const quaternion &other) const
|
||||
{
|
||||
quaternion tmp;
|
||||
|
||||
@ -304,34 +294,32 @@ inline quaternion quaternion::operator*(const quaternion& other) const
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
// multiplication operator
|
||||
inline quaternion quaternion::operator*(f32 s) const
|
||||
{
|
||||
return quaternion(s*X, s*Y, s*Z, s*W);
|
||||
return quaternion(s * X, s * Y, s * Z, s * W);
|
||||
}
|
||||
|
||||
|
||||
// multiplication operator
|
||||
inline quaternion& quaternion::operator*=(f32 s)
|
||||
inline quaternion &quaternion::operator*=(f32 s)
|
||||
{
|
||||
X*=s;
|
||||
Y*=s;
|
||||
Z*=s;
|
||||
W*=s;
|
||||
X *= s;
|
||||
Y *= s;
|
||||
Z *= s;
|
||||
W *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// multiplication operator
|
||||
inline quaternion& quaternion::operator*=(const quaternion& other)
|
||||
inline quaternion &quaternion::operator*=(const quaternion &other)
|
||||
{
|
||||
return (*this = other * (*this));
|
||||
}
|
||||
|
||||
// add operator
|
||||
inline quaternion quaternion::operator+(const quaternion& b) const
|
||||
inline quaternion quaternion::operator+(const quaternion &b) const
|
||||
{
|
||||
return quaternion(X+b.X, Y+b.Y, Z+b.Z, W+b.W);
|
||||
return quaternion(X + b.X, Y + b.Y, Z + b.Z, W + b.W);
|
||||
}
|
||||
|
||||
#ifndef IRR_TEST_BROKEN_QUATERNION_USE
|
||||
@ -345,24 +333,24 @@ inline matrix4 quaternion::getMatrix() const
|
||||
#endif
|
||||
|
||||
//! Faster method to create a rotation matrix, you should normalize the quaternion before!
|
||||
inline void quaternion::getMatrixFast( matrix4 &dest) const
|
||||
inline void quaternion::getMatrixFast(matrix4 &dest) const
|
||||
{
|
||||
// TODO:
|
||||
// gpu quaternion skinning => fast Bones transform chain O_O YEAH!
|
||||
// http://www.mrelusive.com/publications/papers/SIMD-From-Quaternion-to-Matrix-and-Back.pdf
|
||||
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
|
||||
dest[1] = 2.0f*X*Y + 2.0f*Z*W;
|
||||
dest[2] = 2.0f*X*Z - 2.0f*Y*W;
|
||||
dest[0] = 1.0f - 2.0f * Y * Y - 2.0f * Z * Z;
|
||||
dest[1] = 2.0f * X * Y + 2.0f * Z * W;
|
||||
dest[2] = 2.0f * X * Z - 2.0f * Y * W;
|
||||
dest[3] = 0.0f;
|
||||
|
||||
dest[4] = 2.0f*X*Y - 2.0f*Z*W;
|
||||
dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
|
||||
dest[6] = 2.0f*Z*Y + 2.0f*X*W;
|
||||
dest[4] = 2.0f * X * Y - 2.0f * Z * W;
|
||||
dest[5] = 1.0f - 2.0f * X * X - 2.0f * Z * Z;
|
||||
dest[6] = 2.0f * Z * Y + 2.0f * X * W;
|
||||
dest[7] = 0.0f;
|
||||
|
||||
dest[8] = 2.0f*X*Z + 2.0f*Y*W;
|
||||
dest[9] = 2.0f*Z*Y - 2.0f*X*W;
|
||||
dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
|
||||
dest[8] = 2.0f * X * Z + 2.0f * Y * W;
|
||||
dest[9] = 2.0f * Z * Y - 2.0f * X * W;
|
||||
dest[10] = 1.0f - 2.0f * X * X - 2.0f * Y * Y;
|
||||
dest[11] = 0.0f;
|
||||
|
||||
dest[12] = 0.f;
|
||||
@ -382,26 +370,26 @@ inline void quaternion::getMatrix(matrix4 &dest,
|
||||
// ok creating a copy may be slower, but at least avoid internal
|
||||
// state chance (also because otherwise we cannot keep this method "const").
|
||||
|
||||
quaternion q( *this);
|
||||
quaternion q(*this);
|
||||
q.normalize();
|
||||
f32 X = q.X;
|
||||
f32 Y = q.Y;
|
||||
f32 Z = q.Z;
|
||||
f32 W = q.W;
|
||||
|
||||
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
|
||||
dest[1] = 2.0f*X*Y + 2.0f*Z*W;
|
||||
dest[2] = 2.0f*X*Z - 2.0f*Y*W;
|
||||
dest[0] = 1.0f - 2.0f * Y * Y - 2.0f * Z * Z;
|
||||
dest[1] = 2.0f * X * Y + 2.0f * Z * W;
|
||||
dest[2] = 2.0f * X * Z - 2.0f * Y * W;
|
||||
dest[3] = 0.0f;
|
||||
|
||||
dest[4] = 2.0f*X*Y - 2.0f*Z*W;
|
||||
dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
|
||||
dest[6] = 2.0f*Z*Y + 2.0f*X*W;
|
||||
dest[4] = 2.0f * X * Y - 2.0f * Z * W;
|
||||
dest[5] = 1.0f - 2.0f * X * X - 2.0f * Z * Z;
|
||||
dest[6] = 2.0f * Z * Y + 2.0f * X * W;
|
||||
dest[7] = 0.0f;
|
||||
|
||||
dest[8] = 2.0f*X*Z + 2.0f*Y*W;
|
||||
dest[9] = 2.0f*Z*Y - 2.0f*X*W;
|
||||
dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
|
||||
dest[8] = 2.0f * X * Z + 2.0f * Y * W;
|
||||
dest[9] = 2.0f * Z * Y - 2.0f * X * W;
|
||||
dest[10] = 1.0f - 2.0f * X * X - 2.0f * Y * Y;
|
||||
dest[11] = 0.0f;
|
||||
|
||||
dest[12] = center.X;
|
||||
@ -409,10 +397,9 @@ inline void quaternion::getMatrix(matrix4 &dest,
|
||||
dest[14] = center.Z;
|
||||
dest[15] = 1.f;
|
||||
|
||||
dest.setDefinitelyIdentityMatrix ( false );
|
||||
dest.setDefinitelyIdentityMatrix(false);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Creates a matrix from this quaternion
|
||||
Rotate about a center point
|
||||
@ -426,8 +413,8 @@ inline void quaternion::getMatrix(matrix4 &dest,
|
||||
lookat *= m2;
|
||||
*/
|
||||
inline void quaternion::getMatrixCenter(matrix4 &dest,
|
||||
const core::vector3df ¢er,
|
||||
const core::vector3df &translation) const
|
||||
const core::vector3df ¢er,
|
||||
const core::vector3df &translation) const
|
||||
{
|
||||
quaternion q(*this);
|
||||
q.normalize();
|
||||
@ -436,22 +423,22 @@ inline void quaternion::getMatrixCenter(matrix4 &dest,
|
||||
f32 Z = q.Z;
|
||||
f32 W = q.W;
|
||||
|
||||
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
|
||||
dest[1] = 2.0f*X*Y + 2.0f*Z*W;
|
||||
dest[2] = 2.0f*X*Z - 2.0f*Y*W;
|
||||
dest[0] = 1.0f - 2.0f * Y * Y - 2.0f * Z * Z;
|
||||
dest[1] = 2.0f * X * Y + 2.0f * Z * W;
|
||||
dest[2] = 2.0f * X * Z - 2.0f * Y * W;
|
||||
dest[3] = 0.0f;
|
||||
|
||||
dest[4] = 2.0f*X*Y - 2.0f*Z*W;
|
||||
dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
|
||||
dest[6] = 2.0f*Z*Y + 2.0f*X*W;
|
||||
dest[4] = 2.0f * X * Y - 2.0f * Z * W;
|
||||
dest[5] = 1.0f - 2.0f * X * X - 2.0f * Z * Z;
|
||||
dest[6] = 2.0f * Z * Y + 2.0f * X * W;
|
||||
dest[7] = 0.0f;
|
||||
|
||||
dest[8] = 2.0f*X*Z + 2.0f*Y*W;
|
||||
dest[9] = 2.0f*Z*Y - 2.0f*X*W;
|
||||
dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
|
||||
dest[8] = 2.0f * X * Z + 2.0f * Y * W;
|
||||
dest[9] = 2.0f * Z * Y - 2.0f * X * W;
|
||||
dest[10] = 1.0f - 2.0f * X * X - 2.0f * Y * Y;
|
||||
dest[11] = 0.0f;
|
||||
|
||||
dest.setRotationCenter ( center, translation );
|
||||
dest.setRotationCenter(center, translation);
|
||||
}
|
||||
|
||||
// Creates a matrix from this quaternion
|
||||
@ -464,19 +451,19 @@ inline void quaternion::getMatrix_transposed(matrix4 &dest) const
|
||||
f32 Z = q.Z;
|
||||
f32 W = q.W;
|
||||
|
||||
dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
|
||||
dest[4] = 2.0f*X*Y + 2.0f*Z*W;
|
||||
dest[8] = 2.0f*X*Z - 2.0f*Y*W;
|
||||
dest[0] = 1.0f - 2.0f * Y * Y - 2.0f * Z * Z;
|
||||
dest[4] = 2.0f * X * Y + 2.0f * Z * W;
|
||||
dest[8] = 2.0f * X * Z - 2.0f * Y * W;
|
||||
dest[12] = 0.0f;
|
||||
|
||||
dest[1] = 2.0f*X*Y - 2.0f*Z*W;
|
||||
dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
|
||||
dest[9] = 2.0f*Z*Y + 2.0f*X*W;
|
||||
dest[1] = 2.0f * X * Y - 2.0f * Z * W;
|
||||
dest[5] = 1.0f - 2.0f * X * X - 2.0f * Z * Z;
|
||||
dest[9] = 2.0f * Z * Y + 2.0f * X * W;
|
||||
dest[13] = 0.0f;
|
||||
|
||||
dest[2] = 2.0f*X*Z + 2.0f*Y*W;
|
||||
dest[6] = 2.0f*Z*Y - 2.0f*X*W;
|
||||
dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
|
||||
dest[2] = 2.0f * X * Z + 2.0f * Y * W;
|
||||
dest[6] = 2.0f * Z * Y - 2.0f * X * W;
|
||||
dest[10] = 1.0f - 2.0f * X * X - 2.0f * Y * Y;
|
||||
dest[14] = 0.0f;
|
||||
|
||||
dest[3] = 0.f;
|
||||
@ -487,17 +474,17 @@ inline void quaternion::getMatrix_transposed(matrix4 &dest) const
|
||||
dest.setDefinitelyIdentityMatrix(false);
|
||||
}
|
||||
|
||||
|
||||
// Inverts this quaternion
|
||||
inline quaternion& quaternion::makeInverse()
|
||||
inline quaternion &quaternion::makeInverse()
|
||||
{
|
||||
X = -X; Y = -Y; Z = -Z;
|
||||
X = -X;
|
||||
Y = -Y;
|
||||
Z = -Z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// sets new quaternion
|
||||
inline quaternion& quaternion::set(f32 x, f32 y, f32 z, f32 w)
|
||||
inline quaternion &quaternion::set(f32 x, f32 y, f32 z, f32 w)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
@ -506,9 +493,8 @@ inline quaternion& quaternion::set(f32 x, f32 y, f32 z, f32 w)
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// sets new quaternion based on Euler angles
|
||||
inline quaternion& quaternion::set(f32 x, f32 y, f32 z)
|
||||
inline quaternion &quaternion::set(f32 x, f32 y, f32 z)
|
||||
{
|
||||
f64 angle;
|
||||
|
||||
@ -538,108 +524,98 @@ inline quaternion& quaternion::set(f32 x, f32 y, f32 z)
|
||||
}
|
||||
|
||||
// sets new quaternion based on Euler angles
|
||||
inline quaternion& quaternion::set(const core::vector3df& vec)
|
||||
inline quaternion &quaternion::set(const core::vector3df &vec)
|
||||
{
|
||||
return set( vec.X, vec.Y, vec.Z);
|
||||
return set(vec.X, vec.Y, vec.Z);
|
||||
}
|
||||
|
||||
// sets new quaternion based on other quaternion
|
||||
inline quaternion& quaternion::set(const core::quaternion& quat)
|
||||
inline quaternion &quaternion::set(const core::quaternion &quat)
|
||||
{
|
||||
return (*this=quat);
|
||||
return (*this = quat);
|
||||
}
|
||||
|
||||
|
||||
//! returns if this quaternion equals the other one, taking floating point rounding errors into account
|
||||
inline bool quaternion::equals(const quaternion& other, const f32 tolerance) const
|
||||
inline bool quaternion::equals(const quaternion &other, const f32 tolerance) const
|
||||
{
|
||||
return core::equals( X, other.X, tolerance) &&
|
||||
core::equals( Y, other.Y, tolerance) &&
|
||||
core::equals( Z, other.Z, tolerance) &&
|
||||
core::equals( W, other.W, tolerance);
|
||||
return core::equals(X, other.X, tolerance) &&
|
||||
core::equals(Y, other.Y, tolerance) &&
|
||||
core::equals(Z, other.Z, tolerance) &&
|
||||
core::equals(W, other.W, tolerance);
|
||||
}
|
||||
|
||||
|
||||
// normalizes the quaternion
|
||||
inline quaternion& quaternion::normalize()
|
||||
inline quaternion &quaternion::normalize()
|
||||
{
|
||||
// removed conditional branch since it may slow down and anyway the condition was
|
||||
// false even after normalization in some cases.
|
||||
return (*this *= (f32)reciprocal_squareroot ( (f64)(X*X + Y*Y + Z*Z + W*W) ));
|
||||
return (*this *= (f32)reciprocal_squareroot((f64)(X * X + Y * Y + Z * Z + W * W)));
|
||||
}
|
||||
|
||||
// Set this quaternion to the result of the linear interpolation between two quaternions
|
||||
inline quaternion& quaternion::lerp( quaternion q1, quaternion q2, f32 time)
|
||||
inline quaternion &quaternion::lerp(quaternion q1, quaternion q2, f32 time)
|
||||
{
|
||||
const f32 scale = 1.0f - time;
|
||||
return (*this = (q1*scale) + (q2*time));
|
||||
return (*this = (q1 * scale) + (q2 * time));
|
||||
}
|
||||
|
||||
// Set this quaternion to the result of the linear interpolation between two quaternions and normalize the result
|
||||
inline quaternion& quaternion::lerpN( quaternion q1, quaternion q2, f32 time)
|
||||
inline quaternion &quaternion::lerpN(quaternion q1, quaternion q2, f32 time)
|
||||
{
|
||||
const f32 scale = 1.0f - time;
|
||||
return (*this = ((q1*scale) + (q2*time)).normalize() );
|
||||
return (*this = ((q1 * scale) + (q2 * time)).normalize());
|
||||
}
|
||||
|
||||
// set this quaternion to the result of the interpolation between two quaternions
|
||||
inline quaternion& quaternion::slerp( quaternion q1, quaternion q2, f32 time, f32 threshold)
|
||||
inline quaternion &quaternion::slerp(quaternion q1, quaternion q2, f32 time, f32 threshold)
|
||||
{
|
||||
f32 angle = q1.dotProduct(q2);
|
||||
|
||||
// make sure we use the short rotation
|
||||
if (angle < 0.0f)
|
||||
{
|
||||
if (angle < 0.0f) {
|
||||
q1 *= -1.0f;
|
||||
angle *= -1.0f;
|
||||
}
|
||||
|
||||
if (angle <= (1-threshold)) // spherical interpolation
|
||||
if (angle <= (1 - threshold)) // spherical interpolation
|
||||
{
|
||||
const f32 theta = acosf(angle);
|
||||
const f32 invsintheta = reciprocal(sinf(theta));
|
||||
const f32 scale = sinf(theta * (1.0f-time)) * invsintheta;
|
||||
const f32 scale = sinf(theta * (1.0f - time)) * invsintheta;
|
||||
const f32 invscale = sinf(theta * time) * invsintheta;
|
||||
return (*this = (q1*scale) + (q2*invscale));
|
||||
}
|
||||
else // linear interpolation
|
||||
return lerpN(q1,q2,time);
|
||||
return (*this = (q1 * scale) + (q2 * invscale));
|
||||
} else // linear interpolation
|
||||
return lerpN(q1, q2, time);
|
||||
}
|
||||
|
||||
|
||||
// calculates the dot product
|
||||
inline f32 quaternion::dotProduct(const quaternion& q2) const
|
||||
inline f32 quaternion::dotProduct(const quaternion &q2) const
|
||||
{
|
||||
return (X * q2.X) + (Y * q2.Y) + (Z * q2.Z) + (W * q2.W);
|
||||
}
|
||||
|
||||
|
||||
//! axis must be unit length, angle in radians
|
||||
inline quaternion& quaternion::fromAngleAxis(f32 angle, const vector3df& axis)
|
||||
inline quaternion &quaternion::fromAngleAxis(f32 angle, const vector3df &axis)
|
||||
{
|
||||
const f32 fHalfAngle = 0.5f*angle;
|
||||
const f32 fHalfAngle = 0.5f * angle;
|
||||
const f32 fSin = sinf(fHalfAngle);
|
||||
W = cosf(fHalfAngle);
|
||||
X = fSin*axis.X;
|
||||
Y = fSin*axis.Y;
|
||||
Z = fSin*axis.Z;
|
||||
X = fSin * axis.X;
|
||||
Y = fSin * axis.Y;
|
||||
Z = fSin * axis.Z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline void quaternion::toAngleAxis(f32 &angle, core::vector3df &axis) const
|
||||
{
|
||||
const f32 scale = sqrtf(X*X + Y*Y + Z*Z);
|
||||
const f32 scale = sqrtf(X * X + Y * Y + Z * Z);
|
||||
|
||||
if (core::iszero(scale) || W > 1.0f || W < -1.0f)
|
||||
{
|
||||
if (core::iszero(scale) || W > 1.0f || W < -1.0f) {
|
||||
angle = 0.0f;
|
||||
axis.X = 0.0f;
|
||||
axis.Y = 1.0f;
|
||||
axis.Z = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
const f32 invscale = reciprocal(scale);
|
||||
angle = 2.0f * acosf(W);
|
||||
axis.X = X * invscale;
|
||||
@ -648,45 +624,39 @@ inline void quaternion::toAngleAxis(f32 &angle, core::vector3df &axis) const
|
||||
}
|
||||
}
|
||||
|
||||
inline void quaternion::toEuler(vector3df& euler) const
|
||||
inline void quaternion::toEuler(vector3df &euler) const
|
||||
{
|
||||
const f64 sqw = W*W;
|
||||
const f64 sqx = X*X;
|
||||
const f64 sqy = Y*Y;
|
||||
const f64 sqz = Z*Z;
|
||||
const f64 test = 2.0 * (Y*W - X*Z);
|
||||
const f64 sqw = W * W;
|
||||
const f64 sqx = X * X;
|
||||
const f64 sqy = Y * Y;
|
||||
const f64 sqz = Z * Z;
|
||||
const f64 test = 2.0 * (Y * W - X * Z);
|
||||
|
||||
if (core::equals(test, 1.0, 0.000001))
|
||||
{
|
||||
if (core::equals(test, 1.0, 0.000001)) {
|
||||
// heading = rotation about z-axis
|
||||
euler.Z = (f32) (-2.0*atan2(X, W));
|
||||
euler.Z = (f32)(-2.0 * atan2(X, W));
|
||||
// bank = rotation about x-axis
|
||||
euler.X = 0;
|
||||
// attitude = rotation about y-axis
|
||||
euler.Y = (f32) (core::PI64/2.0);
|
||||
}
|
||||
else if (core::equals(test, -1.0, 0.000001))
|
||||
{
|
||||
euler.Y = (f32)(core::PI64 / 2.0);
|
||||
} else if (core::equals(test, -1.0, 0.000001)) {
|
||||
// heading = rotation about z-axis
|
||||
euler.Z = (f32) (2.0*atan2(X, W));
|
||||
euler.Z = (f32)(2.0 * atan2(X, W));
|
||||
// bank = rotation about x-axis
|
||||
euler.X = 0;
|
||||
// attitude = rotation about y-axis
|
||||
euler.Y = (f32) (core::PI64/-2.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
euler.Y = (f32)(core::PI64 / -2.0);
|
||||
} else {
|
||||
// heading = rotation about z-axis
|
||||
euler.Z = (f32) atan2(2.0 * (X*Y +Z*W),(sqx - sqy - sqz + sqw));
|
||||
euler.Z = (f32)atan2(2.0 * (X * Y + Z * W), (sqx - sqy - sqz + sqw));
|
||||
// bank = rotation about x-axis
|
||||
euler.X = (f32) atan2(2.0 * (Y*Z +X*W),(-sqx - sqy + sqz + sqw));
|
||||
euler.X = (f32)atan2(2.0 * (Y * Z + X * W), (-sqx - sqy + sqz + sqw));
|
||||
// attitude = rotation about y-axis
|
||||
euler.Y = (f32) asin( clamp(test, -1.0, 1.0) );
|
||||
euler.Y = (f32)asin(clamp(test, -1.0, 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline vector3df quaternion::operator* (const vector3df& v) const
|
||||
inline vector3df quaternion::operator*(const vector3df &v) const
|
||||
{
|
||||
// nVidia SDK implementation
|
||||
|
||||
@ -701,7 +671,7 @@ inline vector3df quaternion::operator* (const vector3df& v) const
|
||||
}
|
||||
|
||||
// set quaternion to identity
|
||||
inline core::quaternion& quaternion::makeIdentity()
|
||||
inline core::quaternion &quaternion::makeIdentity()
|
||||
{
|
||||
W = 1.f;
|
||||
X = 0.f;
|
||||
@ -710,7 +680,7 @@ inline core::quaternion& quaternion::makeIdentity()
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline core::quaternion& quaternion::rotationFromTo(const vector3df& from, const vector3df& to)
|
||||
inline core::quaternion &quaternion::rotationFromTo(const vector3df &from, const vector3df &to)
|
||||
{
|
||||
// Based on Stan Melax's article in Game Programming Gems
|
||||
// Optimized by Robert Eisele: https://raw.org/proof/quaternion-from-two-vectors
|
||||
@ -725,14 +695,12 @@ inline core::quaternion& quaternion::rotationFromTo(const vector3df& from, const
|
||||
if (d >= 1.0f) // If dot == 1, vectors are the same
|
||||
{
|
||||
return makeIdentity();
|
||||
}
|
||||
else if (d <= -1.0f) // exactly opposite
|
||||
} else if (d <= -1.0f) // exactly opposite
|
||||
{
|
||||
core::vector3df axis(1.0f, 0.f, 0.f);
|
||||
axis = axis.crossProduct(v0);
|
||||
if (axis.getLength()==0)
|
||||
{
|
||||
axis.set(0.f,1.f,0.f);
|
||||
if (axis.getLength() == 0) {
|
||||
axis.set(0.f, 1.f, 0.f);
|
||||
axis = axis.crossProduct(v0);
|
||||
}
|
||||
// same as fromAngleAxis(core::PI, axis).normalize();
|
||||
@ -743,8 +711,5 @@ inline core::quaternion& quaternion::rotationFromTo(const vector3df& from, const
|
||||
return set(c.X, c.Y, c.Z, 1 + d).normalize();
|
||||
}
|
||||
|
||||
|
||||
} // end namespace core
|
||||
} // end namespace irr
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user