// ViewFrustum.cpp: implementation of the CViewFrustum class. // ////////////////////////////////////////////////////////////////////// #include "ViewFrustum.h" #include "SceneManager.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CViewFrustum::CViewFrustum() { } CViewFrustum::~CViewFrustum() { } void CViewFrustum::Update() { LPDIRECT3DDEVICE8 device; D3DXMATRIX view; D3DXMATRIX project; D3DXMATRIX clip; device = CSceneManager::GetDevice(); device->GetTransform(D3DTS_VIEW,&view); device->GetTransform(D3DTS_PROJECTION,&project); D3DXMatrixMultiply(&clip,&view,&project); //left plane m_Frustum[LEFT_P].a = clip._14 + clip._11; m_Frustum[LEFT_P].b = clip._24 + clip._21; m_Frustum[LEFT_P].c = clip._34 + clip._31; m_Frustum[LEFT_P].d = clip._44 + clip._41; //right plane m_Frustum[RIGHT_P].a = clip._14 - clip._11; m_Frustum[RIGHT_P].b = clip._24 - clip._21; m_Frustum[RIGHT_P].c = clip._34 - clip._31; m_Frustum[RIGHT_P].d = clip._44 - clip._41; //top plane m_Frustum[TOP_P].a = clip._14 - clip._12; m_Frustum[TOP_P].b = clip._24 - clip._22; m_Frustum[TOP_P].c = clip._34 - clip._32; m_Frustum[TOP_P].d = clip._44 - clip._42; //bottom plane m_Frustum[BOTTOM_P].a = clip._14 + clip._12; m_Frustum[BOTTOM_P].b = clip._24 + clip._22; m_Frustum[BOTTOM_P].c = clip._34 + clip._32; m_Frustum[BOTTOM_P].d = clip._44 + clip._42; //near plane m_Frustum[NEAR_P].a = clip._13; m_Frustum[NEAR_P].b = clip._23; m_Frustum[NEAR_P].c = clip._33; m_Frustum[NEAR_P].d = clip._43; //far plane m_Frustum[FAR_P].a = clip._14 - clip._13; m_Frustum[FAR_P].b = clip._24 - clip._23; m_Frustum[FAR_P].c = clip._34 - clip._33; m_Frustum[FAR_P].d = clip._44 - clip._43; //normalize plane for(int i=0;i<6;i++) D3DXPlaneNormalize(&(m_Frustum[i]),&(m_Frustum[i])); } bool CViewFrustum::PointInFrustum(float x,float y,float z) { for(int i=0;i<6;i++) { float fvalue = m_Frustum[i].a * x + m_Frustum[i].b * y + m_Frustum[i].c * z + m_Frustum[i].d; if(fvalue <= 0) return false; //point not in frustum } // point in frustum return true; } bool CViewFrustum::SphereInFrustum(float x,float y,float z,float rad){ for(int i=0;i<6;i++) { float fvalue = m_Frustum[i].a * x + m_Frustum[i].b * y + m_Frustum[i].c * z + m_Frustum[i].d; if(fvalue <= -rad) return false; //Sphere not in frustum } // Sphere in frustum return true; } bool CViewFrustum::BoxInFrustum(int *vecMin,int *vecMax) { for(int i = 0; i < 6; i++ ) { if(m_Frustum[i].a * vecMin[0] + m_Frustum[i].b * vecMin[1] + m_Frustum[i].c * vecMin[2] + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMax[0] + m_Frustum[i].b * vecMin[1] + m_Frustum[i].c * vecMin[2] + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMin[0] + m_Frustum[i].b * vecMax[1] + m_Frustum[i].c * vecMin[2] + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMax[0] + m_Frustum[i].b * vecMax[1] + m_Frustum[i].c * vecMin[2] + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMin[0] + m_Frustum[i].b * vecMin[1] + m_Frustum[i].c * vecMax[2] + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMax[0] + m_Frustum[i].b * vecMin[1] + m_Frustum[i].c * vecMax[2] + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMin[0] + m_Frustum[i].b * vecMax[1] + m_Frustum[i].c * vecMax[2] + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMax[0] + m_Frustum[i].b * vecMax[1] + m_Frustum[i].c * vecMax[2] + m_Frustum[i].d > 0) continue; // If we get here, it isn't in the frustum return false; } // Return a true for the box being inside of the frustum return true; } bool CViewFrustum::BoxInFrustum(D3DXVECTOR3 vecMin,D3DXVECTOR3 vecMax) { for(int i = 0; i < 6; i++ ) { if(m_Frustum[i].a * vecMin.x + m_Frustum[i].b * vecMin.y + m_Frustum[i].c * vecMin.z + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMax.x + m_Frustum[i].b * vecMin.y + m_Frustum[i].c * vecMin.z + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMin.x + m_Frustum[i].b * vecMax.y + m_Frustum[i].c * vecMin.z + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMax.x + m_Frustum[i].b * vecMax.y + m_Frustum[i].c * vecMin.z + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMin.x + m_Frustum[i].b * vecMin.y + m_Frustum[i].c * vecMax.z + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMax.x + m_Frustum[i].b * vecMin.y + m_Frustum[i].c * vecMax.z + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMin.x + m_Frustum[i].b * vecMax.y + m_Frustum[i].c * vecMax.z + m_Frustum[i].d > 0) continue; if(m_Frustum[i].a * vecMax.x + m_Frustum[i].b * vecMax.y + m_Frustum[i].c * vecMax.z + m_Frustum[i].d > 0) continue; // If we get here, it isn't in the frustum return false; } // Return a true for the box being inside of the frustum return true; } bool CViewFrustum::BoxInFrustum(RCullingBox *BoundB) { BYTE bOutside[8]; ZeroMemory( &bOutside, sizeof(bOutside) ); //bound box check in frustum for( int iPoint = 0; iPoint < 8; iPoint++) { for( int iPlane = 0; iPlane < 6; iPlane++) { // bound box Á¡ÀÌ frustum plane ¿ÜºÎ¿¡ ÀÖÀ»¶§ if((m_Frustum[iPlane].a * (BoundB->m_WorldBound[iPoint].x) + m_Frustum[iPlane].b * (BoundB->m_WorldBound[iPoint].y) + m_Frustum[iPlane].c * (BoundB->m_WorldBound[iPoint].z) + m_Frustum[iPlane].d) < 0) { //¿ÜºÎ¿¡ Á¸Àç ÇÒ¶§ 1 bit setting bOutside[iPoint] |= (1 << iPlane); } } // bound box inside frustum. if( bOutside[iPoint] == 0 ) return true; } return false; }