| 1 | namespace glm |
| 2 | { |
| 3 | template<typename T, qualifier Q> |
| 4 | GLM_FUNC_QUALIFIER GLM_CONSTEXPR T dot(qua<T, Q> const& x, qua<T, Q> const& y) |
| 5 | { |
| 6 | static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'dot' accepts only floating-point inputs"); |
| 7 | return detail::compute_dot<qua<T, Q>, T, detail::is_aligned<Q>::value>::call(x, y); |
| 8 | } |
| 9 | |
| 10 | template<typename T, qualifier Q> |
| 11 | GLM_FUNC_QUALIFIER T length(qua<T, Q> const& q) |
| 12 | { |
| 13 | return glm::sqrt(dot(q, q)); |
| 14 | } |
| 15 | |
| 16 | template<typename T, qualifier Q> |
| 17 | GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> normalize(qua<T, Q> const& q) |
| 18 | { |
| 19 | T len = length(q); |
| 20 | if(len <= static_cast<T>(0)) // Problem |
| 21 | return qua<T, Q>::wxyz(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)); |
| 22 | T oneOverLen = static_cast<T>(1) / len; |
| 23 | return qua<T, Q>::wxyz(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen); |
| 24 | } |
| 25 | |
| 26 | template<typename T, qualifier Q> |
| 27 | GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> cross(qua<T, Q> const& q1, qua<T, Q> const& q2) |
| 28 | { |
| 29 | return qua<T, Q>::wxyz( |
| 30 | q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z, |
| 31 | q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y, |
| 32 | q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z, |
| 33 | q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x); |
| 34 | } |
| 35 | }//namespace glm |
| 36 | |