mirror of
https://github.com/g-truc/glm.git
synced 2024-11-29 19:34:36 +00:00
Fixed intersectRayTriangle #6
This commit is contained in:
parent
07d826e185
commit
58c5e0ef4d
@ -44,12 +44,13 @@ namespace glm
|
||||
typename genType::value_type & intersectionDistance);
|
||||
|
||||
//! Compute the intersection of a ray and a triangle.
|
||||
/// Based om Tomas Möller implementation http://fileadmin.cs.lth.se/cs/Personal/Tomas_Akenine-Moller/raytri/
|
||||
//! From GLM_GTX_intersect extension.
|
||||
template <typename genType>
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_DECL bool intersectRayTriangle(
|
||||
genType const & orig, genType const & dir,
|
||||
genType const & vert0, genType const & vert1, genType const & vert2,
|
||||
genType & baryPosition);
|
||||
tvec3<T, P> const& orig, tvec3<T, P> const& dir,
|
||||
tvec3<T, P> const& v0, tvec3<T, P> const& v1, tvec3<T, P> const& v2,
|
||||
tvec3<T, P>& baryPosition, T& distance);
|
||||
|
||||
//! Compute the intersection of a line and a triangle.
|
||||
//! From GLM_GTX_intersect extension.
|
||||
|
@ -23,21 +23,75 @@ namespace glm
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename genType>
|
||||
template <typename T, precision P>
|
||||
GLM_FUNC_QUALIFIER bool intersectRayTriangle
|
||||
(
|
||||
genType const & orig, genType const & dir,
|
||||
genType const & v0, genType const & v1, genType const & v2,
|
||||
genType & baryPosition
|
||||
tvec3<T, P> const& orig, tvec3<T, P> const& dir,
|
||||
tvec3<T, P> const& vert0, tvec3<T, P> const& vert1, tvec3<T, P> const& vert2,
|
||||
tvec2<T, P>& baryPosition, T& distance
|
||||
)
|
||||
{
|
||||
genType e1 = v1 - v0;
|
||||
genType e2 = v2 - v0;
|
||||
// find vectors for two edges sharing vert0
|
||||
tvec3<T, P> const edge1 = vert1 - vert0;
|
||||
tvec3<T, P> const edge2 = vert2 - vert0;
|
||||
|
||||
genType p = glm::cross(dir, e2);
|
||||
// begin calculating determinant - also used to calculate U parameter
|
||||
tvec3<T, P> const p = glm::cross(dir, edge2);
|
||||
|
||||
typename genType::value_type a = glm::dot(e1, p);
|
||||
// if determinant is near zero, ray lies in plane of triangle
|
||||
T const det = glm::dot(edge1, p);
|
||||
|
||||
tvec3<T, P> qvec;
|
||||
|
||||
if(det > std::numeric_limits<T>::epsilon())
|
||||
{
|
||||
// calculate distance from vert0 to ray origin
|
||||
tvec3<T, P> const tvec = orig - vert0;
|
||||
|
||||
// calculate U parameter and test bounds
|
||||
baryPosition.x = glm::dot(tvec, p);
|
||||
if(baryPosition.x < static_cast<T>(0) || baryPosition.x > det)
|
||||
return false;
|
||||
|
||||
// prepare to test V parameter
|
||||
qvec = glm::cross(tvec, edge1);
|
||||
|
||||
// calculate V parameter and test bounds
|
||||
baryPosition.y = glm::dot(dir, qvec);
|
||||
if((baryPosition.y < static_cast<T>(0)) || ((baryPosition.x + baryPosition.y) > det))
|
||||
return false;
|
||||
}
|
||||
else if(det < -std::numeric_limits<T>::epsilon())
|
||||
{
|
||||
// calculate distance from vert0 to ray origin
|
||||
tvec3<T, P> const tvec = orig - vert0;
|
||||
|
||||
// calculate U parameter and test bounds
|
||||
baryPosition.x = glm::dot(tvec, p);
|
||||
if((baryPosition.x > static_cast<T>(0)) || (baryPosition.x < det))
|
||||
return false;
|
||||
|
||||
// prepare to test V parameter
|
||||
qvec = glm::cross(tvec, edge1);
|
||||
|
||||
// calculate V parameter and test bounds
|
||||
baryPosition.y = glm::dot(dir, qvec);
|
||||
if((baryPosition.y > static_cast<T>(0)) || (baryPosition.x + baryPosition.y < det))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false; // ray is parallel to the plane of the triangle
|
||||
|
||||
T inv_det = static_cast<T>(1) / det;
|
||||
|
||||
// calculate distance, ray intersects triangle
|
||||
distance = glm::dot(edge2, qvec) * inv_det;
|
||||
baryPosition *= inv_det;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
|
||||
if(a < Epsilon && a > -Epsilon)
|
||||
return false;
|
||||
@ -62,6 +116,7 @@ namespace glm
|
||||
|
||||
return baryPosition.z >= typename genType::value_type(0.0f);
|
||||
}
|
||||
*/
|
||||
|
||||
template <typename genType>
|
||||
GLM_FUNC_QUALIFIER bool intersectLineTriangle
|
||||
|
@ -72,6 +72,7 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate)
|
||||
#### Fixes:
|
||||
- Removed doxygen references to GTC_half_float which was removed in 0.9.4
|
||||
- Fixed glm::decompose #448
|
||||
- Fixed intersectRayTriangle #6
|
||||
|
||||
#### Deprecation:
|
||||
- Removed GLM_GTX_simd_vec4 extension
|
||||
|
@ -1,9 +1,34 @@
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/epsilon.hpp>
|
||||
#include <glm/gtx/intersect.hpp>
|
||||
|
||||
int main()
|
||||
int test_intersectRayTriangle()
|
||||
{
|
||||
int Error(0);
|
||||
int Error = 0;
|
||||
|
||||
glm::vec3 const Orig(0, 0, 2);
|
||||
glm::vec3 const Dir(0, 0, -1);
|
||||
glm::vec3 const Vert0(0, 0, 0);
|
||||
glm::vec3 const Vert1(-1, -1, 0);
|
||||
glm::vec3 const Vert2(1, -1, 0);
|
||||
glm::vec2 BaryPosition(0);
|
||||
float Distance = 0;
|
||||
|
||||
bool const Result = glm::intersectRayTriangle(Orig, Dir, Vert0, Vert1, Vert2, BaryPosition, Distance);
|
||||
|
||||
Error += glm::all(glm::epsilonEqual(BaryPosition, glm::vec2(0), std::numeric_limits<float>::epsilon())) ? 0 : 1;
|
||||
Error += glm::abs(Distance - 2.f) <= std::numeric_limits<float>::epsilon() ? 0 : 1;
|
||||
Error += Result ? 0 : 1;
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int Error = 0;
|
||||
|
||||
Error += test_intersectRayTriangle();
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user