|

楼主 |
发表于 2014-9-3 13:55:03
|
显示全部楼层
找到答案了:
http://hi.baidu.com/laizhishen/item/bd0aedf1850316c9521c265e
贴下代码- class CFrustum
- {
- public:
- CFrustum() {}
- ~CFrustum() {}
- public:
- void InitFrustum(const D3DXMATRIX& aoViewMatrix,const D3DXMATRIX& aoProjMatrix);
- BOOL PointInFrustum(float afX, float afY, float afZ);
- BOOL SphereInFrustum(float afX, float afY, float afZ, float AfRadius );
- BOOL CubeInFrustum(float afX, float afY, float afZ, float aiSize,BOOL& abIsCompletelyContained);
- private:
- enum
- {
- FRUSTUM_PLANE_NEAR = 0,
- FRUSTUM_PLANE_FAR = 1,
- FRUSTUM_PLANE_LEFT = 2,
- FRUSTUM_PLANE_RIGHT = 3,
- FRUSTUM_PLANE_TOP = 4,
- FRUSTUM_PLANE_BOTTOM = 5,
- FRUSTUM_PLANE_COUNT,
- };
- private:
- D3DXPLANE moFrustumPlane[FRUSTUM_PLANE_COUNT];
- };
- void CFrustum::InitFrustum(const D3DXMATRIX& aoViewMatrix,const D3DXMATRIX& aoProjMatrix)
- {
- D3DXMATRIX loComboMatrix;
- D3DXMatrixMultiply(&loComboMatrix,&aoViewMatrix, &aoProjMatrix);
- // calculate the planes
- // Near
- D3DXPLANE* lpPlane = &moFrustumPlane[FRUSTUM_PLANE_NEAR];
- lpPlane->a = loComboMatrix._14 + loComboMatrix._13;
- lpPlane->b = loComboMatrix._24 + loComboMatrix._23;
- lpPlane->c = loComboMatrix._34 + loComboMatrix._33;
- lpPlane->d = loComboMatrix._44 + loComboMatrix._43;
- D3DXPlaneNormalize(lpPlane,lpPlane);
- // Far
- lpPlane = &moFrustumPlane[FRUSTUM_PLANE_FAR];
- lpPlane->a = loComboMatrix._14 - loComboMatrix._13;
- lpPlane->b = loComboMatrix._24 - loComboMatrix._23;
- lpPlane->c = loComboMatrix._34 - loComboMatrix._33;
- lpPlane->d = loComboMatrix._44 - loComboMatrix._43;
- D3DXPlaneNormalize(lpPlane,lpPlane);
- //Left
- lpPlane = &moFrustumPlane[FRUSTUM_PLANE_LEFT];
- lpPlane->a = loComboMatrix._14 + loComboMatrix._11; // Left
- lpPlane->b = loComboMatrix._24 + loComboMatrix._21;
- lpPlane->c = loComboMatrix._34 + loComboMatrix._31;
- lpPlane->d = loComboMatrix._44 + loComboMatrix._41;
- D3DXPlaneNormalize(lpPlane,lpPlane);
- // Right
- lpPlane = &moFrustumPlane[FRUSTUM_PLANE_RIGHT];
- lpPlane->a = loComboMatrix._14 - loComboMatrix._11;
- lpPlane->b = loComboMatrix._24 - loComboMatrix._21;
- lpPlane->c = loComboMatrix._34 - loComboMatrix._31;
- lpPlane->d = loComboMatrix._44 - loComboMatrix._41;
- D3DXPlaneNormalize(lpPlane,lpPlane);
- // Top
- lpPlane = &moFrustumPlane[FRUSTUM_PLANE_TOP];
- lpPlane->a = loComboMatrix._14 - loComboMatrix._12;
- lpPlane->b = loComboMatrix._24 - loComboMatrix._22;
- lpPlane->c = loComboMatrix._34 - loComboMatrix._32;
- lpPlane->d = loComboMatrix._44 - loComboMatrix._42;
- D3DXPlaneNormalize(lpPlane,lpPlane);
- // Bottom
- lpPlane = &moFrustumPlane[FRUSTUM_PLANE_BOTTOM];
- lpPlane->a = loComboMatrix._14 + loComboMatrix._12; // Bottom
- lpPlane->b = loComboMatrix._24 + loComboMatrix._22;
- lpPlane->c = loComboMatrix._34 + loComboMatrix._32;
- lpPlane->d = loComboMatrix._44 + loComboMatrix._42;
- D3DXPlaneNormalize(lpPlane,lpPlane);
- }
- BOOL CFrustum::PointInFrustum(float afX, float afY, float afZ )
- {
- // A*x+B*y+C*z+D = 0 is inplane,
- for(int i = 0; i < FRUSTUM_PLANE_COUNT; i++)
- {
- D3DXPLANE &loPlane = moFrustumPlane[i];
- //减少函数调用
- //if(D3DXPlaneDotCoord(&moFrustumPlane[i],&D3DXVECTOR3(afX, afY, afZ)) <0.0f)
- if(loPlane.a * afX + loPlane.b * afY + loPlane.c * afZ +loPlane.d < 0.0f)
- return FALSE;
- }
- return TRUE;
- }
- BOOL CFrustum::SphereInFrustum(float afX, float afY, float afZ, float AfRadius)
- {
- // A*x+B*y+C*z+D = -radius is inplane,
- for(int i = 0; i < FRUSTUM_PLANE_COUNT; i++)
- {
- D3DXPLANE &loPlane = moFrustumPlane[i];
- //减少函数调用,直接用公式运算
- //if(D3DXPlaneDotCoord(&moFrustumPlane[i],&D3DXVECTOR3(afX, afY, afZ)) <-AfRadius)
- if( loPlane.a * afX + loPlane.b * afY + loPlane.c * afZ +loPlane.d <= -AfRadius )
- return false;
- }
- return TRUE;
- }
- BOOL CFrustum::CubeInFrustum(float afX, float afY, float afZ, float aiSize,BOOL& abIsCompletelyContained)
- {
- float lfAlfaX = afX + aiSize;
- float lfDeltaX = afX - aiSize;
- float lfAlfaY = afY + aiSize;
- float lfDeltaY = afY - aiSize;
- float lfAlfaZ = afZ + aiSize;
- float lfDeltaZ = afZ - aiSize;
- DWORD ldwNumPointInFrustum = 0;
- for(int i = 0; i < FRUSTUM_PLANE_COUNT; i++)
- {
- int j = 8;
- BOOL lbIsInAllPlanes = TRUE;
- D3DXPLANE &loPlane = moFrustumPlane[i];
- //if(D3DXPlaneDotCoord(&loPlane[i],&D3DXVECTOR3(lfDeltaX,lfDeltaY, lfDeltaZ))< 0.0f)
- if(loPlane.a * lfDeltaX + loPlane.b * lfDeltaY + loPlane.c *lfDeltaZ + loPlane.d < 0.0f)
- {
- lbIsInAllPlanes = FALSE;
- j--;
- }
- //if(D3DXPlaneDotCoord(&loPlane[i],&D3DXVECTOR3(lfAlfaX,lfDeltaY, lfDeltaZ))< 0.0f)
- if(loPlane.a * lfAlfaX + loPlane.b * lfDeltaY + loPlane.c *lfDeltaZ + loPlane.d < 0.0f)
- {
- lbIsInAllPlanes = FALSE;
- j--;
- }
- //if(D3DXPlaneDotCoord(&loPlane[i],&D3DXVECTOR3(lfDeltaX,lfAlfaY, lfDeltaZ))< 0.0f)
- if(loPlane.a * lfDeltaX + loPlane.b * lfAlfaY + loPlane.c *lfDeltaZ + loPlane.d < 0.0f)
- {
- lbIsInAllPlanes = FALSE;
- j--;
- }
- //if(D3DXPlaneDotCoord(&loPlane[i],&D3DXVECTOR3(lfAlfaX,lfAlfaY, lfAlfaZ))< 0.0f)
- if(loPlane.a * lfAlfaX + loPlane.b * lfAlfaY + loPlane.c *lfDeltaZ + loPlane.d < 0.0f)
- {
- lbIsInAllPlanes = FALSE;
- j--;
- }
- //if(D3DXPlaneDotCoord(&loPlane[i],&D3DXVECTOR3(lfDeltaX,lfDeltaY, lfAlfaZ))< 0.0f)
- if(loPlane.a * lfDeltaX + loPlane.b * lfDeltaY + loPlane.c *lfAlfaZ + loPlane.d < 0.0f)
- {
- lbIsInAllPlanes = FALSE;
- j--;
- }
- //if(D3DXPlaneDotCoord(&loPlane[i],&D3DXVECTOR3(lfAlfaX,lfDeltaY, lfAlfaZ))< 0.0f)
- if(loPlane.a * lfAlfaX + loPlane.b * lfDeltaY + loPlane.c *lfAlfaZ + loPlane.d < 0.0f)
- {
- lbIsInAllPlanes = FALSE;
- j--;
- }
- //if(D3DXPlaneDotCoord(&loPlane[i],&D3DXVECTOR3(lfDeltaX,lfDeltaY, lfAlfaZ))< 0.0f)
- if(loPlane.a * lfDeltaX + loPlane.b * lfDeltaY + loPlane.c *lfAlfaZ + loPlane.d < 0.0f)
- {
- lbIsInAllPlanes = FALSE;
- j--;
- }
- //if(D3DXPlaneDotCoord(&loPlane[i],&D3DXVECTOR3(lfAlfaX,lfAlfaY, lfAlfaZ))< 0.0f)
- if(loPlane.a * lfAlfaX + loPlane.b * lfAlfaY + loPlane.c *lfAlfaZ + loPlane.d < 0.0f)
- {
- lbIsInAllPlanes = FALSE;
- j--;
- }
- // if none contained, return FALSE.
- if(0 == j)
- return FALSE;
- // update counter if they were all in front of plane.
- if(lbIsInAllPlanes)
- ++ldwNumPointInFrustum;
- }
- abIsCompletelyContained = (BOOL)(ldwNumPointInFrustum ==FRUSTUM_PLANE_COUNT);
- return TRUE;
- }
复制代码 |
|