Frustum.cpp 2.8 KB

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