Heightmap.cpp
上传用户:hkb425
上传日期:2007-06-16
资源大小:34191k
文件大小:7k
- // Heightmap.cpp: implementation of the CHeightmap class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "Heightmap.h"
- #include "stdio.h"
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- MOVE_VERTEX * CHeightmap::m_pMovemap=NULL;
- unsigned char * CHeightmap::m_pTmap=NULL;
- unsigned char * CHeightmap::m_pCovermap=NULL;
- VERTEX * CHeightmap::m_pViewPos=NULL;
- VERTEX * CHeightmap::m_pSunPos =NULL;
- float * CHeightmap::m_pViewRotX=NULL;
- float * CHeightmap::m_pViewRotY=NULL;
- bool CHeightmap::m_bSunVisible=true;
- int CHeightmap::m_numUser=0;
- BOUNDARY_2D CHeightmap::m_rect=BOUNDARY_2D(0,0,0,0);
- CHeightmap::CHeightmap()
- {
- if(m_numUser==0)
- {
- /////////read terrain map
- if(!ReadTerrainmapFile())
- {
- MessageBox(0, "read heightmap failed", "Error", MB_OK | MB_ICONERROR);
- return ;
- }
- if(!ReadPlantmapFile())
- {
- MessageBox(0, "read plantmap failed", "Error", MB_OK | MB_ICONERROR);
- return ;
- }
- m_pMovemap =new MOVE_VERTEX [256*256];
- m_pViewPos =new VERTEX;
- m_pSunPos =new VERTEX;
- m_pViewRotX=new float;
- m_pViewRotY=new float;
- }
- m_numUser++;
- }
- CHeightmap::~CHeightmap()
- {
- m_numUser--;
- if(m_pTmap!=NULL && m_pCovermap!=NULL && (m_numUser==0))
- {
- delete [] m_pTmap;
- delete [] m_pCovermap;
- delete [] m_pMovemap;
- delete m_pViewPos;
- delete m_pSunPos;
- delete m_pViewRotY;
- delete m_pViewRotX;
- m_pTmap=NULL;
- m_pCovermap=NULL;
- m_pMovemap=NULL;
- m_pViewPos=NULL;
- m_pSunPos =NULL;
- m_pViewRotY=NULL;
- m_pViewRotX=NULL;
- }
- }
- unsigned char CHeightmap::GetHeightmapPointValue(VERTEX *checked)
- {
- /*
- POINT point=ConvertToHeightmap(checked);
- return m_pTmap[256*point.y + point.x];*/
- return 0;
- }
- float CHeightmap::GetHeight(VERTEX *checked)
- {
- POINT point=ConvertToHeightmap(checked);
- float Xpos,Zpos;
- if(checked->xpos<0)
- Xpos=1+checked->xpos*0.1f-int(checked->xpos*0.1f);
- else
- Xpos=checked->xpos*0.1f-int(checked->xpos*0.1f);
- if(checked->zpos<0)
- Zpos=1+checked->zpos*0.1f-int(checked->zpos*0.1f);
- else
- Zpos=checked->zpos*0.1f-int(checked->zpos*0.1f);
- ///////////////////////
- float ypos;
- float h11,h12,h22,h21;
- float ha,hb;
- //////////check Xpos and Zpos
- ////////////////////////////
- int addx=point.x+1;
- int addy=point.y+1;
- if(addx==256)addx=0;
- if(addy==256)addy=0;
- h11=float(m_pTmap[256*(point.y+0) + (point.x+0)]);
- h12=float(m_pTmap[256*(addy) + (point.x+0)]);
- h21=float(m_pTmap[256*(point.y+0) + addx]);
- h22=float(m_pTmap[256*(addy) + addx]);
- ha=h11+Xpos*(h21-h11);
- hb=h12+Xpos*(h22-h12);
- ypos=ha +Zpos*(hb-ha);
- return ypos;
- }
- float CHeightmap::GetHeight(float xpos,float zpos)
- {
- VERTEX temp=VERTEX(xpos,0,zpos);
- float ypos=GetHeight(&temp);
- return ypos;
- }
- bool CHeightmap::CollideCheck(VERTEX viewPos,VERTEX objPos,float step)
- {
- float dy=viewPos.ypos-objPos.ypos;
- float dx=viewPos.xpos-objPos.xpos;
- float dz=viewPos.zpos-objPos.zpos;
- int signx,signy,signz;
- if(dx<0)
- {dx=-dx; signx=-1;}
- else
- signx=1;
- if(dy<0)
- {dy=-dy; signy=-1;}
- else
- signy=1;
- if(dz<0)
- {dz=-dz; signz=-1;}
- else
- signz=1;
- float terrainHeight=GetHeight(&viewPos);
- float CurLineHeight=viewPos.ypos;
-
- float CurZ=viewPos.zpos;
- float CurX=viewPos.xpos;
- if(dz>dx)
- {
- int times=int(dz/step);
- float deltaH=dy/times;
- float deltax=signx*dx*step/dz;
- for(int i=0;i<times;i++)
- {
- if(terrainHeight>CurLineHeight)return true;
- CurLineHeight -= signy*deltaH;
- terrainHeight=GetHeight(CurX,CurZ);
- CurX-=deltax;
- CurZ-=signz*step;
- }
- }
- else
- {
- int times=int(dx/step);
- float deltaH=dy/times;
- float deltaz=signz*dz*step/dx;
- for(int i=0;i<times;i++)
- {
- if(terrainHeight>CurLineHeight)return true;
- CurLineHeight -= signy*deltaH;
- terrainHeight=GetHeight(CurX,CurZ);
- CurZ-=deltaz;
- CurX-=signx*step;
- }
- }
- return false;
- }
- bool CHeightmap::IsInFrustum(VERTEX checked)
- {
- POINT point=ConvertToMovemap(checked);
- if(point.x==0 && point.y==0)return false;
- return true;
- }
- bool CHeightmap::CheckSunVisible()
- {
- if(!m_bSunVisible)return false;
- float dx=m_pViewPos->xpos-m_pSunPos->xpos ;
- float dz=m_pViewPos->zpos-m_pSunPos->zpos ;
- float dy=m_pViewPos->ypos-m_pSunPos->ypos ;
-
- float absx=dx;
- if(absx<0)absx=-absx;
- float absz=dz;
- if(absz<0)absz=-absz;
- float max=absz;
- if(absx>max)max=absx;
- max=200/max;
- dx=dx*max;
- dz=dz*max;
- dy=dy*max*0.85f;
- VERTEX checkPos=VERTEX(m_pViewPos->xpos-dx,m_pViewPos->ypos-dy,m_pViewPos->zpos-dz);
- return !CollideCheck(*m_pViewPos,checkPos,2);
- }
- POINT CHeightmap::ConvertToHeightmap(VERTEX *pos)
- {
- POINT point;
- if(pos->xpos<0)
- point.x=255+int(pos->xpos*0.1f)%256;
- else
- point.x=int(pos->xpos*0.1f)%256;
- if(pos->zpos<0)
- point.y=255+int(pos->zpos*0.1f)%256;
- else
- point.y=int(pos->zpos*0.1f)%256;
- return point;
- }
- POINT CHeightmap::ConvertToMovemap(VERTEX pos)
- {
- POINT point;
-
- point.x=int((pos.xpos-m_pViewPos->xpos)*0.05f)+128;
- point.y=int((pos.zpos-m_pViewPos->zpos)*0.05f)+128;
- if(point.x<m_rect.minx || point.x>m_rect.maxx )
- {
- POINT p;
- p.x=p.y=0;
- return p;
- }
- if(point.y<m_rect.minz || point.y>m_rect.maxz )
- {
- POINT p;
- p.x=p.y=0;
- return p;
- }
-
- return point;
- }
- bool CHeightmap::ReadTerrainmapFile()
- {
- FILE *fp;
- fp=fopen("Terrains/ter256.bmp","rb");
- if(!fp)return false;
- BITMAPFILEHEADER fileheader;
- fread(&fileheader,sizeof(BITMAPFILEHEADER),1,fp);
- if(fileheader.bfType!=19778)return false;
- m_pTmap=new unsigned char[256*256];
- if(m_pTmap==NULL)return false;
- fseek(fp,1078,SEEK_SET);
- for(int z=255;z>-1;z--)
- for(int x=0;x<256;x++)
- {
- fread(&m_pTmap[256*z+x],sizeof(unsigned char),1,fp);
- }
- fclose(fp);
- return true;
- }
- bool CHeightmap::ReadPlantmapFile()
- {
- FILE *fp;
- fp=fopen("plants/plantmap.bmp","rb");
- if(!fp)return false;
- BITMAPFILEHEADER fileheader;
- fread(&fileheader,sizeof(BITMAPFILEHEADER),1,fp);
- if(fileheader.bfType!=19778)return false;
- m_pCovermap=new unsigned char[256*256];
- if(m_pCovermap==NULL)return false;
- fseek(fp,1078,SEEK_SET);
- for(int z=255;z>-1;z--)
- for(int x=0;x<256;x++)
- {
- fread(&m_pCovermap[256*z+x],sizeof(unsigned char),1,fp);
- }
- fclose(fp);
- return true;
- }
- int CHeightmap::GetPosInMovemap(int x,int z)
- {
- return m_pMovemap[(128+z)*256+128+x].zpos*256+m_pMovemap[(128+z)*256+128+x].xpos;
- }