Frustum.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #include "math/Frustum.hpp"
  2. Core::Frustum::Frustum(float fieldOfView, float nearClip_, float farClip_)
  3. : projection(), planes(),
  4. tan(Core::Math::tan(Core::Math::degreeToRadian(fieldOfView) * 0.5f)),
  5. nearClip(nearClip_), farClip(farClip_) {
  6. float diff = 1.0f / (nearClip - farClip);
  7. projection.set(1, Vector4(0.0f, 1.0f / tan, 0.0f, 0.0f));
  8. projection.set(2, Vector4(0.0f, 0.0f, (nearClip + farClip) * diff,
  9. (2.0f * nearClip * farClip) * diff));
  10. projection.set(3, Vector4(0.0f, 0.0f, -1.0f, 0.0f));
  11. }
  12. const Core::Matrix& Core::Frustum::updateProjection(const IntVector2& size) {
  13. projection.set(0, Vector4(static_cast<float>(size[1]) /
  14. (tan * static_cast<float>(size[0])),
  15. 0.0f, 0.0f, 0.0f));
  16. return projection;
  17. }
  18. void Core::Frustum::updatePlanes(const Vector3& pos, const Vector3& right,
  19. const Vector3& up, const Vector3& front,
  20. const IntVector2& size) {
  21. float aspect = static_cast<float>(size[0]) / static_cast<float>(size[1]);
  22. float hNearHeight = tan * nearClip;
  23. float hNearWidth = hNearHeight * aspect;
  24. float hFarHeight = tan * farClip;
  25. float hFarWidth = hFarHeight * aspect;
  26. Vector3 fCenter = pos + front * farClip;
  27. Vector3 fTopLeft = fCenter + (up * hFarHeight) - (right * hFarWidth);
  28. Vector3 fTopRight = fCenter + (up * hFarHeight) + (right * hFarWidth);
  29. Vector3 fBottomRight = fCenter - (up * hFarHeight) + (right * hFarWidth);
  30. Vector3 nCenter = pos + front * nearClip;
  31. Vector3 nTopLeft = nCenter + (up * hNearHeight) - (right * hNearWidth);
  32. Vector3 nBottomLeft = nCenter - (up * hNearHeight) - (right * hNearWidth);
  33. Vector3 nBottomRight = nCenter - (up * hNearHeight) + (right * hNearWidth);
  34. planes[0] = Plane(nBottomRight, nTopLeft, nBottomLeft); // n plane
  35. planes[1] = Plane(fTopRight, fBottomRight, fTopLeft); // f plane
  36. planes[2] = Plane(nBottomRight, nBottomLeft, fBottomRight); // bottom plane
  37. planes[3] = Plane(fTopLeft, nTopLeft, fTopRight); // top plane
  38. planes[4] = Plane(nBottomLeft, nTopLeft, fTopLeft); // left plane
  39. planes[5] = Plane(fBottomRight, fTopRight, nBottomRight); // right plane
  40. }
  41. bool Core::Frustum::isInside(const Vector3& pos) const {
  42. for(const Plane& p : planes) {
  43. if(p.getSignedDistance(pos) < 0.0f) {
  44. return false;
  45. }
  46. }
  47. return true;
  48. }
  49. bool Core::Frustum::isInside(const Vector3& pos, float radius) const {
  50. for(const Plane& p : planes) {
  51. if(p.getSignedDistance(pos) < -radius) {
  52. return false;
  53. }
  54. }
  55. return true;
  56. }