Collection of DPF-based plugins for packaging
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.

226 lines
6.9KB

  1. /// @ref gtx_intersect
  2. /// @file glm/gtx/intersect.inl
  3. namespace glm
  4. {
  5. template<typename genType>
  6. GLM_FUNC_QUALIFIER bool intersectRayPlane
  7. (
  8. genType const& orig, genType const& dir,
  9. genType const& planeOrig, genType const& planeNormal,
  10. typename genType::value_type & intersectionDistance
  11. )
  12. {
  13. typename genType::value_type d = glm::dot(dir, planeNormal);
  14. typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
  15. if(d < -Epsilon)
  16. {
  17. intersectionDistance = glm::dot(planeOrig - orig, planeNormal) / d;
  18. return true;
  19. }
  20. return false;
  21. }
  22. template<typename T, qualifier Q>
  23. GLM_FUNC_QUALIFIER bool intersectRayTriangle
  24. (
  25. vec<3, T, Q> const& orig, vec<3, T, Q> const& dir,
  26. vec<3, T, Q> const& vert0, vec<3, T, Q> const& vert1, vec<3, T, Q> const& vert2,
  27. vec<2, T, Q>& baryPosition, T& distance
  28. )
  29. {
  30. // find vectors for two edges sharing vert0
  31. vec<3, T, Q> const edge1 = vert1 - vert0;
  32. vec<3, T, Q> const edge2 = vert2 - vert0;
  33. // begin calculating determinant - also used to calculate U parameter
  34. vec<3, T, Q> const p = glm::cross(dir, edge2);
  35. // if determinant is near zero, ray lies in plane of triangle
  36. T const det = glm::dot(edge1, p);
  37. vec<3, T, Q> qvec;
  38. if(det > std::numeric_limits<T>::epsilon())
  39. {
  40. // calculate distance from vert0 to ray origin
  41. vec<3, T, Q> const tvec = orig - vert0;
  42. // calculate U parameter and test bounds
  43. baryPosition.x = glm::dot(tvec, p);
  44. if(baryPosition.x < static_cast<T>(0) || baryPosition.x > det)
  45. return false;
  46. // prepare to test V parameter
  47. qvec = glm::cross(tvec, edge1);
  48. // calculate V parameter and test bounds
  49. baryPosition.y = glm::dot(dir, qvec);
  50. if((baryPosition.y < static_cast<T>(0)) || ((baryPosition.x + baryPosition.y) > det))
  51. return false;
  52. }
  53. else if(det < -std::numeric_limits<T>::epsilon())
  54. {
  55. // calculate distance from vert0 to ray origin
  56. vec<3, T, Q> const tvec = orig - vert0;
  57. // calculate U parameter and test bounds
  58. baryPosition.x = glm::dot(tvec, p);
  59. if((baryPosition.x > static_cast<T>(0)) || (baryPosition.x < det))
  60. return false;
  61. // prepare to test V parameter
  62. qvec = glm::cross(tvec, edge1);
  63. // calculate V parameter and test bounds
  64. baryPosition.y = glm::dot(dir, qvec);
  65. if((baryPosition.y > static_cast<T>(0)) || (baryPosition.x + baryPosition.y < det))
  66. return false;
  67. }
  68. else
  69. return false; // ray is parallel to the plane of the triangle
  70. T inv_det = static_cast<T>(1) / det;
  71. // calculate distance, ray intersects triangle
  72. distance = glm::dot(edge2, qvec) * inv_det;
  73. baryPosition *= inv_det;
  74. return true;
  75. }
  76. /*
  77. typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
  78. if(a < Epsilon && a > -Epsilon)
  79. return false;
  80. typename genType::value_type f = typename genType::value_type(1.0f) / a;
  81. genType s = orig - v0;
  82. baryPosition.x = f * glm::dot(s, p);
  83. if(baryPosition.x < typename genType::value_type(0.0f))
  84. return false;
  85. if(baryPosition.x > typename genType::value_type(1.0f))
  86. return false;
  87. genType q = glm::cross(s, e1);
  88. baryPosition.y = f * glm::dot(dir, q);
  89. if(baryPosition.y < typename genType::value_type(0.0f))
  90. return false;
  91. if(baryPosition.y + baryPosition.x > typename genType::value_type(1.0f))
  92. return false;
  93. baryPosition.z = f * glm::dot(e2, q);
  94. return baryPosition.z >= typename genType::value_type(0.0f);
  95. }
  96. */
  97. template<typename genType>
  98. GLM_FUNC_QUALIFIER bool intersectLineTriangle
  99. (
  100. genType const& orig, genType const& dir,
  101. genType const& vert0, genType const& vert1, genType const& vert2,
  102. genType & position
  103. )
  104. {
  105. typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
  106. genType edge1 = vert1 - vert0;
  107. genType edge2 = vert2 - vert0;
  108. genType pvec = cross(dir, edge2);
  109. float det = dot(edge1, pvec);
  110. if (det > -Epsilon && det < Epsilon)
  111. return false;
  112. float inv_det = typename genType::value_type(1) / det;
  113. genType tvec = orig - vert0;
  114. position.y = dot(tvec, pvec) * inv_det;
  115. if (position.y < typename genType::value_type(0) || position.y > typename genType::value_type(1))
  116. return false;
  117. genType qvec = cross(tvec, edge1);
  118. position.z = dot(dir, qvec) * inv_det;
  119. if (position.z < typename genType::value_type(0) || position.y + position.z > typename genType::value_type(1))
  120. return false;
  121. position.x = dot(edge2, qvec) * inv_det;
  122. return true;
  123. }
  124. template<typename genType>
  125. GLM_FUNC_QUALIFIER bool intersectRaySphere
  126. (
  127. genType const& rayStarting, genType const& rayNormalizedDirection,
  128. genType const& sphereCenter, const typename genType::value_type sphereRadiusSquered,
  129. typename genType::value_type & intersectionDistance
  130. )
  131. {
  132. typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
  133. genType diff = sphereCenter - rayStarting;
  134. typename genType::value_type t0 = dot(diff, rayNormalizedDirection);
  135. typename genType::value_type dSquared = dot(diff, diff) - t0 * t0;
  136. if( dSquared > sphereRadiusSquered )
  137. {
  138. return false;
  139. }
  140. typename genType::value_type t1 = sqrt( sphereRadiusSquered - dSquared );
  141. intersectionDistance = t0 > t1 + Epsilon ? t0 - t1 : t0 + t1;
  142. return intersectionDistance > Epsilon;
  143. }
  144. template<typename genType>
  145. GLM_FUNC_QUALIFIER bool intersectRaySphere
  146. (
  147. genType const& rayStarting, genType const& rayNormalizedDirection,
  148. genType const& sphereCenter, const typename genType::value_type sphereRadius,
  149. genType & intersectionPosition, genType & intersectionNormal
  150. )
  151. {
  152. typename genType::value_type distance;
  153. if( intersectRaySphere( rayStarting, rayNormalizedDirection, sphereCenter, sphereRadius * sphereRadius, distance ) )
  154. {
  155. intersectionPosition = rayStarting + rayNormalizedDirection * distance;
  156. intersectionNormal = (intersectionPosition - sphereCenter) / sphereRadius;
  157. return true;
  158. }
  159. return false;
  160. }
  161. template<typename genType>
  162. GLM_FUNC_QUALIFIER bool intersectLineSphere
  163. (
  164. genType const& point0, genType const& point1,
  165. genType const& sphereCenter, typename genType::value_type sphereRadius,
  166. genType & intersectionPoint1, genType & intersectionNormal1,
  167. genType & intersectionPoint2, genType & intersectionNormal2
  168. )
  169. {
  170. typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
  171. genType dir = normalize(point1 - point0);
  172. genType diff = sphereCenter - point0;
  173. typename genType::value_type t0 = dot(diff, dir);
  174. typename genType::value_type dSquared = dot(diff, diff) - t0 * t0;
  175. if( dSquared > sphereRadius * sphereRadius )
  176. {
  177. return false;
  178. }
  179. typename genType::value_type t1 = sqrt( sphereRadius * sphereRadius - dSquared );
  180. if( t0 < t1 + Epsilon )
  181. t1 = -t1;
  182. intersectionPoint1 = point0 + dir * (t0 - t1);
  183. intersectionNormal1 = (intersectionPoint1 - sphereCenter) / sphereRadius;
  184. intersectionPoint2 = point0 + dir * (t0 + t1);
  185. intersectionNormal2 = (intersectionPoint2 - sphereCenter) / sphereRadius;
  186. return true;
  187. }
  188. }//namespace glm