You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

321 lines
8.4 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////
  2. /// OpenGL Mathematics (glm.g-truc.net)
  3. ///
  4. /// Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net)
  5. /// Permission is hereby granted, free of charge, to any person obtaining a copy
  6. /// of this software and associated documentation files (the "Software"), to deal
  7. /// in the Software without restriction, including without limitation the rights
  8. /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. /// copies of the Software, and to permit persons to whom the Software is
  10. /// furnished to do so, subject to the following conditions:
  11. ///
  12. /// The above copyright notice and this permission notice shall be included in
  13. /// all copies or substantial portions of the Software.
  14. ///
  15. /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. /// THE SOFTWARE.
  22. ///
  23. /// @ref core
  24. /// @file glm/core/func_geometric.inl
  25. /// @date 2008-08-03 / 2011-06-15
  26. /// @author Christophe Riccio
  27. ///////////////////////////////////////////////////////////////////////////////////
  28. namespace glm
  29. {
  30. // length
  31. template <typename genType>
  32. GLM_FUNC_QUALIFIER genType length
  33. (
  34. genType const & x
  35. )
  36. {
  37. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'length' only accept floating-point inputs");
  38. genType sqr = x * x;
  39. return sqrt(sqr);
  40. }
  41. template <typename T>
  42. GLM_FUNC_QUALIFIER typename detail::tvec2<T>::value_type length
  43. (
  44. detail::tvec2<T> const & v
  45. )
  46. {
  47. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'length' only accept floating-point inputs");
  48. typename detail::tvec2<T>::value_type sqr = v.x * v.x + v.y * v.y;
  49. return sqrt(sqr);
  50. }
  51. template <typename T>
  52. GLM_FUNC_QUALIFIER typename detail::tvec3<T>::value_type length
  53. (
  54. detail::tvec3<T> const & v
  55. )
  56. {
  57. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'length' only accept floating-point inputs");
  58. typename detail::tvec3<T>::value_type sqr = v.x * v.x + v.y * v.y + v.z * v.z;
  59. return sqrt(sqr);
  60. }
  61. template <typename T>
  62. GLM_FUNC_QUALIFIER typename detail::tvec4<T>::value_type length
  63. (
  64. detail::tvec4<T> const & v
  65. )
  66. {
  67. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'length' only accept floating-point inputs");
  68. typename detail::tvec4<T>::value_type sqr = v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w;
  69. return sqrt(sqr);
  70. }
  71. // distance
  72. template <typename genType>
  73. GLM_FUNC_QUALIFIER genType distance
  74. (
  75. genType const & p0,
  76. genType const & p1
  77. )
  78. {
  79. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'distance' only accept floating-point inputs");
  80. return length(p1 - p0);
  81. }
  82. template <typename T>
  83. GLM_FUNC_QUALIFIER typename detail::tvec2<T>::value_type distance
  84. (
  85. detail::tvec2<T> const & p0,
  86. detail::tvec2<T> const & p1
  87. )
  88. {
  89. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'distance' only accept floating-point inputs");
  90. return length(p1 - p0);
  91. }
  92. template <typename T>
  93. GLM_FUNC_QUALIFIER typename detail::tvec3<T>::value_type distance
  94. (
  95. detail::tvec3<T> const & p0,
  96. detail::tvec3<T> const & p1
  97. )
  98. {
  99. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'distance' only accept floating-point inputs");
  100. return length(p1 - p0);
  101. }
  102. template <typename T>
  103. GLM_FUNC_QUALIFIER typename detail::tvec4<T>::value_type distance
  104. (
  105. detail::tvec4<T> const & p0,
  106. detail::tvec4<T> const & p1
  107. )
  108. {
  109. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'distance' only accept floating-point inputs");
  110. return length(p1 - p0);
  111. }
  112. // dot
  113. template <typename genType>
  114. GLM_FUNC_QUALIFIER genType dot
  115. (
  116. genType const & x,
  117. genType const & y
  118. )
  119. {
  120. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'dot' only accept floating-point inputs");
  121. return x * y;
  122. }
  123. template <typename T>
  124. GLM_FUNC_QUALIFIER typename detail::tvec2<T>::value_type dot
  125. (
  126. detail::tvec2<T> const & x,
  127. detail::tvec2<T> const & y
  128. )
  129. {
  130. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'dot' only accept floating-point inputs");
  131. return x.x * y.x + x.y * y.y;
  132. }
  133. template <typename T>
  134. GLM_FUNC_QUALIFIER T dot
  135. (
  136. detail::tvec3<T> const & x,
  137. detail::tvec3<T> const & y
  138. )
  139. {
  140. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'dot' only accept floating-point inputs");
  141. return x.x * y.x + x.y * y.y + x.z * y.z;
  142. }
  143. /* // SSE3
  144. GLM_FUNC_QUALIFIER float dot(const tvec4<float>& x, const tvec4<float>& y)
  145. {
  146. float Result;
  147. __asm
  148. {
  149. mov esi, x
  150. mov edi, y
  151. movaps xmm0, [esi]
  152. mulps xmm0, [edi]
  153. haddps( _xmm0, _xmm0 )
  154. haddps( _xmm0, _xmm0 )
  155. movss Result, xmm0
  156. }
  157. return Result;
  158. }
  159. */
  160. template <typename T>
  161. GLM_FUNC_QUALIFIER T dot
  162. (
  163. detail::tvec4<T> const & x,
  164. detail::tvec4<T> const & y
  165. )
  166. {
  167. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'dot' only accept floating-point inputs");
  168. return x.x * y.x + x.y * y.y + x.z * y.z + x.w * y.w;
  169. }
  170. // cross
  171. template <typename T>
  172. GLM_FUNC_QUALIFIER detail::tvec3<T> cross
  173. (
  174. detail::tvec3<T> const & x,
  175. detail::tvec3<T> const & y
  176. )
  177. {
  178. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'cross' only accept floating-point inputs");
  179. return detail::tvec3<T>(
  180. x.y * y.z - y.y * x.z,
  181. x.z * y.x - y.z * x.x,
  182. x.x * y.y - y.x * x.y);
  183. }
  184. // normalize
  185. template <typename genType>
  186. GLM_FUNC_QUALIFIER genType normalize
  187. (
  188. genType const & x
  189. )
  190. {
  191. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'normalize' only accept floating-point inputs");
  192. return x < genType(0) ? genType(-1) : genType(1);
  193. }
  194. // According to issue 10 GLSL 1.10 specification, if length(x) == 0 then result is undefine and generate an error
  195. template <typename T>
  196. GLM_FUNC_QUALIFIER detail::tvec2<T> normalize
  197. (
  198. detail::tvec2<T> const & x
  199. )
  200. {
  201. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'normalize' only accept floating-point inputs");
  202. typename detail::tvec2<T>::value_type sqr = x.x * x.x + x.y * x.y;
  203. return x * inversesqrt(sqr);
  204. }
  205. template <typename T>
  206. GLM_FUNC_QUALIFIER detail::tvec3<T> normalize
  207. (
  208. detail::tvec3<T> const & x
  209. )
  210. {
  211. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'normalize' only accept floating-point inputs");
  212. typename detail::tvec3<T>::value_type sqr = x.x * x.x + x.y * x.y + x.z * x.z;
  213. return x * inversesqrt(sqr);
  214. }
  215. template <typename T>
  216. GLM_FUNC_QUALIFIER detail::tvec4<T> normalize
  217. (
  218. detail::tvec4<T> const & x
  219. )
  220. {
  221. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'normalize' only accept floating-point inputs");
  222. typename detail::tvec4<T>::value_type sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
  223. return x * inversesqrt(sqr);
  224. }
  225. // faceforward
  226. template <typename genType>
  227. GLM_FUNC_QUALIFIER genType faceforward
  228. (
  229. genType const & N,
  230. genType const & I,
  231. genType const & Nref
  232. )
  233. {
  234. return dot(Nref, I) < 0 ? N : -N;
  235. }
  236. // reflect
  237. template <typename genType>
  238. GLM_FUNC_QUALIFIER genType reflect
  239. (
  240. genType const & I,
  241. genType const & N
  242. )
  243. {
  244. return I - N * dot(N, I) * genType(2);
  245. }
  246. // refract
  247. template <typename genType>
  248. GLM_FUNC_QUALIFIER genType refract
  249. (
  250. genType const & I,
  251. genType const & N,
  252. genType const & eta
  253. )
  254. {
  255. //It could be a vector
  256. //GLM_STATIC_ASSERT(detail::type<genType>::is_float);
  257. genType dotValue = dot(N, I);
  258. genType k = genType(1) - eta * eta * (genType(1) - dotValue * dotValue);
  259. if(k < genType(0))
  260. return genType(0);
  261. else
  262. return eta * I - (eta * dotValue + sqrt(k)) * N;
  263. }
  264. template <typename genType>
  265. GLM_FUNC_QUALIFIER genType refract
  266. (
  267. genType const & I,
  268. genType const & N,
  269. typename genType::value_type const & eta
  270. )
  271. {
  272. //It could be a vector
  273. //GLM_STATIC_ASSERT(detail::type<genType>::is_float);
  274. typename genType::value_type dotValue = dot(N, I);
  275. typename genType::value_type k = typename genType::value_type(1) - eta * eta * (typename genType::value_type(1) - dotValue * dotValue);
  276. if(k < typename genType::value_type(0))
  277. return genType(0);
  278. else
  279. return eta * I - (eta * dotValue + sqrt(k)) * N;
  280. }
  281. }//namespace glm