Merge pull request #1148 from Vadmeme/master

Made GLM_FORCE_QUAT_DATA_XYZW be supported by most major functions #1148
This commit is contained in:
Christophe 2023-08-18 15:13:52 +02:00 committed by GitHub
commit d46ce89c74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 87 additions and 55 deletions

View File

@ -95,6 +95,8 @@ namespace glm
GLM_FUNC_DECL GLM_CONSTEXPR qua(T w, T x, T y, T z);
# endif
GLM_FUNC_DECL static GLM_CONSTEXPR qua<T, Q> wxyz(T w, T x, T y, T z);
// -- Conversion constructors --
template<typename U, qualifier P>

View File

@ -28,7 +28,7 @@ namespace detail
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua<T, Q> call(qua<T, Q> const& q, qua<T, Q> const& p)
{
return qua<T, Q>(q.w + p.w, q.x + p.x, q.y + p.y, q.z + p.z);
return qua<T, Q>::wxyz(q.w + p.w, q.x + p.x, q.y + p.y, q.z + p.z);
}
};
@ -37,7 +37,7 @@ namespace detail
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua<T, Q> call(qua<T, Q> const& q, qua<T, Q> const& p)
{
return qua<T, Q>(q.w - p.w, q.x - p.x, q.y - p.y, q.z - p.z);
return qua<T, Q>::wxyz(q.w - p.w, q.x - p.x, q.y - p.y, q.z - p.z);
}
};
@ -46,7 +46,7 @@ namespace detail
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua<T, Q> call(qua<T, Q> const& q, T s)
{
return qua<T, Q>(q.w * s, q.x * s, q.y * s, q.z * s);
return qua<T, Q>::wxyz(q.w * s, q.x * s, q.y * s, q.z * s);
}
};
@ -55,7 +55,7 @@ namespace detail
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua<T, Q> call(qua<T, Q> const& q, T s)
{
return qua<T, Q>(q.w / s, q.x / s, q.y / s, q.z / s);
return qua<T, Q>::wxyz(q.w / s, q.x / s, q.y / s, q.z / s);
}
};
@ -150,6 +150,15 @@ namespace detail
# endif
{}
template <typename T, qualifier Q>
GLM_CONSTEXPR qua<T, Q> qua<T, Q>::wxyz(T w, T x, T y, T z) {
# ifdef GLM_FORCE_QUAT_DATA_XYZW
return qua<T, Q>(x, y, z, w);
# else
return qua<T, Q>(w, x, y, z);
# endif
}
// -- Conversion constructors --
template<typename T, qualifier Q>
@ -201,7 +210,7 @@ namespace detail
t = cross(u, v);
}
*this = normalize(qua<T, Q>(real_part, t.x, t.y, t.z));
*this = normalize(qua<T, Q>::wxyz(real_part, t.x, t.y, t.z));
}
template<typename T, qualifier Q>
@ -320,7 +329,7 @@ namespace detail
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator-(qua<T, Q> const& q)
{
return qua<T, Q>(-q.w, -q.x, -q.y, -q.z);
return qua<T, Q>::wxyz(-q.w, -q.x, -q.y, -q.z);
}
// -- Binary operators --
@ -374,7 +383,7 @@ namespace detail
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator*(qua<T, Q> const& q, T const& s)
{
return qua<T, Q>(
return qua<T, Q>::wxyz(
q.w * s, q.x * s, q.y * s, q.z * s);
}
@ -387,7 +396,7 @@ namespace detail
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator/(qua<T, Q> const& q, T const& s)
{
return qua<T, Q>(
return qua<T, Q>::wxyz(
q.w / s, q.x / s, q.y / s, q.z / s);
}

View File

@ -161,24 +161,45 @@ namespace detail
{
static vec<4, float, Q> call(qua<float, Q> const& q, vec<4, float, Q> const& v)
{
__m128 const q_wwww = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 3, 3, 3));
__m128 const q_swp0 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 0, 2, 1));
__m128 const q_swp1 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 1, 0, 2));
__m128 const v_swp0 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 0, 2, 1));
__m128 const v_swp1 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 1, 0, 2));
# ifdef GLM_FORCE_QUAT_DATA_XYZW
__m128 const q_wwww = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 3, 3, 3));
__m128 const q_swp0 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 0, 2, 1));
__m128 const q_swp1 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 1, 0, 2));
__m128 const v_swp0 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 0, 2, 1));
__m128 const v_swp1 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 1, 0, 2));
__m128 uv = _mm_sub_ps(_mm_mul_ps(q_swp0, v_swp1), _mm_mul_ps(q_swp1, v_swp0));
__m128 uv_swp0 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 0, 2, 1));
__m128 uv_swp1 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 1, 0, 2));
__m128 uuv = _mm_sub_ps(_mm_mul_ps(q_swp0, uv_swp1), _mm_mul_ps(q_swp1, uv_swp0));
__m128 uv = _mm_sub_ps(_mm_mul_ps(q_swp0, v_swp1), _mm_mul_ps(q_swp1, v_swp0));
__m128 uv_swp0 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 0, 2, 1));
__m128 uv_swp1 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 1, 0, 2));
__m128 uuv = _mm_sub_ps(_mm_mul_ps(q_swp0, uv_swp1), _mm_mul_ps(q_swp1, uv_swp0));
__m128 const two = _mm_set1_ps(2.0f);
uv = _mm_mul_ps(uv, _mm_mul_ps(q_wwww, two));
uuv = _mm_mul_ps(uuv, two);
__m128 const two = _mm_set1_ps(2.0f);
uv = _mm_mul_ps(uv, _mm_mul_ps(q_wwww, two));
uuv = _mm_mul_ps(uuv, two);
vec<4, float, Q> Result;
Result.data = _mm_add_ps(v.data, _mm_add_ps(uv, uuv));
return Result;
vec<4, float, Q> Result;
Result.data = _mm_add_ps(v.data, _mm_add_ps(uv, uuv));
return Result;
# else
__m128 const q_wwww = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(0, 0, 0, 0));
__m128 const q_swp0 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(0, 1, 3, 2));
__m128 const q_swp1 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(0, 2, 1, 3));
__m128 const v_swp0 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 0, 2, 1));
__m128 const v_swp1 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 1, 0, 2));
__m128 uv = _mm_sub_ps(_mm_mul_ps(q_swp0, v_swp1), _mm_mul_ps(q_swp1, v_swp0));
__m128 uv_swp0 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 0, 2, 1));
__m128 uv_swp1 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 1, 0, 2));
__m128 uuv = _mm_sub_ps(_mm_mul_ps(q_swp0, uv_swp1), _mm_mul_ps(q_swp1, uv_swp0));
__m128 const two = _mm_set1_ps(2.0f);
uv = _mm_mul_ps(uv, _mm_mul_ps(q_wwww, two));
uuv = _mm_mul_ps(uuv, two);
vec<4, float, Q> Result;
Result.data = _mm_add_ps(v.data, _mm_add_ps(uv, uuv));
return Result;
# endif
}
};
}//namespace detail

