Frustum.pkg 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. $#include "Frustum.h"
  2. /// Frustum planes.
  3. enum FrustumPlane
  4. {
  5. PLANE_NEAR = 0,
  6. PLANE_LEFT,
  7. PLANE_RIGHT,
  8. PLANE_UP,
  9. PLANE_DOWN,
  10. PLANE_FAR,
  11. };
  12. static const unsigned NUM_FRUSTUM_PLANES;
  13. static const unsigned NUM_FRUSTUM_VERTICES;
  14. /// Convex constructed of 6 planes.
  15. class Frustum
  16. {
  17. public:
  18. /// Construct undefined.
  19. Frustum();
  20. /// Copy-construct from another frustum.
  21. Frustum(const Frustum& frustum);
  22. /// Define with projection parameters and a transform matrix.
  23. void Define(float fov, float aspectRatio, float zoom, float nearZ, float farZ, const Matrix3x4& transform = Matrix3x4::IDENTITY);
  24. /// Define with near and far dimension vectors and a transform matrix.
  25. void Define(const Vector3& near, const Vector3& far, const Matrix3x4& transform = Matrix3x4::IDENTITY);
  26. /// Define with a bounding box and a transform matrix.
  27. void Define(const BoundingBox& box, const Matrix3x4& transform = Matrix3x4::IDENTITY);
  28. /// Define with orthographic projection parameters and a transform matrix.
  29. void DefineOrtho(float orthoSize, float aspectRatio, float zoom, float nearZ, float farZ, const Matrix3x4& transform = Matrix3x4::IDENTITY);
  30. /// Transform by a 3x3 matrix.
  31. void Transform(const Matrix3& transform);
  32. /// Transform by a 3x4 matrix.
  33. void Transform(const Matrix3x4& transform);
  34. /// Test if a point is inside or outside.
  35. Intersection IsInside(const Vector3& point) const
  36. {
  37. for (unsigned i = 0; i < NUM_FRUSTUM_PLANES; ++i)
  38. {
  39. if (planes_[i].Distance(point) < 0.0f)
  40. return OUTSIDE;
  41. }
  42. return INSIDE;
  43. }
  44. /// Test if a sphere is inside, outside or intersects.
  45. Intersection IsInside(const Sphere& sphere) const
  46. {
  47. bool allInside = true;
  48. for (unsigned i = 0; i < NUM_FRUSTUM_PLANES; ++i)
  49. {
  50. float dist = planes_[i].Distance(sphere.center_);
  51. if (dist < -sphere.radius_)
  52. return OUTSIDE;
  53. else if (dist < sphere.radius_)
  54. allInside = false;
  55. }
  56. return allInside ? INSIDE : INTERSECTS;
  57. }
  58. /// Test if a sphere if (partially) inside or outside.
  59. Intersection IsInsideFast(const Sphere& sphere) const
  60. {
  61. for (unsigned i = 0; i < NUM_FRUSTUM_PLANES; ++i)
  62. {
  63. if (planes_[i].Distance(sphere.center_) < -sphere.radius_)
  64. return OUTSIDE;
  65. }
  66. return INSIDE;
  67. }
  68. /// Test if a bounding box is inside, outside or intersects.
  69. Intersection IsInside(const BoundingBox& box) const
  70. {
  71. Vector3 center = box.Center();
  72. Vector3 edge = center - box.min_;
  73. bool allInside = true;
  74. for (unsigned i = 0; i < NUM_FRUSTUM_PLANES; ++i)
  75. {
  76. const Plane& plane = planes_[i];
  77. float dist = plane.normal_.DotProduct(center) - plane.intercept_;
  78. float absDist = plane.absNormal_.DotProduct(edge);
  79. if (dist < -absDist)
  80. return OUTSIDE;
  81. else if (dist < absDist)
  82. allInside = false;
  83. }
  84. return allInside ? INSIDE : INTERSECTS;
  85. }
  86. /// Test if a bounding box is (partially) inside or outside.
  87. Intersection IsInsideFast(const BoundingBox& box) const
  88. {
  89. Vector3 center = box.Center();
  90. Vector3 edge = center - box.min_;
  91. for (unsigned i = 0; i < NUM_FRUSTUM_PLANES; ++i)
  92. {
  93. const Plane& plane = planes_[i];
  94. float dist = plane.normal_.DotProduct(center) - plane.intercept_;
  95. float absDist = plane.absNormal_.DotProduct(edge);
  96. if (dist < -absDist)
  97. return OUTSIDE;
  98. }
  99. return INSIDE;
  100. }
  101. /// Return distance of a point to the frustum, or 0 if inside.
  102. float Distance(const Vector3& point) const
  103. {
  104. float distance = 0.0f;
  105. for (unsigned i = 0; i < NUM_FRUSTUM_PLANES; ++i)
  106. distance = Max(-planes_[i].Distance(point), distance);
  107. return distance;
  108. }
  109. /// Return transformed by a 3x3 matrix.
  110. Frustum Transformed(const Matrix3& transform) const;
  111. /// Return transformed by a 3x4 matrix.
  112. Frustum Transformed(const Matrix3x4& transform) const;
  113. /// Return projected by a 4x4 projection matrix.
  114. Rect Projected(const Matrix4& transform) const;
  115. /// Update the planes. Called internally.
  116. void UpdatePlanes();
  117. };