// computes a frustum with given far and near planes Frustum BaseCamera::CalculateFrustum( float fNear, float fFar ) { noVec3 vZ = Normalize(m_to - m_from); noVec3 vX = Normalize(Cross(m_up, vZ)); noVec3 vY = Normalize(Cross(vZ, vX)); float fAspect = GetApp()->GetAspectRatio(); float fNearPlaneHalfHeight = tanf(m_fov * 0.5f) * fNear; float fNearPlaneHalfWidth = fNearPlaneHalfHeight * fAspect; float fFarPlaneHalfHeight = tanf(m_fov * 0.5f) * fFar; float fFarPlaneHalfWidth = fFarPlaneHalfHeight * fAspect; noVec3 vNearPlaneCenter = m_from + vZ * fNear; noVec3 vFarPlaneCenter = m_from + vZ * fFar; Frustum frustum; frustum.m_pPoints[0] = noVec3(vNearPlaneCenter - vX*fNearPlaneHalfWidth - vY*fNearPlaneHalfHeight); frustum.m_pPoints[1] = noVec3(vNearPlaneCenter - vX*fNearPlaneHalfWidth + vY*fNearPlaneHalfHeight); frustum.m_pPoints[2] = noVec3(vNearPlaneCenter + vX*fNearPlaneHalfWidth + vY*fNearPlaneHalfHeight); frustum.m_pPoints[3] = noVec3(vNearPlaneCenter + vX*fNearPlaneHalfWidth - vY*fNearPlaneHalfHeight); frustum.m_pPoints[4] = noVec3(vFarPlaneCenter - vX*fFarPlaneHalfWidth - vY*fFarPlaneHalfHeight); frustum.m_pPoints[5] = noVec3(vFarPlaneCenter - vX*fFarPlaneHalfWidth + vY*fFarPlaneHalfHeight); frustum.m_pPoints[6] = noVec3(vFarPlaneCenter + vX*fFarPlaneHalfWidth + vY*fFarPlaneHalfHeight); frustum.m_pPoints[7] = noVec3(vFarPlaneCenter + vX*fFarPlaneHalfWidth - vY*fFarPlaneHalfHeight); // update frustum AABB frustum.CalculateAABB(); return frustum; }
// finds scene objects inside the camera frustum std::vector<SceneObject *> ShadowCamera::FindReceivers(void) { Frustum cameraFrustum = CalculateFrustum(m_fNearMin, m_fFarMax); cameraFrustum.CalculateAABB(); std::vector<SceneObject *> receivers; receivers.reserve(g_SceneObjects.size()); for(unsigned int i=0; i<g_SceneObjects.size(); i++) { SceneObject *pObject = g_SceneObjects[i]; // intersection test if(g_iVisibilityTest == VISTEST_ACCURATE) { // test accurately if(!IntersectionTest(pObject->m_AABB, cameraFrustum)) continue; } else if(g_iVisibilityTest == VISTEST_CHEAP) { // test only with AABB of frustum if(!IntersectionTest(pObject->m_AABB, cameraFrustum.m_AABB)) continue; } receivers.push_back(pObject); } return receivers; }