Commit 3eec8059 authored by Jan Möbius's avatar Jan Möbius

Marlin: axisAlignedBBIntersection triangleIntersection and docu

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@9434 383ad7c9-94d9-4d36-a494-682f7c89f535
parent cdc60059
......@@ -1101,6 +1101,124 @@ roundness( const VectorT<Scalar, N>& _v0,
(_v2-_v0).sqrnorm() ));
}
template<typename Vec>
bool
triangleIntersection( const Vec& _o,
const Vec& _dir,
const Vec& _v0,
const Vec& _v1,
const Vec& _v2,
typename Vec::value_type& _t,
typename Vec::value_type& _u,
typename Vec::value_type& _v )
{
//This code effectively replicates the method described by Moeller et al. in "Fast, Minimum Storage Ray-Triangle Intersection".
Vec edge1, edge2, tvec, pvec, qvec;
typename Vec::value_type det, inv_det;
//find vectors for two edges sharing v0
edge1 = _v1-_v0;
edge2 = _v2-_v0;
//begin calculating determinant - also used to calculate u parameter
pvec = _dir % edge2;
//if determinant is near zero, the ray lies in plane of triangle
det = edge1 | pvec;
if (det > -0.000001 && det < 0.000001)
return false;
inv_det = 1.0 / det;
//calculate distance from vert0 to ray origin
tvec = _o - _v0;
//calculate U parameter and test bounds
_u = (tvec | pvec) * inv_det;
if (_u < 0.0 || _u > 1.0)
return false;
//prepare to test V parameter
qvec = tvec % edge1;
//calculate V parameter and test bounds
_v = (_dir | qvec) * inv_det;
if (_v < 0.0 || _u + _v > 1.0)
return false;
//Intersection found! Calculate t and exit...
_t = (edge2 | qvec) * inv_det;
return true;
}
template<typename Vec>
bool
axisAlignedBBIntersection( const Vec& _o,
const Vec& _dir,
const Vec& _bbmin,
const Vec& _bbmax,
typename Vec::value_type& tmin,
typename Vec::value_type& tmax )
{
/*
* Ray-box intersection using IEEE numerical properties to ensure that the
* test is both robust and efficient, as described in:
*
* Amy Williams, Steve Barrus, R. Keith Morley, and Peter Shirley
* "An Efficient and Robust Ray-Box Intersection Algorithm"
* Journal of graphics tools, 10(1):49-54, 2005
*
*/
typename Vec::value_type tymin, tymax, tzmin, tzmax;
Vec inv_dir;
inv_dir[0] = 1/_dir[0];
inv_dir[1] = 1/_dir[1];
inv_dir[2] = 1/_dir[2];
if (inv_dir[0] >= 0) {
tmin = (_bbmin[0] - _o[0]) * inv_dir[0];
tmax = (_bbmax[0] - _o[0]) * inv_dir[0];
}
else {
tmin = (_bbmax[0] - _o[0]) * inv_dir[0];
tmax = (_bbmin[0] - _o[0]) * inv_dir[0];
}
if (inv_dir[1] >= 0) {
tymin = (_bbmin[1] - _o[1]) * inv_dir[1];
tymax = (_bbmax[1] - _o[1]) * inv_dir[1];
}
else {
tymin = (_bbmax[1] - _o[1]) * inv_dir[1];
tymax = (_bbmin[1] - _o[1]) * inv_dir[1];
}
if ( (tmin > tymax) || (tymin > tmax) )
return false;
if (tymin > tmin)
tmin = tymin;
if (tymax < tmax)
tmax = tymax;
if (inv_dir[2] >= 0) {
tzmin = (_bbmin[2] - _o[2]) * inv_dir[2];
tzmax = (_bbmax[2] - _o[2]) * inv_dir[2];
}
else {
tzmin = (_bbmax[2] - _o[2]) * inv_dir[2];
tzmax = (_bbmin[2] - _o[2]) * inv_dir[2];
}
if ( (tmin > tzmax) || (tzmin > tmax) )
return false;
if (tzmin > tmin)
tmin = tzmin;
if (tzmax < tmax)
tmax = tzmax;
return true;
}
//=============================================================================
} // namespace Geometry
......
......@@ -102,6 +102,53 @@ VectorT<Scalar,3>
perpendicular( const VectorT<Scalar,3>& _v );
/** \brief Intersect a ray and a triangle.
*
* Computes the intersection point between a ray and a triangle.
*
* @param _o origin of the ray
* @param _dir direction vector of the ray
* @param _v0 first point of the triangle
* @param _v1 second point of the triangle
* @param _v2 third point of the triangle
* @param _t returned distance from the origin to the intersection, in units of _dir
* @param _u returned first barycentric coordinate of the intersection point in the triangle
* @param _v returned second barycentric coordinate of the intersection point in the triangle
* @return true if an intersection was found
*/
template<typename Vec>
bool
triangleIntersection( const Vec& _o,
const Vec& _dir,
const Vec& _v0,
const Vec& _v1,
const Vec& _v2,
typename Vec::value_type& _t,
typename Vec::value_type& _u,
typename Vec::value_type& _v );
/** \brief Intersect a ray and an axis aligned bounding box
*
* Computes the intersection point between a ray and an axis aligned bounding box
*
* @param _dir direction vector of the ray
* @param _bbmin lower left front corner of the bounding box
* @param _bbmax upper right back corner of the bounding box
* @param _t0 if there was an intersection, this value marks the entry point
* @param _t1 if there was an intersection, this value marks the exit point
* @return true if an intersection was found
*/
template<typename Vec>
bool
axisAlignedBBIntersection( const Vec& _o,
const Vec& _dir,
const Vec& _bbmin,
const Vec& _bbmax,
typename Vec::value_type& _t0,
typename Vec::value_type& _t1 );
//== 2D STUFF =================================================================
/// orientation of point _p w.r.t. line through _v0,_v1 in 2D
......
......@@ -149,7 +149,17 @@ public:
Vec3& _v, Scalar& _t ) const
{ return intersect(_v0, _v1, _v, _t, LineSegment); }
/// general intersection
/** \brief General intersection function.
*
* General intersection between a line/ray and the plane.
*
* @param _v0 start vector of the ray
* @param _v1 end vector of the ray
* @param _v returned intersection point
* @param _t returned relative distance from the interection to _v0 compared to _v1
* @param _target type of intersection to test
* @return true if an intersection was found
*/
bool intersect( const Vec3& _v0,
const Vec3& _v1,
Vec3& _v,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment