ray_box_intersect.cpp 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. #include "ray_box_intersect.h"
  2. template <
  3. typename Derivedsource,
  4. typename Deriveddir,
  5. typename Scalar>
  6. IGL_INLINE bool igl::ray_box_intersect(
  7. const Eigen::PlainObjectBase<Derivedsource> & origin,
  8. const Eigen::PlainObjectBase<Deriveddir> & dir,
  9. const Eigen::AlignedBox<Scalar,3> & box,
  10. const Scalar & t0,
  11. const Scalar & t1)
  12. {
  13. using namespace Eigen;
  14. // This should be precomputed and provided as input
  15. typedef Matrix<Scalar,1,3> RowVector3S;
  16. const RowVector3S inv_dir( 1./dir(0),1./dir(1),1./dir(2));
  17. const std::vector<bool> sign = { inv_dir(0)<0, inv_dir(1)<0, inv_dir(2)<0};
  18. // http://people.csail.mit.edu/amy/papers/box-jgt.pdf
  19. // "An Efficient and Robust Ray–Box Intersection Algorithm"
  20. Scalar tmin, tmax, tymin, tymax, tzmin, tzmax;
  21. std::vector<RowVector3S> bounds = {box.min(),box.max()};
  22. tmin = ( bounds[sign[0]](0) - origin(0)) * inv_dir(0);
  23. tmax = ( bounds[1-sign[0]](0) - origin(0)) * inv_dir(0);
  24. tymin = (bounds[sign[1]](1) - origin(1)) * inv_dir(1);
  25. tymax = (bounds[1-sign[1]](1) - origin(1)) * inv_dir(1);
  26. if ( (tmin > tymax) || (tymin > tmax) )
  27. {
  28. return false;
  29. }
  30. if (tymin > tmin)
  31. {
  32. tmin = tymin;
  33. }
  34. if (tymax < tmax)
  35. {
  36. tmax = tymax;
  37. }
  38. tzmin = (bounds[sign[2]](2) - origin(2)) * inv_dir(2);
  39. tzmax = (bounds[1-sign[2]](2) - origin(2)) * inv_dir(2);
  40. if ( (tmin > tzmax) || (tzmin > tmax) )
  41. {
  42. return false;
  43. }
  44. if (tzmin > tmin)
  45. {
  46. tmin = tzmin;
  47. }
  48. if (tzmax < tmax)
  49. {
  50. tmax = tzmax;
  51. }
  52. return ( (tmin < t1) && (tmax > t0) );
  53. }