Frustum.cpp 2.6 KB

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