mirror of
https://github.com/g-truc/glm.git
synced 2024-11-16 06:44:35 +00:00
Added intersectLineQuad and fastIntersectLineQuad
This commit is contained in:
parent
31fef4819b
commit
ed98125fc0
@ -103,7 +103,7 @@ namespace glm
|
|||||||
genType & intersectionPosition1, genType & intersectionNormal1,
|
genType & intersectionPosition1, genType & intersectionNormal1,
|
||||||
genType & intersectionPosition2 = genType(), genType & intersectionNormal2 = genType());
|
genType & intersectionPosition2 = genType(), genType & intersectionNormal2 = genType());
|
||||||
|
|
||||||
//! Compute the intersection of a line and a non-degenerate quadrilateral.
|
//! Compute the intersection of a ray and a non-degenerate quadrilateral.
|
||||||
//! From the GLM_GTX_intersect extension
|
//! From the GLM_GTX_intersect extension
|
||||||
template <typename genType>
|
template <typename genType>
|
||||||
GLM_FUNC_DECL bool intersectRayQuad(
|
GLM_FUNC_DECL bool intersectRayQuad(
|
||||||
@ -112,13 +112,32 @@ namespace glm
|
|||||||
genType & bilinearCoordinates
|
genType & bilinearCoordinates
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//! Compute the intersection of a ray and a non-degenerate quadrilateral.
|
||||||
|
//! Does not compute the bilinear coordinates of the intersection.
|
||||||
|
//! From the GLM_GTX_intersect extension
|
||||||
|
template<typename genType>
|
||||||
|
GLM_FUNC_DECL bool fastIntersectRayQuad(
|
||||||
|
genType const & orig, genType const & dir,
|
||||||
|
genType const & v00, genType const & v10, genType const & v11, genType const & v01
|
||||||
|
);
|
||||||
|
|
||||||
|
//! Compute the intersection of a line and a non-degenerate quadrilateral.
|
||||||
|
//! From the GLM_GTX_intersect extension
|
||||||
|
template<typename genType>
|
||||||
|
GLM_FUNC_DECL bool intersectLineQuad(
|
||||||
|
genType const & orig, genType const & dir,
|
||||||
|
genType const & v00, genType const & v10, genType const & v11, genType const & v01,
|
||||||
|
genType & bilinearCoordinates
|
||||||
|
);
|
||||||
|
|
||||||
//! Compute the intersection of a line and a non-degenerate quadrilateral.
|
//! Compute the intersection of a line and a non-degenerate quadrilateral.
|
||||||
//! Does not compute the bilinear coordinates of the intersection.
|
//! Does not compute the bilinear coordinates of the intersection.
|
||||||
//! From the GLM_GTX_intersect extension
|
//! From the GLM_GTX_intersect extension
|
||||||
template<typename genType>
|
template<typename genType>
|
||||||
GLM_FUNC_DECL bool fastIntersectRayQuad(
|
GLM_FUNC_DECL bool fastIntersectLineQuad(
|
||||||
genType const & orig, genType const & dir,
|
genType const & orig, genType const & dir,
|
||||||
genType const & v00, genType const & v10, genType const & v11, genType const & v01
|
genType const & v00, genType const & v10, genType const & v11, genType const & v01
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
@ -449,6 +449,232 @@ namespace glm
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
GLM_FUNC_QUALIFIER bool intersectLineQuad
|
||||||
|
(
|
||||||
|
genType const & orig, genType const & dir,
|
||||||
|
genType const & v00, genType const & v10, genType const & v11, genType const & v01,
|
||||||
|
genType & bilinearCoordinates
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Epsilon to reject parallell lines
|
||||||
|
typename genType::value_type epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
|
||||||
|
|
||||||
|
// Calculate edges and normal of first triangle
|
||||||
|
genType e01 = v10 - v00;
|
||||||
|
genType e03 = v01 - v00;
|
||||||
|
|
||||||
|
genType p = glm::cross(dir, e03);
|
||||||
|
|
||||||
|
typename genType::value_type det = glm::dot(e01, p);
|
||||||
|
|
||||||
|
// Reject rays orthagonal to the normal vector. I.e. rays parallell to the plane.
|
||||||
|
if(det < epsilon && det > -epsilon)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
typename genType::value_type inv_det = typename genType::value_type(1.0f)/det;
|
||||||
|
|
||||||
|
genType s = orig - v00;
|
||||||
|
|
||||||
|
// Calculate the barycentric alpha coordinate of the first triangle
|
||||||
|
typename genType::value_type alpha = inv_det * glm::dot(s, p);
|
||||||
|
|
||||||
|
// It lies outside the triangle
|
||||||
|
if(alpha > typename genType::value_type(1.0f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(alpha < typename genType::value_type(0.0f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Vector perpendicular to T and e01
|
||||||
|
genType q = glm::cross(s, e01);
|
||||||
|
|
||||||
|
// Calculate barycentric beta coordinate of the first triangle
|
||||||
|
typename genType::value_type beta = inv_det * glm::dot(dir, q);
|
||||||
|
|
||||||
|
if(beta > typename genType::value_type(1.0f))
|
||||||
|
return false;
|
||||||
|
if(beta < typename genType::value_type(0.0f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bilinearCoordinates.z = inv_det * glm::dot(e03, q);
|
||||||
|
|
||||||
|
if(alpha + beta > typename genType::value_type(1.0f)){
|
||||||
|
// Do exactly the same for the second triangle
|
||||||
|
|
||||||
|
genType e23 = v01 - v11;
|
||||||
|
genType e21 = v10 - v11;
|
||||||
|
|
||||||
|
p = glm::cross(dir, e21);
|
||||||
|
|
||||||
|
det = glm::dot(e23, p);
|
||||||
|
|
||||||
|
if(det < epsilon && det > -epsilon)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
inv_det = typename genType::value_type(1.0f)/det;
|
||||||
|
s = orig - v11;
|
||||||
|
|
||||||
|
alpha = inv_det * glm::dot(s, p);
|
||||||
|
|
||||||
|
if(alpha < typename genType::value_type(0.0f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
q = glm::cross(s, e23);
|
||||||
|
beta = inv_det * glm::dot(dir, q);
|
||||||
|
|
||||||
|
if(beta < typename genType::value_type(0.0f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// This to support degenerate squares
|
||||||
|
if(beta + alpha > typename genType::value_type(1.0f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bilinearCoordinates.z = inv_det * glm::dot(e21, q);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute barycentric coordinates of v11
|
||||||
|
genType e02 = v11 - v00;
|
||||||
|
genType N = glm::cross(e01, e03);
|
||||||
|
|
||||||
|
typename genType::value_type alpha_11, beta_11;
|
||||||
|
|
||||||
|
if(abs(N.x) >= abs(N.y) && abs(N.x) >= abs(N.z)) {
|
||||||
|
alpha_11 = (e02.y * e03.z - e02.z * e03.y) / N.x;
|
||||||
|
beta_11 = (e01.y * e02.z - e01.z * e02.y) / N.x;
|
||||||
|
} else if(abs(N.y) >= abs(N.x) && abs(N.y) >= abs(N.z)) {
|
||||||
|
alpha_11 = (e02.z * e03.x - e02.x * e03.z) / N.x;
|
||||||
|
beta_11 = (e01.z * e02.x - e01.x * e02.z) / N.x;
|
||||||
|
} else {
|
||||||
|
alpha_11 = (e02.x * e03.y - e02.y * e03.x) / N.z;
|
||||||
|
beta_11 = (e01.x * e02.y - e01.y * e02.x) / N.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute bilinear coordinates of the intersection point
|
||||||
|
if(abs(alpha_11 - typename genType::value_type(1.0f)) < epsilon) {
|
||||||
|
bilinearCoordinates.x = alpha;
|
||||||
|
|
||||||
|
if(abs(beta_11 - typename genType::value_type(1.0f)) < epsilon){
|
||||||
|
bilinearCoordinates.y = beta;
|
||||||
|
} else {
|
||||||
|
bilinearCoordinates.y = beta/(bilinearCoordinates.x * (beta_11 - typename genType::value_type(1.0f)) + typename genType::value_type(1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(abs(beta_11 - typename genType::value_type(1.0f)) < epsilon) {
|
||||||
|
bilinearCoordinates.y = alpha;
|
||||||
|
bilinearCoordinates.x = alpha/(bilinearCoordinates.y*(alpha_11 - typename genType::value_type(1.0f)) + typename genType::value_type(1.0f));
|
||||||
|
} else {
|
||||||
|
typename genType::value_type a, b, c, discr, q;
|
||||||
|
|
||||||
|
a = -(beta_11 - typename genType::value_type(1.0f));
|
||||||
|
b = alpha*(beta_11 - 1) - beta*(alpha_11 - typename genType::value_type(1.0f)) - typename genType::value_type(1.0f);
|
||||||
|
c = alpha;
|
||||||
|
|
||||||
|
discr = b*b - typename genType::value_type(4.0f)*a*c;
|
||||||
|
|
||||||
|
// Get sign of b
|
||||||
|
typename genType::value_type sign = (typename genType::value_type(0) < b) - (b < typename genType::value_type(0));
|
||||||
|
|
||||||
|
q = -(typename genType::value_type(0.5f)) * (b + sign*glm::fastSqrt(discr));
|
||||||
|
|
||||||
|
bilinearCoordinates.x = q/a;
|
||||||
|
|
||||||
|
if(bilinearCoordinates.x < 0 || bilinearCoordinates.y > 1){
|
||||||
|
bilinearCoordinates.x = c/q;
|
||||||
|
}
|
||||||
|
|
||||||
|
bilinearCoordinates.y = beta/(bilinearCoordinates.x*(beta_11 - 1) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename genType>
|
||||||
|
GLM_FUNC_QUALIFIER bool fastIntersectLineQuad
|
||||||
|
(
|
||||||
|
genType const & orig, genType const & dir,
|
||||||
|
genType const & v00, genType const & v10, genType const & v11, genType const & v01
|
||||||
|
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Epsilon to reject parallell lines
|
||||||
|
typename genType::value_type epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
|
||||||
|
|
||||||
|
// Calculate edges and normal of first triangle
|
||||||
|
genType e01 = v10 - v00;
|
||||||
|
genType e03 = v01 - v00;
|
||||||
|
|
||||||
|
genType p = glm::cross(dir, e03);
|
||||||
|
|
||||||
|
typename genType::value_type det = glm::dot(e01, p);
|
||||||
|
|
||||||
|
// Reject rays orthagonal to the normal vector. I.e. rays parallell to the plane.
|
||||||
|
if(det < epsilon && det > -epsilon)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
typename genType::value_type inv_det = typename genType::value_type(1.0f)/det;
|
||||||
|
|
||||||
|
|
||||||
|
genType s = orig - v00;
|
||||||
|
|
||||||
|
// Calculate the barycentric alpha coordinate of the first triangle
|
||||||
|
typename genType::value_type alpha = inv_det * glm::dot(s, p);
|
||||||
|
|
||||||
|
// It lies outside the triangle
|
||||||
|
if(alpha > typename genType::value_type(1.0f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(alpha < typename genType::value_type(0.0f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Vector perpendicular to T and e01
|
||||||
|
genType q = glm::cross(s, e01);
|
||||||
|
|
||||||
|
// Calculate barycentric beta coordinate of the first triangle
|
||||||
|
typename genType::value_type beta = inv_det * glm::dot(dir, q);
|
||||||
|
|
||||||
|
if(beta > typename genType::value_type(1.0f))
|
||||||
|
return false;
|
||||||
|
if(beta < typename genType::value_type(0.0f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
if(alpha + beta > typename genType::value_type(1.0f)){
|
||||||
|
// Do exactly the same for the second triangle
|
||||||
|
|
||||||
|
genType e23 = v01 - v11;
|
||||||
|
genType e21 = v10 - v11;
|
||||||
|
|
||||||
|
p = glm::cross(dir, e21);
|
||||||
|
|
||||||
|
det = glm::dot(e23, p);
|
||||||
|
|
||||||
|
if(det < epsilon && det > -epsilon)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
inv_det = typename genType::value_type(1.0f)/det;
|
||||||
|
s = orig - v11;
|
||||||
|
|
||||||
|
alpha = inv_det * glm::dot(s, p);
|
||||||
|
|
||||||
|
if(alpha < typename genType::value_type(0.0f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
q = glm::cross(s, e23);
|
||||||
|
beta = inv_det * glm::dot(dir, q);
|
||||||
|
|
||||||
|
if(beta < typename genType::value_type(0.0f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// This to support degenerate squares
|
||||||
|
if(beta + alpha > typename genType::value_type(1.0f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}//namespace glm
|
}//namespace glm
|
||||||
|
Loading…
Reference in New Issue
Block a user