mirror of
https://github.com/g-truc/glm.git
synced 2024-11-22 17:04:35 +00:00
Fixed quaternion constructor from two vectors special cases #469
This commit is contained in:
parent
4e0c87683c
commit
6932058f59
@ -148,11 +148,25 @@ namespace detail
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER tquat<T, Q>::tquat(vec<3, T, Q> const& u, vec<3, T, Q> const& v)
|
||||
{
|
||||
vec<3, T, Q> const LocalW(cross(u, v));
|
||||
T Dot = detail::compute_dot<vec<3, T, Q>, T, detail::is_aligned<Q>::value>::call(u, v);
|
||||
tquat<T, Q> q(T(1) + Dot, LocalW.x, LocalW.y, LocalW.z);
|
||||
T norm_u_norm_v = sqrt(dot(u, u) * dot(v, v));
|
||||
T real_part = norm_u_norm_v + dot(u, v);
|
||||
vec<3, T, Q> w;
|
||||
|
||||
*this = normalize(q);
|
||||
if(real_part < static_cast<T>(1.e-6f) * norm_u_norm_v)
|
||||
{
|
||||
// If u and v are exactly opposite, rotate 180 degrees
|
||||
// around an arbitrary orthogonal axis. Axis normalisation
|
||||
// can happen later, when we normalise the quaternion.
|
||||
real_part = static_cast<T>(0);
|
||||
w = abs(u.x) > abs(u.z) ? vec<3, T, Q>(-u.y, u.x, static_cast<T>(0)) : vec<3, T, Q>(static_cast<T>(0), -u.z, u.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, build quaternion the standard way.
|
||||
w = cross(u, v);
|
||||
}
|
||||
|
||||
*this = normalize(tquat<T, Q>(real_part, w.x, w.y, w.z));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
|
@ -101,6 +101,7 @@ glm::mat4 camera(float Translate, glm::vec2 const& Rotate)
|
||||
- Fixed documentation warnings
|
||||
- Fixed GLM_HAS_OPENMP when OpenMP is not enabled
|
||||
- Fixed Better follow GLSL min and max specification #372
|
||||
- Fixed quaternion constructor from two vectors special cases #469
|
||||
|
||||
#### Deprecation:
|
||||
- Requires Visual Studio 2013, GCC 4.7, Clang 3.4, Cuda 7, ICC 2013 or a C++11 compiler
|
||||
|
@ -225,16 +225,28 @@ int test_quat_mul()
|
||||
|
||||
int test_quat_two_axis_ctr()
|
||||
{
|
||||
int Error(0);
|
||||
int Error = 0;
|
||||
|
||||
glm::quat q1(glm::vec3(1, 0, 0), glm::vec3(0, 1, 0));
|
||||
glm::vec3 v1 = q1 * glm::vec3(1, 0, 0);
|
||||
glm::quat const q1(glm::vec3(1, 0, 0), glm::vec3(0, 1, 0));
|
||||
glm::vec3 const v1 = q1 * glm::vec3(1, 0, 0);
|
||||
Error += glm::all(glm::epsilonEqual(v1, glm::vec3(0, 1, 0), 0.0001f)) ? 0 : 1;
|
||||
|
||||
glm::quat q2 = q1 * q1;
|
||||
glm::vec3 v2 = q2 * glm::vec3(1, 0, 0);
|
||||
glm::quat const q2 = q1 * q1;
|
||||
glm::vec3 const v2 = q2 * glm::vec3(1, 0, 0);
|
||||
Error += glm::all(glm::epsilonEqual(v2, glm::vec3(-1, 0, 0), 0.0001f)) ? 0 : 1;
|
||||
|
||||
glm::quat const q3(glm::vec3(1, 0, 0), glm::vec3(-1, 0, 0));
|
||||
glm::vec3 const v3 = q3 * glm::vec3(1, 0, 0);
|
||||
Error += glm::all(glm::epsilonEqual(v3, glm::vec3(-1, 0, 0), 0.0001f)) ? 0 : 1;
|
||||
|
||||
glm::quat const q4(glm::vec3(0, 1, 0), glm::vec3(0, -1, 0));
|
||||
glm::vec3 const v4 = q4 * glm::vec3(0, 1, 0);
|
||||
Error += glm::all(glm::epsilonEqual(v4, glm::vec3(0, -1, 0), 0.0001f)) ? 0 : 1;
|
||||
|
||||
glm::quat const q5(glm::vec3(0, 0, 1), glm::vec3(0, 0, -1));
|
||||
glm::vec3 const v5 = q5 * glm::vec3(0, 0, 1);
|
||||
Error += glm::all(glm::epsilonEqual(v5, glm::vec3(0, 0, -1), 0.0001f)) ? 0 : 1;
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user