FrustumCull.cpp
上传用户:hkb425
上传日期:2007-06-16
资源大小:34191k
文件大小:5k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. // FrustumCull.cpp: implementation of the CFrustumCull class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "FrustumCull.h"
  6. #include <math.h>
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char THIS_FILE[]=__FILE__;
  10. #define new DEBUG_NEW
  11. #endif
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction/Destruction
  14. //////////////////////////////////////////////////////////////////////
  15. CFrustumCull::CFrustumCull()
  16. {  
  17. m_HalfFOV=40;
  18. m_ViewerRotate=0;
  19. m_ViewDistance=30;
  20.     m_ViewerX=m_ViewerZ=0;
  21. m_ViewLeftX=m_ViewLeftZ=0;
  22. m_ViewRightX=m_ViewRightZ=0;
  23.     m_FarFoucsX=m_FarFoucsZ=0;
  24. m_BackLeftX=m_BackLeftZ=0;
  25. m_BackRightX=m_BackRightZ=0;
  26.     m_MaxX=m_MaxZ=0;
  27. m_MinX=m_MinZ=256;
  28. for(int i=0;i<128;i++)
  29. {
  30. m_LeftArray[i]=0;
  31. m_RightArray[i]=0;
  32. }
  33. }
  34. void CFrustumCull::InitFrustumCull(int halfFOV,int distance)
  35. {
  36. m_HalfFOV=halfFOV;
  37. m_ViewDistance=distance;
  38. if(m_ViewDistance>125)m_ViewDistance=125;
  39. }
  40. CFrustumCull::~CFrustumCull()
  41. {
  42. }
  43. void CFrustumCull::UpdateFrustumCull(float angle)
  44. {
  45. /////////////update viewer rotate //////
  46.     m_ViewerRotate=angle;
  47.     /////////////////////////////////////////////
  48.     ///////////// Calculate Frustum /////////////
  49.     /////////////////////////////////////////////
  50. ///////////////get view back,left and right
  51.     m_BackLeftX =-int(4*sinf((m_ViewerRotate+150)*0.01745329f));
  52.     m_BackLeftZ =-int(4*cosf((m_ViewerRotate+150)*0.01745329f));
  53.     m_BackRightX=-int(4*sinf((m_ViewerRotate-150)*0.01745329f));
  54.     m_BackRightZ=-int(4*cosf((m_ViewerRotate-150)*0.01745329f));
  55.     m_FarFoucsX =-int(m_ViewDistance*sinf(m_ViewerRotate*0.01745329f));
  56. m_FarFoucsZ =-int(m_ViewDistance*cosf(m_ViewerRotate*0.01745329f));
  57.     m_ViewLeftX =-int(m_ViewDistance*sinf((m_ViewerRotate+m_HalfFOV)*0.01745329f));
  58.     m_ViewLeftZ =-int(m_ViewDistance*cosf((m_ViewerRotate+m_HalfFOV)*0.01745329f));
  59.     m_ViewRightX=-int(m_ViewDistance*sinf((m_ViewerRotate-m_HalfFOV)*0.01745329f));
  60.     m_ViewRightZ=-int(m_ViewDistance*cosf((m_ViewerRotate-m_HalfFOV)*0.01745329f));
  61. ////////////////get Rectangle boundary
  62.     m_MaxX=m_MaxZ=0;
  63. m_MinX=m_MinZ=256;
  64.     if(m_ViewLeftX>m_MaxX)m_MaxX=m_ViewLeftX;
  65.     if(m_ViewLeftZ>m_MaxZ)m_MaxZ=m_ViewLeftZ;
  66.     if(m_ViewRightX>m_MaxX)m_MaxX=m_ViewRightX;
  67.     if(m_ViewRightZ>m_MaxZ)m_MaxZ=m_ViewRightZ;
  68.     if(m_FarFoucsX>m_MaxX)m_MaxX=m_FarFoucsX;
  69.     if(m_FarFoucsZ>m_MaxZ)m_MaxZ=m_FarFoucsZ;
  70.     if(m_BackLeftX>m_MaxX)m_MaxX=m_BackLeftX;
  71.     if(m_BackLeftZ>m_MaxZ)m_MaxZ=m_BackLeftZ;
  72.     if(m_BackRightX>m_MaxX)m_MaxX=m_BackRightX;
  73.     if(m_BackRightZ>m_MaxZ)m_MaxZ=m_BackRightZ;
  74.     if(m_ViewLeftX<m_MinX)m_MinX=m_ViewLeftX;
  75.     if(m_ViewLeftZ<m_MinZ)m_MinZ=m_ViewLeftZ;
  76.     if(m_ViewRightX<m_MinX)m_MinX=m_ViewRightX;
  77.     if(m_ViewRightZ<m_MinZ)m_MinZ=m_ViewRightZ;
  78.     if(m_FarFoucsX<m_MinX)m_MinX=m_FarFoucsX;
  79.     if(m_FarFoucsZ<m_MinZ)m_MinZ=m_FarFoucsZ;
  80.     if(m_BackLeftX<m_MinX)m_MinX=m_BackLeftX;
  81.     if(m_BackLeftZ<m_MinZ)m_MinZ=m_BackLeftZ;
  82.     if(m_BackRightX<m_MinX)m_MinX=m_BackRightX;
  83.     if(m_BackRightZ<m_MinZ)m_MinZ=m_BackRightZ;
  84. /////////////////Fill array//////////////////////////////
  85.     BresenhamFill(m_ViewLeftX,m_ViewLeftZ,m_FarFoucsX,m_FarFoucsZ,
  86.           m_LeftArray);
  87.     BresenhamFill(m_FarFoucsX,m_FarFoucsZ,m_ViewRightX,m_ViewRightZ,
  88.           m_RightArray);
  89. ///////////// GOOD WORK !!!!
  90. ///////////// Now ,we get two boundary array
  91. }
  92. void CFrustumCull::BresenhamFill(int startx,int startz,int endx,int endz, char *pArray)
  93. {
  94.     ///////////// Bresenham Line
  95. int    dx=1;
  96. int    dz=1;
  97. int    x, z;
  98. int    d;
  99. int    SignX,SignZ;
  100. bool   bChange;
  101. if(endx>startx)
  102. {
  103. dx=endx-startx;
  104. SignX=1;
  105. }
  106. else
  107. {
  108. dx=startx-endx;
  109. SignX=-1;
  110. }
  111. if(endz>startz)
  112. {
  113. dz=endz-startz;
  114. SignZ=1;
  115. }
  116. else
  117. {
  118. dz=startz-endz;
  119. SignZ=-1;
  120. }
  121.     x=startx;
  122. z=startz;
  123. if(dz>dx)
  124. {
  125. int temp;
  126.   temp=dx; dx=dz;dz=temp;
  127. bChange=true;
  128.         pArray[124]=dx+1;      //存储个数
  129.         pArray[125]=startz;  //起始
  130.         pArray[126]=endz;    //结束
  131.         pArray[127]=1;       //Z轴加
  132. }
  133. else
  134. {
  135. bChange=false;
  136.         pArray[124]=dx+1;      //存储个数
  137.         pArray[125]=startx;  //起始
  138.         pArray[126]=endx;    //结束
  139.         pArray[127]=0;       //X轴加
  140. }
  141. d=2*dz-dx;
  142. ////////////////////////
  143. for(int i=0;i<dx+1;i++)
  144. {
  145.     if(bChange)
  146.             pArray[i]=x;
  147.         else
  148.             pArray[i]=z;
  149. if(d>=0)
  150. {
  151. if(bChange) x+=SignX;
  152. else z+=SignZ;
  153. d=d-dx*2;
  154. }
  155.         if(bChange)z+=SignZ;
  156. else x+=SignX;
  157. d=d+dz*2;
  158. }
  159. }