Removed comment lines and replaced duplicate intersectLineQuad with correct intersectRayDegenerateQuad

This commit is contained in:
Tormod Haugland 2014-04-27 09:51:50 +02:00
parent 05865e239b
commit 26f32e6ed6

View File

@ -223,57 +223,40 @@ namespace glm
genType & bilinearCoordinates genType & bilinearCoordinates
) )
{ {
// Epsilon to reject parallell lines
typename genType::value_type epsilon = std::numeric_limits<typename genType::value_type>::epsilon(); 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 e01 = v10 - v00;
genType e03 = v01 - v00; genType e03 = v01 - v00;
genType p = glm::cross(dir, e03); genType p = glm::cross(dir, e03);
typename genType::value_type det = glm::dot(e01, p); 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) if(det < epsilon)
return false; return false;
typename genType::value_type inv_det = typename genType::value_type(1.0f)/det; typename genType::value_type inv_det = typename genType::value_type(1.0f)/det;
genType s = orig - v00; genType s = orig - v00;
// Calculate the barycentric alpha coordinate of the first triangle
typename genType::value_type alpha = inv_det * glm::dot(s, p); typename genType::value_type alpha = inv_det * glm::dot(s, p);
// It lies outside the triangle
if(alpha > typename genType::value_type(1.0f)) if(alpha > typename genType::value_type(1.0f))
return false; return false;
if(alpha < typename genType::value_type(0.0f)) if(alpha < typename genType::value_type(0.0f))
return false; return false;
// Vector perpendicular to T and e01
genType q = glm::cross(s, 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); typename genType::value_type beta = inv_det * glm::dot(dir, q);
if(beta > typename genType::value_type(1.0f)) if(beta > typename genType::value_type(1.0f))
return false; return false;
if(beta < typename genType::value_type(0.0f)) if(beta < typename genType::value_type(0.0f))
return false; return false;
bilinearCoordinates.z = inv_det * glm::dot(e03, q); bilinearCoordinates.z = inv_det * glm::dot(e03, q);
if(alpha + beta > typename genType::value_type(1.0f)){ if(alpha + beta > typename genType::value_type(1.0f)){
// Do exactly the same for the second triangle
genType e23 = v01 - v11; genType e23 = v01 - v11;
genType e21 = v10 - v11; genType e21 = v10 - v11;
p = glm::cross(dir, e21); p = glm::cross(dir, e21);
det = glm::dot(e23, p); det = glm::dot(e23, p);
if(det < epsilon && det > -epsilon) if(det < epsilon && det > -epsilon)
@ -292,8 +275,6 @@ namespace glm
if(beta < typename genType::value_type(0.0f)) if(beta < typename genType::value_type(0.0f))
return false; return false;
// This to support degenerate squares
if(beta + alpha > typename genType::value_type(1.0f)) if(beta + alpha > typename genType::value_type(1.0f))
return false; return false;
@ -304,7 +285,6 @@ namespace glm
if(bilinearCoordinates.z < typename genType::value_type(0.0f)) if(bilinearCoordinates.z < typename genType::value_type(0.0f))
return false; return false;
// Compute barycentric coordinates of v11
genType e02 = v11 - v00; genType e02 = v11 - v00;
genType N = glm::cross(e01, e03); genType N = glm::cross(e01, e03);
@ -321,7 +301,6 @@ namespace glm
beta_11 = (e01.x * e02.y - e01.y * e02.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) { if(abs(alpha_11 - typename genType::value_type(1.0f)) < epsilon) {
bilinearCoordinates.x = alpha; bilinearCoordinates.x = alpha;
@ -330,7 +309,6 @@ namespace glm
} else { } else {
bilinearCoordinates.y = beta/(bilinearCoordinates.x * (beta_11 - typename genType::value_type(1.0f)) + typename genType::value_type(1.0f)); 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) { } else if(abs(beta_11 - typename genType::value_type(1.0f)) < epsilon) {
bilinearCoordinates.y = alpha; bilinearCoordinates.y = alpha;
bilinearCoordinates.x = alpha/(bilinearCoordinates.y*(alpha_11 - typename genType::value_type(1.0f)) + typename genType::value_type(1.0f)); bilinearCoordinates.x = alpha/(bilinearCoordinates.y*(alpha_11 - typename genType::value_type(1.0f)) + typename genType::value_type(1.0f));
@ -343,7 +321,6 @@ namespace glm
discr = b*b - typename genType::value_type(4.0f)*a*c; 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)); 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)); q = -(typename genType::value_type(0.5f)) * (b + sign*glm::fastSqrt(discr));
@ -356,7 +333,6 @@ namespace glm
bilinearCoordinates.y = beta/(bilinearCoordinates.x*(beta_11 - 1) + 1); bilinearCoordinates.y = beta/(bilinearCoordinates.x*(beta_11 - 1) + 1);
} }
return true; return true;
} }
@ -367,40 +343,27 @@ namespace glm
genType const & v00, genType const & v10, genType const & v11, genType const & v01 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(); 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 e01 = v10 - v00;
genType e03 = v01 - v00; genType e03 = v01 - v00;
genType p = glm::cross(dir, e03); genType p = glm::cross(dir, e03);
typename genType::value_type det = glm::dot(e01, p); 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) if(det < epsilon)
return false; return false;
typename genType::value_type inv_det = typename genType::value_type(1.0f)/det; typename genType::value_type inv_det = typename genType::value_type(1.0f)/det;
genType s = orig - v00; genType s = orig - v00;
// Calculate the barycentric alpha coordinate of the first triangle
typename genType::value_type alpha = inv_det * glm::dot(s, p); typename genType::value_type alpha = inv_det * glm::dot(s, p);
// It lies outside the triangle
if(alpha > typename genType::value_type(1.0f)) if(alpha > typename genType::value_type(1.0f))
return false; return false;
if(alpha < typename genType::value_type(0.0f)) if(alpha < typename genType::value_type(0.0f))
return false; return false;
// Vector perpendicular to T and e01
genType q = glm::cross(s, 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); typename genType::value_type beta = inv_det * glm::dot(dir, q);
if(beta > typename genType::value_type(1.0f)) if(beta > typename genType::value_type(1.0f))
@ -411,13 +374,10 @@ namespace glm
typename genType::value_type t = inv_det * glm::dot(e03, q); typename genType::value_type t = inv_det * glm::dot(e03, q);
if(alpha + beta > typename genType::value_type(1.0f)){ if(alpha + beta > typename genType::value_type(1.0f)){
// Do exactly the same for the second triangle
genType e23 = v01 - v11; genType e23 = v01 - v11;
genType e21 = v10 - v11; genType e21 = v10 - v11;
p = glm::cross(dir, e21); p = glm::cross(dir, e21);
det = glm::dot(e23, p); det = glm::dot(e23, p);
if(det < epsilon) if(det < epsilon)
@ -425,7 +385,6 @@ namespace glm
inv_det = typename genType::value_type(1.0f)/det; inv_det = typename genType::value_type(1.0f)/det;
s = orig - v11; s = orig - v11;
alpha = inv_det * glm::dot(s, p); alpha = inv_det * glm::dot(s, p);
if(alpha < typename genType::value_type(0.0f)) if(alpha < typename genType::value_type(0.0f))
@ -437,7 +396,6 @@ namespace glm
if(beta < typename genType::value_type(0.0f)) if(beta < typename genType::value_type(0.0f))
return false; return false;
// This to support degenerate squares
if(beta + alpha > typename genType::value_type(1.0f)) if(beta + alpha > typename genType::value_type(1.0f))
return false; return false;
@ -446,7 +404,6 @@ namespace glm
if(t < typename genType::value_type(0.0f)) if(t < typename genType::value_type(0.0f))
return false; return false;
return true; return true;
} }
@ -458,39 +415,28 @@ namespace glm
genType & bilinearCoordinates genType & bilinearCoordinates
) )
{ {
// Epsilon to reject parallell lines
typename genType::value_type epsilon = std::numeric_limits<typename genType::value_type>::epsilon(); 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 e01 = v10 - v00;
genType e03 = v01 - v00; genType e03 = v01 - v00;
genType p = glm::cross(dir, e03); genType p = glm::cross(dir, e03);
typename genType::value_type det = glm::dot(e01, p); 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) if(det < epsilon && det > -epsilon)
return false; return false;
typename genType::value_type inv_det = typename genType::value_type(1.0f)/det; typename genType::value_type inv_det = typename genType::value_type(1.0f)/det;
genType s = orig - v00; genType s = orig - v00;
// Calculate the barycentric alpha coordinate of the first triangle
typename genType::value_type alpha = inv_det * glm::dot(s, p); typename genType::value_type alpha = inv_det * glm::dot(s, p);
// It lies outside the triangle
if(alpha > typename genType::value_type(1.0f)) if(alpha > typename genType::value_type(1.0f))
return false; return false;
if(alpha < typename genType::value_type(0.0f)) if(alpha < typename genType::value_type(0.0f))
return false; return false;
// Vector perpendicular to T and e01
genType q = glm::cross(s, 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); typename genType::value_type beta = inv_det * glm::dot(dir, q);
if(beta > typename genType::value_type(1.0f)) if(beta > typename genType::value_type(1.0f))
@ -501,13 +447,10 @@ namespace glm
bilinearCoordinates.z = inv_det * glm::dot(e03, q); bilinearCoordinates.z = inv_det * glm::dot(e03, q);
if(alpha + beta > typename genType::value_type(1.0f)){ if(alpha + beta > typename genType::value_type(1.0f)){
// Do exactly the same for the second triangle
genType e23 = v01 - v11; genType e23 = v01 - v11;
genType e21 = v10 - v11; genType e21 = v10 - v11;
p = glm::cross(dir, e21); p = glm::cross(dir, e21);
det = glm::dot(e23, p); det = glm::dot(e23, p);
if(det < epsilon && det > -epsilon) if(det < epsilon && det > -epsilon)
@ -515,7 +458,6 @@ namespace glm
inv_det = typename genType::value_type(1.0f)/det; inv_det = typename genType::value_type(1.0f)/det;
s = orig - v11; s = orig - v11;
alpha = inv_det * glm::dot(s, p); alpha = inv_det * glm::dot(s, p);
if(alpha < typename genType::value_type(0.0f)) if(alpha < typename genType::value_type(0.0f))
@ -527,14 +469,12 @@ namespace glm
if(beta < typename genType::value_type(0.0f)) if(beta < typename genType::value_type(0.0f))
return false; return false;
// This to support degenerate squares
if(beta + alpha > typename genType::value_type(1.0f)) if(beta + alpha > typename genType::value_type(1.0f))
return false; return false;
bilinearCoordinates.z = inv_det * glm::dot(e21, q); bilinearCoordinates.z = inv_det * glm::dot(e21, q);
} }
// Compute barycentric coordinates of v11
genType e02 = v11 - v00; genType e02 = v11 - v00;
genType N = glm::cross(e01, e03); genType N = glm::cross(e01, e03);
@ -551,7 +491,6 @@ namespace glm
beta_11 = (e01.x * e02.y - e01.y * e02.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) { if(abs(alpha_11 - typename genType::value_type(1.0f)) < epsilon) {
bilinearCoordinates.x = alpha; bilinearCoordinates.x = alpha;
@ -573,7 +512,7 @@ namespace glm
discr = b*b - typename genType::value_type(4.0f)*a*c; 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)); 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)); q = -(typename genType::value_type(0.5f)) * (b + sign*glm::fastSqrt(discr));
@ -598,40 +537,28 @@ namespace glm
) )
{ {
// Epsilon to reject parallell lines
typename genType::value_type epsilon = std::numeric_limits<typename genType::value_type>::epsilon(); 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 e01 = v10 - v00;
genType e03 = v01 - v00; genType e03 = v01 - v00;
genType p = glm::cross(dir, e03); genType p = glm::cross(dir, e03);
typename genType::value_type det = glm::dot(e01, p); 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) if(det < epsilon && det > -epsilon)
return false; return false;
typename genType::value_type inv_det = typename genType::value_type(1.0f)/det; typename genType::value_type inv_det = typename genType::value_type(1.0f)/det;
genType s = orig - v00; genType s = orig - v00;
// Calculate the barycentric alpha coordinate of the first triangle
typename genType::value_type alpha = inv_det * glm::dot(s, p); typename genType::value_type alpha = inv_det * glm::dot(s, p);
// It lies outside the triangle
if(alpha > typename genType::value_type(1.0f)) if(alpha > typename genType::value_type(1.0f))
return false; return false;
if(alpha < typename genType::value_type(0.0f)) if(alpha < typename genType::value_type(0.0f))
return false; return false;
// Vector perpendicular to T and e01
genType q = glm::cross(s, e01);
// Calculate barycentric beta coordinate of the first triangle genType q = glm::cross(s, e01);
typename genType::value_type beta = inv_det * glm::dot(dir, q); typename genType::value_type beta = inv_det * glm::dot(dir, q);
if(beta > typename genType::value_type(1.0f)) if(beta > typename genType::value_type(1.0f))
@ -639,15 +566,12 @@ namespace glm
if(beta < typename genType::value_type(0.0f)) if(beta < typename genType::value_type(0.0f))
return false; return false;
if(alpha + beta > typename genType::value_type(1.0f)){ if(alpha + beta > typename genType::value_type(1.0f)){
// Do exactly the same for the second triangle
genType e23 = v01 - v11; genType e23 = v01 - v11;
genType e21 = v10 - v11; genType e21 = v10 - v11;
p = glm::cross(dir, e21); p = glm::cross(dir, e21);
det = glm::dot(e23, p); det = glm::dot(e23, p);
if(det < epsilon && det > -epsilon) if(det < epsilon && det > -epsilon)
@ -655,7 +579,6 @@ namespace glm
inv_det = typename genType::value_type(1.0f)/det; inv_det = typename genType::value_type(1.0f)/det;
s = orig - v11; s = orig - v11;
alpha = inv_det * glm::dot(s, p); alpha = inv_det * glm::dot(s, p);
if(alpha < typename genType::value_type(0.0f)) if(alpha < typename genType::value_type(0.0f))
@ -666,8 +589,6 @@ namespace glm
if(beta < typename genType::value_type(0.0f)) if(beta < typename genType::value_type(0.0f))
return false; return false;
// This to support degenerate squares
if(beta + alpha > typename genType::value_type(1.0f)) if(beta + alpha > typename genType::value_type(1.0f))
return false; return false;
@ -676,72 +597,80 @@ namespace glm
return true; return true;
} }
template<typename genType> template <typename genType>
GLM_FUNC_QUALIFIER bool intersectLineQuad GLM_FUNC_QUALIFIER bool intersectRayDegenerateQuad
( (
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,
genType & bilinearCoordinates genType & bilinearCoordinates
) )
{ {
// Epsilon to reject parallell lines genType e01, e03, p, s, q;
typename genType::value_type epsilon = std::numeric_limits<typename genType::value_type>::epsilon(); typename genType::value_type epsilon, det, inv_det, alpha, beta, t;
bool isInOne = true;
// Calculate edges and normal of first triangle epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
genType e01 = v10 - v00;
genType e03 = v01 - v00;
genType p = glm::cross(dir, e03); e01 = v10 - v00;
e03 = v01 - v00;
typename genType::value_type det = glm::dot(e01, p); p = glm::cross(dir, e03);
// Reject rays orthagonal to the normal vector. I.e. rays parallell to the plane. det = glm::dot(e01, p);
if(det < epsilon && det > -epsilon)
return false;
typename genType::value_type inv_det = typename genType::value_type(1.0f)/det; if(det < epsilon){
isInOne = false;
goto second;
}
genType s = orig - v00; inv_det = typename genType::value_type(1.0f)/det;
s = orig - v00;
alpha = inv_det * glm::dot(s, p);
// Calculate the barycentric alpha coordinate of the first triangle if(alpha > typename genType::value_type(1.0f)){
typename genType::value_type alpha = inv_det * glm::dot(s, p); isInOne = false;
goto second;
}
// It lies outside the triangle if(alpha < typename genType::value_type(0.0f)){
if(alpha > typename genType::value_type(1.0f)) isInOne = false;
return false; goto second;
}
if(alpha < typename genType::value_type(0.0f)) q = glm::cross(s, e01);
return false; beta = inv_det * glm::dot(dir, q);
// Vector perpendicular to T and e01 if(beta > typename genType::value_type(1.0f)){
genType q = glm::cross(s, e01); isInOne = false;
goto second;
}
// Calculate barycentric beta coordinate of the first triangle if(beta < typename genType::value_type(0.0f)){
typename genType::value_type beta = inv_det * glm::dot(dir, q); isInOne = false;
goto second;
}
if(beta > typename genType::value_type(1.0f)) t = inv_det * glm::dot(e03, q);
return false;
if(beta < typename genType::value_type(0.0f))
return false;
bilinearCoordinates.z = inv_det * glm::dot(e03, q); if(t < typename genType::value_type(0.0f)){
isInOne = false;
if(alpha + beta > typename genType::value_type(1.0f)){ goto second;
// Do exactly the same for the second triangle }
second:
if(!isInOne || alpha + beta > typename genType::value_type(1.0f)){
genType e23 = v01 - v11; genType e23 = v01 - v11;
genType e21 = v10 - v11; genType e21 = v10 - v11;
p = glm::cross(dir, e21); p = glm::cross(dir, e21);
det = glm::dot(e23, p); det = glm::dot(e23, p);
if(det < epsilon && det > -epsilon) if(det < epsilon){
return false; return false;
}
inv_det = typename genType::value_type(1.0f)/det; inv_det = typename genType::value_type(1.0f)/det;
s = orig - v11; s = orig - v11;
alpha = inv_det * glm::dot(s, p); alpha = inv_det * glm::dot(s, p);
if(alpha < typename genType::value_type(0.0f)) if(alpha < typename genType::value_type(0.0f))
@ -752,15 +681,15 @@ namespace glm
if(beta < typename genType::value_type(0.0f)) if(beta < typename genType::value_type(0.0f))
return false; return false;
// This to support degenerate squares
if(beta + alpha > typename genType::value_type(1.0f)) if(beta + alpha > typename genType::value_type(1.0f))
return false; return false;
bilinearCoordinates.z = inv_det * glm::dot(e21, q); t = inv_det * glm::dot(e21, q);
if(t < typename genType::value_type(0.0f))
return false;
} }
// Compute barycentric coordinates of v11
genType e02 = v11 - v00; genType e02 = v11 - v00;
genType N = glm::cross(e01, e03); genType N = glm::cross(e01, e03);
@ -777,7 +706,6 @@ namespace glm
beta_11 = (e01.x * e02.y - e01.y * e02.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) { if(abs(alpha_11 - typename genType::value_type(1.0f)) < epsilon) {
bilinearCoordinates.x = alpha; bilinearCoordinates.x = alpha;
@ -799,7 +727,6 @@ namespace glm
discr = b*b - typename genType::value_type(4.0f)*a*c; 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)); 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)); q = -(typename genType::value_type(0.5f)) * (b + sign*glm::fastSqrt(discr));
@ -817,57 +744,65 @@ namespace glm
} }
template<typename genType> template<typename genType>
GLM_FUNC_QUALIFIER bool fastIntersectLineQuad GLM_FUNC_QUALIFIER bool fastIntersectRayDegenerateQuad
( (
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
) )
{ {
// Epsilon to reject parallell lines genType e01, e03, p, s, q;
typename genType::value_type epsilon = std::numeric_limits<typename genType::value_type>::epsilon(); typename genType::value_type epsilon, det, inv_det, alpha, beta, t;
bool isInOne = true;
// Calculate edges and normal of first triangle epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
genType e01 = v10 - v00;
genType e03 = v01 - v00;
genType p = glm::cross(dir, e03); e01 = v10 - v00;
e03 = v01 - v00;
typename genType::value_type det = glm::dot(e01, p); p = glm::cross(dir, e03);
det = glm::dot(e01, p);
// Reject rays orthagonal to the normal vector. I.e. rays parallell to the plane. if(det < epsilon){
if(det < epsilon && det > -epsilon) isInOne = false;
return false; goto second;
}
typename genType::value_type inv_det = typename genType::value_type(1.0f)/det; inv_det = typename genType::value_type(1.0f)/det;
s = orig - v00;
alpha = inv_det * glm::dot(s, p);
if(alpha > typename genType::value_type(1.0f)){
isInOne = false;
goto second;
}
genType s = orig - v00; if(alpha < typename genType::value_type(0.0f)){
isInOne = false;
goto second;
}
// Calculate the barycentric alpha coordinate of the first triangle q = glm::cross(s, e01);
typename genType::value_type alpha = inv_det * glm::dot(s, p); beta = inv_det * glm::dot(dir, q);
// It lies outside the triangle if(beta > typename genType::value_type(1.0f)){
if(alpha > typename genType::value_type(1.0f)) isInOne = false;
return false; goto second;
}
if(alpha < typename genType::value_type(0.0f)) if(beta < typename genType::value_type(0.0f)){
return false; isInOne = false;
goto second;
}
// Vector perpendicular to T and e01 t = inv_det * glm::dot(e03, q);
genType q = glm::cross(s, e01);
// Calculate barycentric beta coordinate of the first triangle if(t < typename genType::value_type(0.0f)){
typename genType::value_type beta = inv_det * glm::dot(dir, q); isInOne = false;
goto second;
}
if(beta > typename genType::value_type(1.0f)) second:
return false; if(!isInOne || alpha + beta > typename genType::value_type(1.0f)){
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 e23 = v01 - v11;
genType e21 = v10 - v11; genType e21 = v10 - v11;
@ -876,8 +811,9 @@ namespace glm
det = glm::dot(e23, p); det = glm::dot(e23, p);
if(det < epsilon && det > -epsilon) if(det < epsilon){
return false; return false;
}
inv_det = typename genType::value_type(1.0f)/det; inv_det = typename genType::value_type(1.0f)/det;
s = orig - v11; s = orig - v11;
@ -893,13 +829,13 @@ namespace glm
if(beta < typename genType::value_type(0.0f)) if(beta < typename genType::value_type(0.0f))
return false; return false;
// This to support degenerate squares
if(beta + alpha > typename genType::value_type(1.0f)) if(beta + alpha > typename genType::value_type(1.0f))
return false; return false;
t = inv_det * glm::dot(e21, q);
} }
return true; return t >= typename genType::value_type(0.0f);
} }
template<typename genType> template<typename genType>
@ -914,18 +850,14 @@ namespace glm
typename genType::value_type epsilon, det, inv_det, alpha, beta; typename genType::value_type epsilon, det, inv_det, alpha, beta;
bool isInOne = true; bool isInOne = true;
// Epsilon to reject parallell lines
epsilon = std::numeric_limits<typename genType::value_type>::epsilon(); epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
// Calculate edges and normal of first triangle
e01 = v10 - v00; e01 = v10 - v00;
e03 = v01 - v00; e03 = v01 - v00;
p = glm::cross(dir, e03); p = glm::cross(dir, e03);
det = glm::dot(e01, p); det = glm::dot(e01, p);
// Reject rays orthagonal to the normal vector. I.e. rays parallell to the plane.
if(det < epsilon && det > -epsilon){ if(det < epsilon && det > -epsilon){
isInOne = false; isInOne = false;
goto second; goto second;
@ -933,11 +865,8 @@ namespace glm
inv_det = typename genType::value_type(1.0f)/det; inv_det = typename genType::value_type(1.0f)/det;
s = orig - v00; s = orig - v00;
// Calculate the barycentric alpha coordinate of the first triangle
alpha = inv_det * glm::dot(s, p); alpha = inv_det * glm::dot(s, p);
// It lies outside the triangle
if(alpha > typename genType::value_type(1.0f)){ if(alpha > typename genType::value_type(1.0f)){
isInOne = false; isInOne = false;
goto second; goto second;
@ -948,32 +877,25 @@ namespace glm
goto second; goto second;
} }
// Vector perpendicular to T and e01
q = glm::cross(s, e01); q = glm::cross(s, e01);
// Calculate barycentric beta coordinate of the first triangle
beta = inv_det * glm::dot(dir, q); beta = inv_det * glm::dot(dir, q);
if(beta > typename genType::value_type(1.0f)){ if(beta > typename genType::value_type(1.0f)){
isInOne = false; isInOne = false;
goto second; goto second;
} }
if(beta < typename genType::value_type(0.0f)){ if(beta < typename genType::value_type(0.0f)){
isInOne = false; isInOne = false;
goto second; goto second;
} }
/* Intersection is not in the first triangle, check the second*/
second: second:
if(!isInOne || alpha + beta > typename genType::value_type(1.0f)){ if(!isInOne || alpha + beta > typename genType::value_type(1.0f)){
// Do exactly the same for the second triangle
genType e23 = v01 - v11; genType e23 = v01 - v11;
genType e21 = v10 - v11; genType e21 = v10 - v11;
p = glm::cross(dir, e21); p = glm::cross(dir, e21);
det = glm::dot(e23, p); det = glm::dot(e23, p);
if(det < epsilon && det > -epsilon){ if(det < epsilon && det > -epsilon){
@ -982,7 +904,6 @@ namespace glm
inv_det = typename genType::value_type(1.0f)/det; inv_det = typename genType::value_type(1.0f)/det;
s = orig - v11; s = orig - v11;
alpha = inv_det * glm::dot(s, p); alpha = inv_det * glm::dot(s, p);
if(alpha < typename genType::value_type(0.0f)) if(alpha < typename genType::value_type(0.0f))
@ -994,13 +915,10 @@ namespace glm
if(beta < typename genType::value_type(0.0f)) if(beta < typename genType::value_type(0.0f))
return false; return false;
// This to support degenerate squares
if(beta + alpha > typename genType::value_type(1.0f)) if(beta + alpha > typename genType::value_type(1.0f))
return false; return false;
} }
// Compute barycentric coordinates of v11
genType e02 = v11 - v00; genType e02 = v11 - v00;
genType N = glm::cross(e01, e03); genType N = glm::cross(e01, e03);
@ -1017,7 +935,6 @@ namespace glm
beta_11 = (e01.x * e02.y - e01.y * e02.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) { if(abs(alpha_11 - typename genType::value_type(1.0f)) < epsilon) {
bilinearCoordinates.x = alpha; bilinearCoordinates.x = alpha;
@ -1039,7 +956,6 @@ namespace glm
discr = b*b - typename genType::value_type(4.0f)*a*c; 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)); 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)); q = -(typename genType::value_type(0.5f)) * (b + sign*glm::fastSqrt(discr));
@ -1067,18 +983,14 @@ namespace glm
typename genType::value_type epsilon, det, inv_det, alpha, beta; typename genType::value_type epsilon, det, inv_det, alpha, beta;
bool isInOne = true; bool isInOne = true;
// Epsilon to reject parallell lines
epsilon = std::numeric_limits<typename genType::value_type>::epsilon(); epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
// Calculate edges and normal of first triangle
e01 = v10 - v00; e01 = v10 - v00;
e03 = v01 - v00; e03 = v01 - v00;
p = glm::cross(dir, e03); p = glm::cross(dir, e03);
det = glm::dot(e01, p); det = glm::dot(e01, p);
// Reject rays orthagonal to the normal vector. I.e. rays parallell to the plane.
if(det < epsilon && det > -epsilon){ if(det < epsilon && det > -epsilon){
isInOne = false; isInOne = false;
goto second; goto second;
@ -1086,11 +998,8 @@ namespace glm
inv_det = typename genType::value_type(1.0f)/det; inv_det = typename genType::value_type(1.0f)/det;
s = orig - v00; s = orig - v00;
// Calculate the barycentric alpha coordinate of the first triangle
alpha = inv_det * glm::dot(s, p); alpha = inv_det * glm::dot(s, p);
// It lies outside the triangle
if(alpha > typename genType::value_type(1.0f)){ if(alpha > typename genType::value_type(1.0f)){
isInOne = false; isInOne = false;
goto second; goto second;
@ -1101,10 +1010,7 @@ namespace glm
goto second; goto second;
} }
// Vector perpendicular to T and e01
q = glm::cross(s, e01); q = glm::cross(s, e01);
// Calculate barycentric beta coordinate of the first triangle
beta = inv_det * glm::dot(dir, q); beta = inv_det * glm::dot(dir, q);
if(beta > typename genType::value_type(1.0f)){ if(beta > typename genType::value_type(1.0f)){
@ -1117,16 +1023,13 @@ namespace glm
goto second; goto second;
} }
/* Intersection is not in the first triangle, check the second*/
second: second:
if(!isInOne || alpha + beta > typename genType::value_type(1.0f)){ if(!isInOne || alpha + beta > typename genType::value_type(1.0f)){
// Do exactly the same for the second triangle
genType e23 = v01 - v11; genType e23 = v01 - v11;
genType e21 = v10 - v11; genType e21 = v10 - v11;
p = glm::cross(dir, e21); p = glm::cross(dir, e21);
det = glm::dot(e23, p); det = glm::dot(e23, p);
if(det < epsilon && det > -epsilon){ if(det < epsilon && det > -epsilon){
@ -1135,7 +1038,6 @@ namespace glm
inv_det = typename genType::value_type(1.0f)/det; inv_det = typename genType::value_type(1.0f)/det;
s = orig - v11; s = orig - v11;
alpha = inv_det * glm::dot(s, p); alpha = inv_det * glm::dot(s, p);
if(alpha < typename genType::value_type(0.0f)) if(alpha < typename genType::value_type(0.0f))
@ -1146,8 +1048,6 @@ namespace glm
if(beta < typename genType::value_type(0.0f)) if(beta < typename genType::value_type(0.0f))
return false; return false;
// This to support degenerate squares
if(beta + alpha > typename genType::value_type(1.0f)) if(beta + alpha > typename genType::value_type(1.0f))
return false; return false;
} }
@ -1155,5 +1055,4 @@ namespace glm
return true; return true;
} }
}//namespace glm }//namespace glm