View File

@ -11,7 +11,7 @@ namespace glm
if(cosTheta > static_cast<T>(1) - epsilon<T>())
{
// Linear interpolation
return qua<T, Q>(
return qua<T, Q>::wxyz(
mix(x.w, y.w, a),
mix(x.x, y.x, a),
mix(x.y, y.y, a),
@ -58,7 +58,7 @@ namespace glm
if(cosTheta > static_cast<T>(1) - epsilon<T>())
{
// Linear interpolation
return qua<T, Q>(
return qua<T, Q>::wxyz(
mix(x.w, z.w, a),
mix(x.x, z.x, a),
mix(x.y, z.y, a),
@ -94,7 +94,7 @@ namespace glm
if (cosTheta > static_cast<T>(1) - epsilon<T>())
{
// Linear interpolation
return qua<T, Q>(
return qua<T, Q>::wxyz(
mix(x.w, z.w, a),
mix(x.x, z.x, a),
mix(x.y, z.y, a),
@ -112,7 +112,7 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> conjugate(qua<T, Q> const& q)
{
return qua<T, Q>(q.w, -q.x, -q.y, -q.z);
return qua<T, Q>::wxyz(q.w, -q.x, -q.y, -q.z);
}
template<typename T, qualifier Q>

View File

@ -23,17 +23,17 @@ namespace glm
if (Vec3Len < epsilon<T>())
{
if(q.w > static_cast<T>(0))
return qua<T, Q>(log(q.w), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
return qua<T, Q>::wxyz(log(q.w), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
else if(q.w < static_cast<T>(0))
return qua<T, Q>(log(-q.w), pi<T>(), static_cast<T>(0), static_cast<T>(0));
return qua<T, Q>::wxyz(log(-q.w), pi<T>(), static_cast<T>(0), static_cast<T>(0));
else
return qua<T, Q>(std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity());
return qua<T, Q>::wxyz(std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity());
}
else
{
T t = atan(Vec3Len, T(q.w)) / Vec3Len;
T QuatLen2 = Vec3Len * Vec3Len + q.w * q.w;
return qua<T, Q>(static_cast<T>(0.5) * log(QuatLen2), t * q.x, t * q.y, t * q.z);
return qua<T, Q>::wxyz(static_cast<T>(0.5) * log(QuatLen2), t * q.x, t * q.y, t * q.z);
}
}
@ -43,7 +43,7 @@ namespace glm
//Raising to the power of 0 should yield 1
//Needed to prevent a division by 0 error later on
if(y > -epsilon<T>() && y < epsilon<T>())
return qua<T, Q>(1,0,0,0);
return qua<T, Q>::wxyz(1,0,0,0);
//To deal with non-unit quaternions
T magnitude = sqrt(x.x * x.x + x.y * x.y + x.z * x.z + x.w *x.w);
@ -62,7 +62,7 @@ namespace glm
//always false, even when VectorMagnitude is 0.
if (VectorMagnitude < std::numeric_limits<T>::min()) {
//Equivalent to raising a real number to a power
return qua<T, Q>(pow(x.w, y), 0, 0, 0);
return qua<T, Q>::wxyz(pow(x.w, y), 0, 0, 0);
}
Angle = asin(sqrt(VectorMagnitude) / magnitude);
@ -76,7 +76,7 @@ namespace glm
T NewAngle = Angle * y;
T Div = sin(NewAngle) / sin(Angle);
T Mag = pow(magnitude, y - static_cast<T>(1));
return qua<T, Q>(cos(NewAngle) * magnitude * Mag, x.x * Div * Mag, x.y * Div * Mag, x.z * Div * Mag);
return qua<T, Q>::wxyz(cos(NewAngle) * magnitude * Mag, x.x * Div * Mag, x.y * Div * Mag, x.z * Div * Mag);
}
template<typename T, qualifier Q>

View File

@ -18,15 +18,15 @@ namespace glm
{
T len = length(q);
if(len <= static_cast<T>(0)) // Problem
return qua<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
return qua<T, Q>::wxyz(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
T oneOverLen = static_cast<T>(1) / len;
return qua<T, Q>(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen);
return qua<T, Q>::wxyz(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> cross(qua<T, Q> const& q1, qua<T, Q> const& q2)
{
return qua<T, Q>(
return qua<T, Q>::wxyz(
q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z,
q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,
q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z,

View File

@ -18,7 +18,7 @@ namespace glm
T const AngleRad(angle);
T const Sin = sin(AngleRad * static_cast<T>(0.5));
return q * qua<T, Q>(cos(AngleRad * static_cast<T>(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
return q * qua<T, Q>::wxyz(cos(AngleRad * static_cast<T>(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
}
}//namespace glm

View File

@ -109,16 +109,16 @@ namespace glm
switch(biggestIndex)
{
case 0:
return qua<T, Q>(biggestVal, (m[1][2] - m[2][1]) * mult, (m[2][0] - m[0][2]) * mult, (m[0][1] - m[1][0]) * mult);
return qua<T, Q>::wxyz(biggestVal, (m[1][2] - m[2][1]) * mult, (m[2][0] - m[0][2]) * mult, (m[0][1] - m[1][0]) * mult);
case 1:
return qua<T, Q>((m[1][2] - m[2][1]) * mult, biggestVal, (m[0][1] + m[1][0]) * mult, (m[2][0] + m[0][2]) * mult);
return qua<T, Q>::wxyz((m[1][2] - m[2][1]) * mult, biggestVal, (m[0][1] + m[1][0]) * mult, (m[2][0] + m[0][2]) * mult);
case 2:
return qua<T, Q>((m[2][0] - m[0][2]) * mult, (m[0][1] + m[1][0]) * mult, biggestVal, (m[1][2] + m[2][1]) * mult);
return qua<T, Q>::wxyz((m[2][0] - m[0][2]) * mult, (m[0][1] + m[1][0]) * mult, biggestVal, (m[1][2] + m[2][1]) * mult);
case 3:
return qua<T, Q>((m[0][1] - m[1][0]) * mult, (m[2][0] + m[0][2]) * mult, (m[1][2] + m[2][1]) * mult, biggestVal);
return qua<T, Q>::wxyz((m[0][1] - m[1][0]) * mult, (m[2][0] + m[0][2]) * mult, (m[1][2] + m[2][1]) * mult, biggestVal);
default: // Silence a -Wswitch-default warning in GCC. Should never actually get here. Assert is just for sanity.
assert(false);
return qua<T, Q>(1, 0, 0, 0);
return qua<T, Q>::wxyz(1, 0, 0, 0);
}
}

View File

@ -28,7 +28,7 @@ namespace glm
GLM_DEFAULTED_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat()
# if GLM_CONFIG_DEFAULTED_FUNCTIONS != GLM_DISABLE
: real(qua<T, Q>())
, dual(qua<T, Q>(0, 0, 0, 0))
, dual(qua<T, Q>::wxyz(0, 0, 0, 0))
# endif
{}
@ -50,16 +50,16 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(qua<T, Q> const& r)
: real(r), dual(qua<T, Q>(0, 0, 0, 0))
: real(r), dual(qua<T, Q>::wxyz(0, 0, 0, 0))
{}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(qua<T, Q> const& q, vec<3, T, Q> const& p)
: real(q), dual(
: real(q), dual(qua<T, Q>::wxyz(
T(-0.5) * ( p.x*q.x + p.y*q.y + p.z*q.z),
T(+0.5) * ( p.x*q.w + p.y*q.z - p.z*q.y),
T(+0.5) * (-p.x*q.z + p.y*q.w + p.z*q.x),
T(+0.5) * ( p.x*q.y - p.y*q.x + p.z*q.w))
T(+0.5) * ( p.x*q.y - p.y*q.x + p.z*q.w)))
{}
template<typename T, qualifier Q>
@ -219,8 +219,8 @@ namespace glm
GLM_FUNC_QUALIFIER tdualquat<T, Q> dual_quat_identity()
{
return tdualquat<T, Q>(
qua<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)),
qua<T, Q>(static_cast<T>(0), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)));
qua<T, Q>::wxyz(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)),
qua<T, Q>::wxyz(static_cast<T>(0), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)));
}
template<typename T, qualifier Q>
@ -295,8 +295,8 @@ namespace glm
GLM_FUNC_QUALIFIER tdualquat<T, Q> dualquat_cast(mat<2, 4, T, Q> const& x)
{
return tdualquat<T, Q>(
qua<T, Q>( x[0].w, x[0].x, x[0].y, x[0].z ),
qua<T, Q>( x[1].w, x[1].x, x[1].y, x[1].z ));
qua<T, Q>::wxyz( x[0].w, x[0].x, x[0].y, x[0].z ),
qua<T, Q>::wxyz( x[1].w, x[1].x, x[1].y, x[1].z ));
}
template<typename T, qualifier Q>

View File

@ -8,7 +8,7 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> quat_identity()
{
return qua<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
return qua<T, Q>::wxyz(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
}
template<typename T, qualifier Q>
@ -105,7 +105,7 @@ namespace glm
k1 = sin((static_cast<T>(0) + a) * fAngle) * fOneOverSin;
}
return qua<T, Q>(
return qua<T, Q>::wxyz(
k0 * x.w + k1 * y2.w,
k0 * x.x + k1 * y2.x,
k0 * x.y + k1 * y2.y,
@ -150,7 +150,7 @@ namespace glm
T s = sqrt((T(1) + cosTheta) * static_cast<T>(2));
T invs = static_cast<T>(1) / s;
return qua<T, Q>(
return qua<T, Q>::wxyz(
s * static_cast<T>(0.5f),
rotationAxis.x * invs,
rotationAxis.y * invs,

View File

@ -52,7 +52,7 @@ namespace glm
T const AngleRad(angle);
T const Sin = sin(AngleRad * T(0.5));
return q * qua<T, Q>(cos(AngleRad * static_cast<T>(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
return q * qua<T, Q>::wxyz(cos(AngleRad * static_cast<T>(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
//return gtc::quaternion::cross(q, tquat<T, Q>(cos(AngleRad * T(0.5)), Tmp.x * fSin, Tmp.y * fSin, Tmp.z * fSin));
}
}//namespace glm