/src/SceneGraph_SceneBase/Culler.cpp

http://github.com/Akranar/daguerreo · C++ · 79 lines · 40 code · 10 blank · 29 comment · 7 complexity · 5b7b5bfa32d3fbcf91b96919464d1f7e MD5 · raw file

  1. #include "Culler.h"
  2. #include "VisibleSet.h"
  3. #include "ExLib_RendererBase.h"
  4. #include "ExLib_BoundingVolume.h"
  5. Culler::Culler()
  6. :
  7. camera(0),
  8. visible_set(new VisibleSet())
  9. {
  10. }
  11. Culler::~Culler()
  12. {
  13. delete visible_set;
  14. }
  15. void Culler::SetFrustum()
  16. {
  17. /*
  18. const float * near_plane = camera->GetNearPlane();
  19. const float * far_plane = camera->GetFarPlane();
  20. const float * left_plane = camera->GetLeftPlane();
  21. const float * bottom_plane = camera->GetBottomPlane();
  22. const float * right_plane = camera->GetRightPlane();
  23. const float * top_plane = camera->GetTopPlane();
  24. for (unsigned int i = 0; i < 4; ++i)
  25. {
  26. frustum[0][i] = near_plane[i];
  27. frustum[1][i] = far_plane[i];
  28. frustum[2][i] = left_plane[i];
  29. frustum[3][i] = bottom_plane[i];
  30. frustum[4][i] = right_plane[i];
  31. frustum[5][i] = top_plane[i];
  32. }
  33. */
  34. }
  35. bool AABBInHalfSpace(const AABB & box, const float * plane)
  36. {
  37. /*
  38. Main Idea:
  39. -> Separating-axis test with only normal of the plane.
  40. */
  41. float radius = box.GetExtent(0) * abs(plane[0])
  42. + box.GetExtent(1) * abs(plane[1])
  43. + box.GetExtent(2) * abs(plane[2]);
  44. float signed_distance = box.GetCenter()[0] * plane[0]
  45. + box.GetCenter()[1] * plane[1]
  46. + box.GetCenter()[2] * plane[2]
  47. + plane[3];
  48. return signed_distance + radius >= 0; //Only test if box is in positive side of plane.
  49. }
  50. /*
  51. bool SphereInHalfSpace(const BoundingSphere & sphere, const Plane & plane)
  52. {
  53. float signed_distance = plane.GetNormal().dot(sphere.GetCenter()) + plane.GetD();
  54. return signed_distance + sphere.GetRadius() >= 0; //Only test if sphere is in positive side of plane.
  55. }
  56. */
  57. bool Culler::IsVisible(const BoundingVolume * bound) const
  58. {
  59. if (!bound) return false;
  60. const AABB * box = static_cast<const AABB *>(bound);
  61. if (!AABBInHalfSpace(*box, frustum[0])) return false;
  62. if (!AABBInHalfSpace(*box, frustum[1])) return false;
  63. if (!AABBInHalfSpace(*box, frustum[2])) return false;
  64. if (!AABBInHalfSpace(*box, frustum[3])) return false;
  65. if (!AABBInHalfSpace(*box, frustum[4])) return false;
  66. if (!AABBInHalfSpace(*box, frustum[5])) return false;
  67. return true;
  68. }