Frustum.cpp 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include "math/Frustum.h"
  2. Frustum::Frustum(float fieldOfView_, float nearClip_, float farClip_)
  3. : fieldOfView(fieldOfView_), nearClip(nearClip_), farClip(farClip_) {
  4. }
  5. const Matrix& Frustum::updateProjection(const IntVector2& size) {
  6. float tan = tanf(fieldOfView * (0.5f * static_cast<float>(M_PI) / 180.0f));
  7. float q = 1.0f / tan;
  8. float aspect = static_cast<float>(size[0]) / static_cast<float>(size[1]);
  9. float diff = 1.0f / (nearClip - farClip);
  10. projection.set(0, Vector4(q / aspect, 0.0f, 0.0f, 0.0f));
  11. projection.set(1, Vector4(0.0f, q, 0.0f, 0.0f));
  12. projection.set(2, Vector4(0.0f, 0.0f, (nearClip + farClip) * diff,
  13. (2.0f * nearClip * farClip) * diff));
  14. projection.set(3, Vector4(0.0f, 0.0f, -1.0f, 0.0f));
  15. return projection;
  16. }
  17. void Frustum::updatePlanes(const Vector3& pos, const Vector3& right,
  18. const Vector3& up, const Vector3& front,
  19. const IntVector2& size) {
  20. float tan = tanf(fieldOfView * (0.5f * static_cast<float>(M_PI) / 180.0f));
  21. float aspect = static_cast<float>(size[0]) / static_cast<float>(size[1]);
  22. float halfNearHeight = tan * nearClip;
  23. float halfNearWidth = halfNearHeight * aspect;
  24. float halfFarHeight = tan * farClip;
  25. float halfFarWidth = halfFarHeight * aspect;
  26. Vector3 farCenter = pos + front * farClip;
  27. Vector3 farTopLeft =
  28. farCenter + (up * halfFarHeight) - (right * halfFarWidth);
  29. Vector3 farTopRight =
  30. farCenter + (up * halfFarHeight) + (right * halfFarWidth);
  31. Vector3 farBottomRight =
  32. farCenter - (up * halfFarHeight) + (right * halfFarWidth);
  33. Vector3 nearCenter = pos + front * nearClip;
  34. Vector3 nearTopLeft =
  35. nearCenter + (up * halfNearHeight) - (right * halfNearWidth);
  36. Vector3 nearBottomLeft =
  37. nearCenter - (up * halfNearHeight) - (right * halfNearWidth);
  38. Vector3 nearBottomRight =
  39. nearCenter - (up * halfNearHeight) + (right * halfNearWidth);
  40. planes[0] =
  41. Plane(nearBottomRight, nearTopLeft, nearBottomLeft); // near plane
  42. planes[1] = Plane(farTopRight, farBottomRight, farTopLeft); // far plane
  43. planes[2] =
  44. Plane(nearBottomRight, nearBottomLeft, farBottomRight); // bottom plane
  45. planes[3] = Plane(farTopLeft, nearTopLeft, farTopRight); // top plane
  46. planes[4] = Plane(nearBottomLeft, nearTopLeft, farTopLeft); // left plane
  47. planes[5] =
  48. Plane(farBottomRight, farTopRight, nearBottomRight); // right plane
  49. }
  50. bool Frustum::isInside(const Vector3& pos) const {
  51. for(const Plane& p : planes) {
  52. if(p.getSignedDistance(pos) < 0.0f) {
  53. return false;
  54. }
  55. }
  56. return true;
  57. }
  58. bool Frustum::isInside(const Vector3& pos, float radius) const {
  59. for(const Plane& p : planes) {
  60. if(p.getSignedDistance(pos) < -radius) {
  61. return false;
  62. }
  63. }
  64. return true;
  65. }