Frustum.cpp 2.8 KB

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