ambient_occlusion.cpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include "ambient_occlusion.h"
  2. #include "EmbreeIntersector.h"
  3. #include <igl/random_dir.h>
  4. template <
  5. typename Scalar,
  6. typename Index,
  7. typename DerivedP,
  8. typename DerivedN,
  9. typename DerivedS >
  10. void igl::ambient_occlusion(
  11. const igl::EmbreeIntersector<Scalar,Index> & ei,
  12. const Eigen::PlainObjectBase<DerivedP> & P,
  13. const Eigen::PlainObjectBase<DerivedN> & N,
  14. const int num_samples,
  15. Eigen::PlainObjectBase<DerivedS> & S)
  16. {
  17. using namespace Eigen;
  18. using namespace igl;
  19. const int n = P.rows();
  20. // Resize output
  21. S.resize(n,1);
  22. // Embree seems to be parallel when constructing but not when tracing rays
  23. #pragma omp parallel for
  24. // loop over mesh vertices
  25. for(int p = 0;p<n;p++)
  26. {
  27. const Vector3d origin = P.row(p);
  28. const Vector3d normal = N.row(p);
  29. int num_hits = 0;
  30. MatrixXd D = random_dir_stratified(num_samples);
  31. for(int s = 0;s<num_samples;s++)
  32. {
  33. //Vector3d d = random_dir();
  34. Vector3d d = D.row(s);
  35. if(d.dot(normal) < 0)
  36. {
  37. // reverse ray
  38. d *= -1;
  39. }
  40. igl::Hit hit;
  41. if(ei.intersectRay(origin,d,hit))
  42. {
  43. num_hits++;
  44. }
  45. }
  46. S(p) = (double)num_hits/(double)num_samples;
  47. }
  48. }
  49. template <
  50. typename DerivedV,
  51. typename DerivedF,
  52. typename DerivedP,
  53. typename DerivedN,
  54. typename DerivedS >
  55. void igl::ambient_occlusion(
  56. const Eigen::PlainObjectBase<DerivedV> & V,
  57. const Eigen::PlainObjectBase<DerivedF> & F,
  58. const Eigen::PlainObjectBase<DerivedP> & P,
  59. const Eigen::PlainObjectBase<DerivedN> & N,
  60. const int num_samples,
  61. Eigen::PlainObjectBase<DerivedS> & S)
  62. {
  63. using namespace igl;
  64. using namespace Eigen;
  65. EmbreeIntersector<
  66. typename DerivedV::Scalar,
  67. typename DerivedF::Scalar > ei(V,F);
  68. return ambient_occlusion(ei,P,N,num_samples,S);
  69. }
  70. #ifndef IGL_HEADER_ONLY
  71. // Explicit template instanciation
  72. template void igl::ambient_occlusion<double, int, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(igl::EmbreeIntersector<double, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  73. template void igl::ambient_occlusion<double, int, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(igl::EmbreeIntersector<double, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  74. #endif