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.

196 lines
6.3 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////////////////////
  2. // OpenGL Mathematics Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net)
  3. ///////////////////////////////////////////////////////////////////////////////////////////////////
  4. // Created : 2007-04-03
  5. // Updated : 2009-01-20
  6. // Licence : This source is under MIT licence
  7. // File : glm/gtx/intersect.inl
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////
  9. #include <cfloat>
  10. #include <limits>
  11. namespace glm
  12. {
  13. template <typename genType>
  14. GLM_FUNC_QUALIFIER bool intersectRayTriangle
  15. (
  16. genType const & orig, genType const & dir,
  17. genType const & v0, genType const & v1, genType const & v2,
  18. genType & baryPosition
  19. )
  20. {
  21. genType e1 = v1 - v0;
  22. genType e2 = v2 - v0;
  23. genType p = glm::cross(dir, e2);
  24. typename genType::value_type a = glm::dot(e1, p);
  25. typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
  26. if(a < Epsilon)
  27. return false;
  28. typename genType::value_type f = typename genType::value_type(1.0f) / a;
  29. genType s = orig - v0;
  30. baryPosition.x = f * glm::dot(s, p);
  31. if(baryPosition.x < typename genType::value_type(0.0f))
  32. return false;
  33. if(baryPosition.x > typename genType::value_type(1.0f))
  34. return false;
  35. genType q = glm::cross(s, e1);
  36. baryPosition.y = f * glm::dot(dir, q);
  37. if(baryPosition.y < typename genType::value_type(0.0f))
  38. return false;
  39. if(baryPosition.y + baryPosition.x > typename genType::value_type(1.0f))
  40. return false;
  41. baryPosition.z = f * glm::dot(e2, q);
  42. return baryPosition.z >= typename genType::value_type(0.0f);
  43. }
  44. //template <typename genType>
  45. //GLM_FUNC_QUALIFIER bool intersectRayTriangle
  46. //(
  47. // genType const & orig, genType const & dir,
  48. // genType const & vert0, genType const & vert1, genType const & vert2,
  49. // genType & position
  50. //)
  51. //{
  52. // typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
  53. //
  54. // genType edge1 = vert1 - vert0;
  55. // genType edge2 = vert2 - vert0;
  56. //
  57. // genType pvec = cross(dir, edge2);
  58. //
  59. // float det = dot(edge1, pvec);
  60. // if(det < Epsilon)
  61. // return false;
  62. //
  63. // genType tvec = orig - vert0;
  64. //
  65. // position.y = dot(tvec, pvec);
  66. // if (position.y < typename genType::value_type(0) || position.y > det)
  67. // return typename genType::value_type(0);
  68. //
  69. // genType qvec = cross(tvec, edge1);
  70. //
  71. // position.z = dot(dir, qvec);
  72. // if (position.z < typename genType::value_type(0) || position.y + position.z > det)
  73. // return typename genType::value_type(0);
  74. //
  75. // position.x = dot(edge2, qvec);
  76. // position *= typename genType::value_type(1) / det;
  77. //
  78. // return typename genType::value_type(1);
  79. //}
  80. template <typename genType>
  81. GLM_FUNC_QUALIFIER bool intersectLineTriangle
  82. (
  83. genType const & orig, genType const & dir,
  84. genType const & vert0, genType const & vert1, genType const & vert2,
  85. genType & position
  86. )
  87. {
  88. typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
  89. genType edge1 = vert1 - vert0;
  90. genType edge2 = vert2 - vert0;
  91. genType pvec = cross(dir, edge2);
  92. float det = dot(edge1, pvec);
  93. if (det > -Epsilon && det < Epsilon)
  94. return false;
  95. float inv_det = typename genType::value_type(1) / det;
  96. genType tvec = orig - vert0;
  97. position.y = dot(tvec, pvec) * inv_det;
  98. if (position.y < typename genType::value_type(0) || position.y > typename genType::value_type(1))
  99. return false;
  100. genType qvec = cross(tvec, edge1);
  101. position.z = dot(dir, qvec) * inv_det;
  102. if (position.z < typename genType::value_type(0) || position.y + position.z > typename genType::value_type(1))
  103. return false;
  104. position.x = dot(edge2, qvec) * inv_det;
  105. return true;
  106. }
  107. template <typename genType>
  108. GLM_FUNC_QUALIFIER bool intersectRaySphere
  109. (
  110. genType const & rayStarting, genType const & rayNormalizedDirection,
  111. genType const & sphereCenter, const typename genType::value_type sphereRadiusSquered,
  112. typename genType::value_type & intersectionDistance
  113. )
  114. {
  115. typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
  116. genType diff = sphereCenter - rayStarting;
  117. typename genType::value_type t0 = dot(diff, rayNormalizedDirection);
  118. typename genType::value_type dSquared = dot(diff, diff) - t0 * t0;
  119. if( dSquared > sphereRadiusSquered )
  120. {
  121. return false;
  122. }
  123. typename genType::value_type t1 = sqrt( sphereRadiusSquered - dSquared );
  124. intersectionDistance = t0 > t1 + Epsilon ? t0 - t1 : t0 + t1;
  125. return intersectionDistance > Epsilon;
  126. }
  127. template <typename genType>
  128. GLM_FUNC_QUALIFIER bool intersectRaySphere
  129. (
  130. genType const & rayStarting, genType const & rayNormalizedDirection,
  131. genType const & sphereCenter, const typename genType::value_type sphereRadius,
  132. genType & intersectionPosition, genType & intersectionNormal
  133. )
  134. {
  135. typename genType::value_type distance;
  136. if( intersectRaySphere( rayStarting, rayNormalizedDirection, sphereCenter, sphereRadius * sphereRadius, distance ) )
  137. {
  138. intersectionPosition = rayStarting + rayNormalizedDirection * distance;
  139. intersectionNormal = (intersectionPosition - sphereCenter) / sphereRadius;
  140. return true;
  141. }
  142. return false;
  143. }
  144. template <typename genType>
  145. GLM_FUNC_QUALIFIER bool intersectLineSphere
  146. (
  147. genType const & point0, genType const & point1,
  148. genType const & sphereCenter, typename genType::value_type sphereRadius,
  149. genType & intersectionPoint1, genType & intersectionNormal1,
  150. genType & intersectionPoint2, genType & intersectionNormal2
  151. )
  152. {
  153. typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
  154. genType dir = normalize(point1 - point0);
  155. genType diff = sphereCenter - point0;
  156. typename genType::value_type t0 = dot(diff, dir);
  157. typename genType::value_type dSquared = dot(diff, diff) - t0 * t0;
  158. if( dSquared > sphereRadius * sphereRadius )
  159. {
  160. return false;
  161. }
  162. typename genType::value_type t1 = sqrt( sphereRadius * sphereRadius - dSquared );
  163. if( t0 < t1 + Epsilon )
  164. t1 = -t1;
  165. intersectionPoint1 = point0 + dir * (t0 - t1);
  166. intersectionNormal1 = (intersectionPoint1 - sphereCenter) / sphereRadius;
  167. intersectionPoint2 = point0 + dir * (t0 + t1);
  168. intersectionNormal2 = (intersectionPoint2 - sphereCenter) / sphereRadius;
  169. return true;
  170. }
  171. }//namespace glm