unproject_in_mesh.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "unproject_in_mesh.h"
  9. #include "EmbreeIntersector.h"
  10. #include <igl/unproject.h>
  11. #include <vector>
  12. #ifndef IGL_OPENGL_4
  13. template <
  14. typename Derivedobj>
  15. IGL_INLINE int igl::unproject_in_mesh(
  16. const double x,
  17. const double y,
  18. const igl::EmbreeIntersector & ei,
  19. Eigen::PlainObjectBase<Derivedobj> & obj)
  20. {
  21. std::vector<igl::Hit> hits;
  22. return igl::unproject_in_mesh(x,y,ei,obj,hits);
  23. }
  24. template <
  25. typename Derivedobj>
  26. IGL_INLINE int igl::unproject_in_mesh(
  27. const double x,
  28. const double y,
  29. const igl::EmbreeIntersector & ei,
  30. Eigen::PlainObjectBase<Derivedobj> & obj,
  31. std::vector<igl::Hit > & hits)
  32. {
  33. using namespace igl;
  34. using namespace std;
  35. using namespace Eigen;
  36. // Source and direction on screen
  37. Vector3f win_s = Vector3f(x,y,0);
  38. Vector3f win_d(x,y,1);
  39. // Source, destination and direction in world
  40. Vector3f s,d,dir;
  41. unproject(win_s,s);
  42. unproject(win_d,d);
  43. dir = d-s;
  44. // Shoot ray, collect all hits (could just collect first two)
  45. int num_rays_shot;
  46. hits.clear();
  47. ei.intersectRay(s,dir,hits,num_rays_shot);
  48. switch(hits.size())
  49. {
  50. case 0:
  51. break;
  52. case 1:
  53. default:
  54. {
  55. obj = (s + dir*hits[0].t).cast<typename Derivedobj::Scalar>();
  56. break;
  57. }
  58. // case 2:
  59. // default:
  60. // {
  61. // obj = 0.5*((s + dir*hits[0].t) + (s + dir*hits[1].t)).cast<typename Derivedobj::Scalar>();
  62. // break;
  63. // }
  64. }
  65. return hits.size();
  66. }
  67. #endif
  68. template <typename Derivedobj>
  69. IGL_INLINE int igl::unproject_in_mesh(
  70. const Eigen::Vector2f& pos,
  71. const Eigen::Matrix4f& model,
  72. const Eigen::Matrix4f& proj,
  73. const Eigen::Vector4f& viewport,
  74. const igl::EmbreeIntersector & ei,
  75. Eigen::PlainObjectBase<Derivedobj> & obj,
  76. std::vector<igl::Hit > & hits)
  77. {
  78. using namespace igl;
  79. using namespace std;
  80. using namespace Eigen;
  81. // Source and direction on screen
  82. Vector3f win_s(pos(0),pos(1),0);
  83. Vector3f win_d(pos(0),pos(1),1);
  84. // Source, destination and direction in world
  85. Vector3f s,d,dir;
  86. s = igl::unproject(win_s,model,proj,viewport);
  87. d = igl::unproject(win_d,model,proj,viewport);
  88. dir = d-s;
  89. // Shoot ray, collect all hits (could just collect first two)
  90. int num_rays_shot;
  91. hits.clear();
  92. ei.intersectRay(s,dir,hits,num_rays_shot);
  93. switch(hits.size())
  94. {
  95. case 0:
  96. break;
  97. case 1:
  98. default:
  99. {
  100. obj = (s + dir*hits[0].t).cast<typename Derivedobj::Scalar>();
  101. break;
  102. }
  103. // case 2:
  104. // default:
  105. // {
  106. // obj = 0.5*((s + dir*hits[0].t) + (s + dir*hits[1].t)).cast<typename Derivedobj::Scalar>();
  107. // break;
  108. // }
  109. }
  110. return hits.size();
  111. }
  112. #ifdef IGL_STATIC_LIBRARY
  113. # ifndef IGL_OPENLGL_4
  114. template int igl::unproject_in_mesh<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(double, double, igl::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&, std::vector<igl::Hit, std::allocator<igl::Hit> >&);
  115. template int igl::unproject_in_mesh<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(double, double, igl::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
  116. # endif
  117. template int igl::unproject_in_mesh<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::Matrix<float, 2, 1, 0, 2, 1> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 1, 0, 4, 1> const&, igl::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, std::vector<igl::Hit, std::allocator<igl::Hit> >&);
  118. template int igl::unproject_in_mesh<Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::Matrix<float, 2, 1, 0, 2, 1> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 1, 0, 4, 1> const&, igl::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, std::vector<igl::Hit, std::allocator<igl::Hit> >&);
  119. #endif