Frustum.cpp 2.7 KB

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