#include "svl/util/frustum.h" #include "glm/gtc/matrix_transform.hpp" /**< glm::ortho glm::perspective */ #include "glm/trigonometric.hpp" /**< glm::radians */ namespace svl { namespace util { const glm::mat4 Frustum::update(const glm::mat4 &viewMatrix) { /* * Frustum is a implementation based on a tutorial by * http://www.lighthouse3d.com/tutorials/view-frustum-culling/ */ // Update matrix and vectors glm::mat4 viewMatrixInverse = glm::inverse(viewMatrix); glm::vec3 right = glm::normalize(glm::vec3(viewMatrixInverse * glm::vec4(glm::vec3(1.0, 0.0, 0.0), 0.0))); glm::vec3 up = glm::normalize(glm::vec3(viewMatrixInverse * glm::vec4(glm::vec3(0.0, 1.0, 0.0), 0.0))); glm::vec3 direction = glm::normalize(glm::vec3(viewMatrixInverse * glm::vec4(glm::vec3(0.0, 0.0, 1.0), 0.0))); glm::vec3 position = glm::vec3(viewMatrixInverse * glm::vec4(glm::vec3(0.0, 0.0, 0.0), 1.0)); // compute the centers of the near and far planes mNearCenter = position - direction * mNearDistance; mFarCenter = position - direction * mFarDistance; // compute the 4 corners of the frustum on the near plane mNearTopLeft = mNearCenter + up * mNearHeight - right * mNearWidth; mNearTopRight = mNearCenter + up * mNearHeight + right * mNearWidth; mNearBottomLeft = mNearCenter - up * mNearHeight - right * mNearWidth; mNearBottomRight = mNearCenter - up * mNearHeight + right * mNearWidth; // compute the 4 corners of the frustum on the far plane mFarTopLeft = mFarCenter + up * mFarHeight - right * mFarWidth; mFarTopRight = mFarCenter + up * mFarHeight + right * mFarWidth; mFarBottomLeft = mFarCenter - up * mFarHeight - right * mFarWidth; mFarBottomRight = mFarCenter - up * mFarHeight + right * mFarWidth; return viewMatrixInverse; } const glm::mat4 &Frustum::perspective(float angle, float aspect, float near, float far) { mRatio = aspect; mFarDistance = far; mNearDistance = near; mAngle = angle; mProjectionMatrix = glm::perspective(glm::radians(mAngle), mRatio, mNearDistance, mFarDistance); mTanAngle = glm::tan(glm::radians(mAngle) * 0.5f); mNearHeight = mNearDistance * mTanAngle; mNearWidth = mNearHeight * mRatio; mFarHeight = mFarDistance * mTanAngle; mFarWidth = mFarHeight * mRatio; return mProjectionMatrix; } const glm::mat4 &Frustum::ortho(float xMin, float xMax, float yMin, float yMax, float zMin, float zMax) { mProjectionMatrix = glm::ortho(xMin, xMax, yMin, yMax, zMin, zMax); mNearWidth = xMax * 2.0f; mNearHeight = yMax * 2.0f; mFarWidth = mNearWidth; mFarHeight = mNearHeight; return mProjectionMatrix; } } // namespace util } // namespace svl