1/////////////////////////////////////////////////////////////////////////////////////////////////// 2// OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) 3/////////////////////////////////////////////////////////////////////////////////////////////////// 4// Created : 2007-03-05 5// Updated : 2010-02-16 6// Licence : This source is under MIT License 7// File : glm/gtx/vector_query.inl 8/////////////////////////////////////////////////////////////////////////////////////////////////// 9// Dependency: 10// - GLM core 11/////////////////////////////////////////////////////////////////////////////////////////////////// 12 13#include <cassert> 14 15namespace glm{ 16namespace detail 17{ 18 template <typename T, precision P, template <typename, precision> class vecType> 19 struct compute_areCollinear{}; 20 21 template <typename T, precision P> 22 struct compute_areCollinear<T, P, tvec2> 23 { 24 GLM_FUNC_QUALIFIER static bool call(detail::tvec2<T, P> const & v0, detail::tvec2<T, P> const & v1, T const & epsilon) 25 { 26 return length(cross(detail::tvec3<T, P>(v0, static_cast<T>(0)), detail::tvec3<T, P>(v1, static_cast<T>(0)))) < epsilon; 27 } 28 }; 29 30 template <typename T, precision P> 31 struct compute_areCollinear<T, P, tvec3> 32 { 33 GLM_FUNC_QUALIFIER static bool call(detail::tvec3<T, P> const & v0, detail::tvec3<T, P> const & v1, T const & epsilon) 34 { 35 return length(cross(v0, v1)) < epsilon; 36 } 37 }; 38 39 template <typename T, precision P> 40 struct compute_areCollinear<T, P, tvec4> 41 { 42 GLM_FUNC_QUALIFIER static bool call(detail::tvec4<T, P> const & v0, detail::tvec4<T, P> const & v1, T const & epsilon) 43 { 44 return length(cross(detail::tvec3<T, P>(v0), detail::tvec3<T, P>(v1))) < epsilon; 45 } 46 }; 47 48 template <typename T, precision P, template <typename, precision> class vecType> 49 struct compute_isCompNull{}; 50 51 template <typename T, precision P> 52 struct compute_isCompNull<T, P, tvec2> 53 { 54 GLM_FUNC_QUALIFIER static detail::tvec2<bool, P> call(detail::tvec2<T, P> const & v, T const & epsilon) 55 { 56 return detail::tvec2<bool, P>( 57 (abs(v.x) < epsilon), 58 (abs(v.y) < epsilon)); 59 } 60 }; 61 62 template <typename T, precision P> 63 struct compute_isCompNull<T, P, tvec3> 64 { 65 GLM_FUNC_QUALIFIER static detail::tvec3<bool, P> call(detail::tvec3<T, P> const & v, T const & epsilon) 66 { 67 return detail::tvec3<bool, P>( 68 (abs(v.x) < epsilon), 69 (abs(v.y) < epsilon), 70 (abs(v.z) < epsilon)); 71 } 72 }; 73 74 template <typename T, precision P> 75 struct compute_isCompNull<T, P, tvec4> 76 { 77 GLM_FUNC_QUALIFIER static detail::tvec4<bool, P> call(detail::tvec4<T, P> const & v, T const & epsilon) 78 { 79 return detail::tvec4<bool, P>( 80 (abs(v.x) < epsilon), 81 (abs(v.y) < epsilon), 82 (abs(v.z) < epsilon), 83 (abs(v.w) < epsilon)); 84 } 85 }; 86 87}//namespace detail 88 89 template <typename T, precision P, template <typename, precision> class vecType> 90 GLM_FUNC_QUALIFIER bool areCollinear 91 ( 92 vecType<T, P> const & v0, 93 vecType<T, P> const & v1, 94 T const & epsilon 95 ) 96 { 97 GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'areCollinear' only accept floating-point inputs"); 98 99 return detail::compute_areCollinear<T, P, vecType>::call(v0, v1, epsilon); 100 } 101 102 template <typename T, precision P, template <typename, precision> class vecType> 103 GLM_FUNC_QUALIFIER bool areOrthogonal 104 ( 105 vecType<T, P> const & v0, 106 vecType<T, P> const & v1, 107 T const & epsilon 108 ) 109 { 110 GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'areOrthogonal' only accept floating-point inputs"); 111 112 return abs(dot(v0, v1)) <= max( 113 static_cast<T>(1), 114 length(v0)) * max(static_cast<T>(1), length(v1)) * epsilon; 115 } 116 117 template <typename T, precision P, template <typename, precision> class vecType> 118 GLM_FUNC_QUALIFIER bool isNormalized 119 ( 120 vecType<T, P> const & v, 121 T const & epsilon 122 ) 123 { 124 GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isNormalized' only accept floating-point inputs"); 125 126 return abs(length(v) - static_cast<T>(1)) <= static_cast<T>(2) * epsilon; 127 } 128 129 template <typename T, precision P, template <typename, precision> class vecType> 130 GLM_FUNC_QUALIFIER bool isNull 131 ( 132 vecType<T, P> const & v, 133 T const & epsilon 134 ) 135 { 136 GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isNull' only accept floating-point inputs"); 137 138 return length(v) <= epsilon; 139 } 140 141 template <typename T, precision P, template <typename, precision> class vecType> 142 GLM_FUNC_QUALIFIER vecType<bool, P> isCompNull 143 ( 144 vecType<T, P> const & v, 145 T const & epsilon 146 ) 147 { 148 GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isCompNull' only accept floating-point inputs"); 149 150 return detail::compute_isCompNull<T, P, vecType>::call(v, epsilon); 151 } 152 153 template <typename T, precision P> 154 GLM_FUNC_QUALIFIER detail::tvec2<bool, P> isCompNull 155 ( 156 detail::tvec2<T, P> const & v, 157 T const & epsilon) 158 { 159 return detail::tvec2<bool, P>( 160 abs(v.x) < epsilon, 161 abs(v.y) < epsilon); 162 } 163 164 template <typename T, precision P> 165 GLM_FUNC_QUALIFIER detail::tvec3<bool, P> isCompNull 166 ( 167 detail::tvec3<T, P> const & v, 168 T const & epsilon 169 ) 170 { 171 return detail::tvec3<bool, P>( 172 abs(v.x) < epsilon, 173 abs(v.y) < epsilon, 174 abs(v.z) < epsilon); 175 } 176 177 template <typename T, precision P> 178 GLM_FUNC_QUALIFIER detail::tvec4<bool, P> isCompNull 179 ( 180 detail::tvec4<T, P> const & v, 181 T const & epsilon 182 ) 183 { 184 return detail::tvec4<bool, P>( 185 abs(v.x) < epsilon, 186 abs(v.y) < epsilon, 187 abs(v.z) < epsilon, 188 abs(v.w) < epsilon); 189 } 190 191 template <typename T, precision P, template <typename, precision> class vecType> 192 GLM_FUNC_QUALIFIER bool areOrthonormal 193 ( 194 vecType<T, P> const & v0, 195 vecType<T, P> const & v1, 196 T const & epsilon 197 ) 198 { 199 return isNormalized(v0, epsilon) && isNormalized(v1, epsilon) && (abs(dot(v0, v1)) <= epsilon); 200 } 201 202}//namespace glm 203