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