Fixed intersectRayTriangle #6
This commit is contained in:
parent
07d826e185
commit
58c5e0ef4d
@ -44,12 +44,13 @@ namespace glm
|
|||||||
typename genType::value_type & intersectionDistance);
|
typename genType::value_type & intersectionDistance);
|
||||||
|
|
||||||
//! Compute the intersection of a ray and a triangle.
|
//! 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.
|
//! From GLM_GTX_intersect extension.
|
||||||
template <typename genType>
|
template <typename T, precision P>
|
||||||
GLM_FUNC_DECL bool intersectRayTriangle(
|
GLM_FUNC_DECL bool intersectRayTriangle(
|
||||||
genType const & orig, genType const & dir,
|
tvec3<T, P> const& orig, tvec3<T, P> const& dir,
|
||||||
genType const & vert0, genType const & vert1, genType const & vert2,
|
tvec3<T, P> const& v0, tvec3<T, P> const& v1, tvec3<T, P> const& v2,
|
||||||
genType & baryPosition);
|
tvec3<T, P>& baryPosition, T& distance);
|
||||||
|
|
||||||
//! Compute the intersection of a line and a triangle.
|
//! Compute the intersection of a line and a triangle.
|
||||||
//! From GLM_GTX_intersect extension.
|
//! From GLM_GTX_intersect extension.
|
||||||
|
@ -23,21 +23,75 @@ namespace glm
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename genType>
|
template <typename T, precision P>
|
||||||
GLM_FUNC_QUALIFIER bool intersectRayTriangle
|
GLM_FUNC_QUALIFIER bool intersectRayTriangle
|
||||||
(
|
(
|
||||||
genType const & orig, genType const & dir,
|
tvec3<T, P> const& orig, tvec3<T, P> const& dir,
|
||||||
genType const & v0, genType const & v1, genType const & v2,
|
tvec3<T, P> const& vert0, tvec3<T, P> const& vert1, tvec3<T, P> const& vert2,
|
||||||
genType & baryPosition
|
tvec2<T, P>& baryPosition, T& distance
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
genType e1 = v1 - v0;
|
// find vectors for two edges sharing vert0
|
||||||
genType e2 = v2 - v0;
|
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();
|
typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
|
||||||
if(a < Epsilon && a > -Epsilon)
|
if(a < Epsilon && a > -Epsilon)
|
||||||
return false;
|
return false;
|
||||||
@ -62,6 +116,7 @@ namespace glm
|
|||||||
|
|
||||||
return baryPosition.z >= typename genType::value_type(0.0f);
|
return baryPosition.z >= typename genType::value_type(0.0f);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
template <typename genType>
|
template <typename genType>
|
||||||
GLM_FUNC_QUALIFIER bool intersectLineTriangle
|
GLM_FUNC_QUALIFIER bool intersectLineTriangle
|
||||||
|
@ -72,6 +72,7 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate)
|
|||||||
#### Fixes:
|
#### Fixes:
|
||||||
- Removed doxygen references to GTC_half_float which was removed in 0.9.4
|
- Removed doxygen references to GTC_half_float which was removed in 0.9.4
|
||||||
- Fixed glm::decompose #448
|
- Fixed glm::decompose #448
|
||||||
|
- Fixed intersectRayTriangle #6
|
||||||
|
|
||||||
#### Deprecation:
|
#### Deprecation:
|
||||||
- Removed GLM_GTX_simd_vec4 extension
|
- Removed GLM_GTX_simd_vec4 extension
|
||||||
|
@ -1,9 +1,34 @@
|
|||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/epsilon.hpp>
|
||||||
#include <glm/gtx/intersect.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;
|
return Error;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user