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

游戏引擎

开发平台:

Visual C++

  1. // Heightmap.cpp: implementation of the CHeightmap class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "Heightmap.h"
  6. #include "stdio.h"
  7. //////////////////////////////////////////////////////////////////////
  8. // Construction/Destruction
  9. //////////////////////////////////////////////////////////////////////
  10. MOVE_VERTEX    * CHeightmap::m_pMovemap=NULL;
  11. unsigned char  * CHeightmap::m_pTmap=NULL;
  12. unsigned char  * CHeightmap::m_pCovermap=NULL;
  13. VERTEX         * CHeightmap::m_pViewPos=NULL;
  14. VERTEX         * CHeightmap::m_pSunPos =NULL;
  15. float          * CHeightmap::m_pViewRotX=NULL;
  16. float          * CHeightmap::m_pViewRotY=NULL;
  17. bool             CHeightmap::m_bSunVisible=true;
  18. int              CHeightmap::m_numUser=0;
  19. BOUNDARY_2D      CHeightmap::m_rect=BOUNDARY_2D(0,0,0,0);
  20. CHeightmap::CHeightmap()
  21. {
  22. if(m_numUser==0)
  23. {
  24. /////////read terrain map
  25.      if(!ReadTerrainmapFile())
  26. {
  27.     MessageBox(0, "read heightmap failed", "Error", MB_OK | MB_ICONERROR);
  28.     return ;
  29. }
  30.      if(!ReadPlantmapFile())
  31. {
  32.     MessageBox(0, "read plantmap failed", "Error", MB_OK | MB_ICONERROR);
  33.     return ;
  34. }
  35. m_pMovemap =new MOVE_VERTEX [256*256];
  36.         m_pViewPos =new VERTEX;
  37.         m_pSunPos  =new VERTEX;
  38. m_pViewRotX=new float;
  39. m_pViewRotY=new float;
  40. }
  41. m_numUser++;
  42. }
  43. CHeightmap::~CHeightmap()
  44. {
  45. m_numUser--;
  46. if(m_pTmap!=NULL && m_pCovermap!=NULL && (m_numUser==0))
  47. {
  48. delete [] m_pTmap;
  49. delete [] m_pCovermap;
  50. delete [] m_pMovemap;
  51. delete    m_pViewPos;
  52. delete    m_pSunPos;
  53. delete    m_pViewRotY;
  54. delete    m_pViewRotX;
  55. m_pTmap=NULL;
  56. m_pCovermap=NULL;
  57. m_pMovemap=NULL;
  58. m_pViewPos=NULL;
  59. m_pSunPos =NULL;
  60. m_pViewRotY=NULL;
  61. m_pViewRotX=NULL;
  62. }
  63. }
  64. unsigned char CHeightmap::GetHeightmapPointValue(VERTEX *checked)
  65. {
  66. /*
  67. POINT point=ConvertToHeightmap(checked);
  68. return m_pTmap[256*point.y + point.x];*/
  69. return 0;
  70. }
  71. float CHeightmap::GetHeight(VERTEX *checked)
  72. {
  73. POINT point=ConvertToHeightmap(checked);
  74. float Xpos,Zpos;
  75. if(checked->xpos<0)
  76.     Xpos=1+checked->xpos*0.1f-int(checked->xpos*0.1f);
  77. else
  78.     Xpos=checked->xpos*0.1f-int(checked->xpos*0.1f);
  79. if(checked->zpos<0)
  80.     Zpos=1+checked->zpos*0.1f-int(checked->zpos*0.1f);
  81. else 
  82. Zpos=checked->zpos*0.1f-int(checked->zpos*0.1f);
  83.     ///////////////////////
  84. float ypos;
  85. float h11,h12,h22,h21;
  86. float ha,hb;
  87. //////////check Xpos and Zpos
  88. ////////////////////////////
  89. int addx=point.x+1;
  90. int addy=point.y+1;
  91. if(addx==256)addx=0;
  92. if(addy==256)addy=0;
  93.     h11=float(m_pTmap[256*(point.y+0) + (point.x+0)]);
  94.     h12=float(m_pTmap[256*(addy) + (point.x+0)]);
  95.     h21=float(m_pTmap[256*(point.y+0) + addx]);
  96.     h22=float(m_pTmap[256*(addy) + addx]);
  97. ha=h11+Xpos*(h21-h11);
  98. hb=h12+Xpos*(h22-h12);
  99.     ypos=ha +Zpos*(hb-ha);
  100. return ypos;
  101. }
  102. float CHeightmap::GetHeight(float xpos,float zpos)
  103. {
  104.    VERTEX temp=VERTEX(xpos,0,zpos);
  105.    float ypos=GetHeight(&temp);
  106.    return ypos;
  107. }
  108. bool CHeightmap::CollideCheck(VERTEX viewPos,VERTEX objPos,float step)
  109. {
  110. float dy=viewPos.ypos-objPos.ypos;
  111. float dx=viewPos.xpos-objPos.xpos;
  112. float dz=viewPos.zpos-objPos.zpos;
  113. int signx,signy,signz;
  114. if(dx<0)
  115. {dx=-dx; signx=-1;}
  116. else
  117.         signx=1;
  118. if(dy<0)
  119. {dy=-dy; signy=-1;}
  120. else
  121.         signy=1;
  122. if(dz<0)
  123. {dz=-dz; signz=-1;}
  124. else
  125.         signz=1;
  126. float terrainHeight=GetHeight(&viewPos);
  127. float CurLineHeight=viewPos.ypos;
  128. float CurZ=viewPos.zpos;
  129. float CurX=viewPos.xpos;
  130. if(dz>dx)
  131. {
  132. int times=int(dz/step);
  133. float deltaH=dy/times;
  134. float deltax=signx*dx*step/dz;
  135.         for(int i=0;i<times;i++)
  136. {
  137. if(terrainHeight>CurLineHeight)return true;
  138.             CurLineHeight -= signy*deltaH;
  139. terrainHeight=GetHeight(CurX,CurZ);
  140. CurX-=deltax;
  141. CurZ-=signz*step;
  142. }
  143. }
  144. else
  145. {
  146. int times=int(dx/step);
  147. float deltaH=dy/times;
  148. float deltaz=signz*dz*step/dx;
  149.         for(int i=0;i<times;i++)
  150. {
  151. if(terrainHeight>CurLineHeight)return true;
  152.             CurLineHeight -= signy*deltaH;
  153. terrainHeight=GetHeight(CurX,CurZ);
  154. CurZ-=deltaz;
  155. CurX-=signx*step;
  156. }
  157. }
  158.     return false;
  159. }
  160. bool CHeightmap::IsInFrustum(VERTEX checked)
  161. {
  162. POINT point=ConvertToMovemap(checked);
  163. if(point.x==0 && point.y==0)return false;
  164. return true;
  165. }
  166. bool CHeightmap::CheckSunVisible()
  167. {
  168. if(!m_bSunVisible)return false;
  169. float dx=m_pViewPos->xpos-m_pSunPos->xpos ;
  170. float dz=m_pViewPos->zpos-m_pSunPos->zpos ;
  171. float dy=m_pViewPos->ypos-m_pSunPos->ypos ;
  172.     
  173. float absx=dx;
  174. if(absx<0)absx=-absx;
  175. float absz=dz;
  176. if(absz<0)absz=-absz;
  177. float max=absz;
  178. if(absx>max)max=absx;
  179. max=200/max;
  180. dx=dx*max;
  181. dz=dz*max;
  182. dy=dy*max*0.85f;
  183. VERTEX checkPos=VERTEX(m_pViewPos->xpos-dx,m_pViewPos->ypos-dy,m_pViewPos->zpos-dz);
  184. return !CollideCheck(*m_pViewPos,checkPos,2);
  185. }
  186. POINT CHeightmap::ConvertToHeightmap(VERTEX *pos)
  187. {
  188. POINT point;
  189. if(pos->xpos<0)
  190.     point.x=255+int(pos->xpos*0.1f)%256;
  191. else
  192. point.x=int(pos->xpos*0.1f)%256;
  193. if(pos->zpos<0)
  194.     point.y=255+int(pos->zpos*0.1f)%256;
  195. else 
  196. point.y=int(pos->zpos*0.1f)%256;
  197. return point;
  198. }
  199. POINT CHeightmap::ConvertToMovemap(VERTEX pos)
  200. {
  201.   POINT point;
  202.     
  203. point.x=int((pos.xpos-m_pViewPos->xpos)*0.05f)+128;
  204. point.y=int((pos.zpos-m_pViewPos->zpos)*0.05f)+128;
  205. if(point.x<m_rect.minx || point.x>m_rect.maxx )
  206. {   
  207. POINT p;
  208.     p.x=p.y=0;
  209. return p;
  210. }
  211. if(point.y<m_rect.minz || point.y>m_rect.maxz )
  212. {   
  213. POINT p;
  214.     p.x=p.y=0;
  215. return p;
  216. }
  217.  
  218. return point;
  219. }
  220. bool CHeightmap::ReadTerrainmapFile()
  221. {
  222. FILE *fp;
  223. fp=fopen("Terrains/ter256.bmp","rb");
  224. if(!fp)return false;
  225. BITMAPFILEHEADER fileheader;
  226. fread(&fileheader,sizeof(BITMAPFILEHEADER),1,fp);
  227. if(fileheader.bfType!=19778)return false;
  228.     m_pTmap=new unsigned char[256*256];
  229. if(m_pTmap==NULL)return false;
  230.     fseek(fp,1078,SEEK_SET);
  231. for(int z=255;z>-1;z--)
  232. for(int x=0;x<256;x++)
  233. {
  234. fread(&m_pTmap[256*z+x],sizeof(unsigned char),1,fp);
  235. }
  236. fclose(fp);
  237.     return true;
  238. }
  239. bool CHeightmap::ReadPlantmapFile()
  240. {
  241. FILE *fp;
  242. fp=fopen("plants/plantmap.bmp","rb");
  243. if(!fp)return false;
  244. BITMAPFILEHEADER fileheader;
  245. fread(&fileheader,sizeof(BITMAPFILEHEADER),1,fp);
  246. if(fileheader.bfType!=19778)return false;
  247.     m_pCovermap=new unsigned char[256*256];
  248. if(m_pCovermap==NULL)return false;
  249.     fseek(fp,1078,SEEK_SET);
  250. for(int z=255;z>-1;z--)
  251. for(int x=0;x<256;x++)
  252. {
  253. fread(&m_pCovermap[256*z+x],sizeof(unsigned char),1,fp);
  254. }
  255. fclose(fp);
  256.     return true;
  257. }
  258. int  CHeightmap::GetPosInMovemap(int x,int z)
  259. {
  260.     return m_pMovemap[(128+z)*256+128+x].zpos*256+m_pMovemap[(128+z)*256+128+x].xpos;
  261. }