www.pudn.com > 3D_Tank.rar > TerrainInfo.cpp


#include "TerrainInfo.h" 
 
CTerrainInfo::CTerrainInfo() 
{} 
 
CTerrainInfo::~CTerrainInfo() 
{} 
 
VOID CTerrainInfo::InitTerrainInfo(LPCTSTR pSrcRawFile, int nCxPixel, int nCzPixel,	 
										   int nCxLength, int nCzLength) 
{ 
	m_nCxVertexCount = nCxPixel; 
	m_nCzVertexCount = nCzPixel; 
	m_nCxBlockLength = nCxLength; 
	m_nCzBlockLength = nCzLength; 
 
	m_BoundingBox.m_vMin = D3DXVECTOR3(0, 0, 0); 
	m_BoundingBox.m_vMax = D3DXVECTOR3( (nCxPixel - 1.0f) * nCxLength, 0,  
										(nCzPixel - 1.0f) * nCzLength); 
 
	std::vector in(GetVertexCount()); 
	std::ifstream inFile(pSrcRawFile, std::ios_base::binary); 
	inFile.read ((char *)&in[0], static_cast(in.size()) ); 
	inFile.close(); 
 
	int nVertex = GetVertexCount(); 
	m_vecHeight.reserve(nVertex); 
	for (int i = 0; i < nVertex; ++i) 
		m_vecHeight[i] = in[i]; 
} 
 
int CTerrainInfo::GetPolygonCount() 
{	return (m_nCxVertexCount - 1) * (m_nCzVertexCount -1) * 2;} 
 
int CTerrainInfo::GetVertexCount() 
{	return m_nCxVertexCount * m_nCzVertexCount;} 
 
int CTerrainInfo::GetCxVertexCount() 
{    return m_nCxVertexCount;} 
 
int CTerrainInfo::GetCzVertexCount() 
{    return m_nCzVertexCount;} 
 
int CTerrainInfo::GetCxBlockLength() 
{	return m_nCxBlockLength;} 
 
int CTerrainInfo::GetCzBlockLength() 
{	return m_nCzBlockLength;} 
 
 
float CTerrainInfo::GetXVertex(float x) 
{ 
    float fx = floorf( x / m_nCxBlockLength); 
	if( fx == m_nCxVertexCount) 
		--fx; 
	return fx; 
} 
 
float CTerrainInfo::GetZVertex(float z) 
{ 
	float fz = floorf( z / m_nCzBlockLength); 
	if( fz == m_nCzVertexCount) 
		--fz; 
	return fz; 
} 
//C-------D 
//|     / | 
//|   /	  | 
//| /	  | 
//A-------B 
float CTerrainInfo::GetHeight(float x, float z) 
{ 
	float FinalHeight; 
 
    int X = (int)GetXVertex(x); 
	int Z = (int)GetZVertex(z); 
 
    int HeightA = m_vecHeight[Z * m_nCxVertexCount + X]; 
	int HeightB = m_vecHeight[Z * m_nCxVertexCount + X + 1]; 
	int HeightC = m_vecHeight[Z * m_nCxVertexCount + X + m_nCxVertexCount]; 
	int HeightD = m_vecHeight[Z * m_nCxVertexCount + X + m_nCzVertexCount + 1]; 
	 
	float dx = x / m_nCxBlockLength - X; 
	float dz = z / m_nCzBlockLength - Z; 
 
	if( X == m_nCxVertexCount) 
		dx = 1; 
	if( X == m_nCzVertexCount) 
		dz = 1; 
	 
	if (dz > dx) 
	{ 
		FinalHeight = HeightC + dx*(HeightD - HeightC) + (1 - dz)*(HeightA - HeightC); 
	} 
	else 
	{ 
		FinalHeight = HeightB + (1 - dx)*(HeightA - HeightB) + dz*(HeightD - HeightB); 
	} 
	return FinalHeight; 
} 
 
VOID CTerrainInfo::GetNormal(float x, float z, D3DXVECTOR3 *vNormal) 
{ 
	int X = (int)GetXVertex(x); 
	int Z = (int)GetZVertex(z); 
 
	int HeightA = m_vecHeight[Z * m_nCxVertexCount + X]; 
	int HeightB = m_vecHeight[Z * m_nCxVertexCount + X + 1]; 
	int HeightC = m_vecHeight[Z * m_nCxVertexCount + X + m_nCxVertexCount]; 
	int HeightD = m_vecHeight[Z * m_nCxVertexCount + X + m_nCzVertexCount + 1]; 
	 
	float dx = x / m_nCxBlockLength - X; 
	float dz = z / m_nCzBlockLength - Z; 
 
	if( X == m_nCxVertexCount) 
		dx = 1; 
	if( X == m_nCzVertexCount) 
		dz = 1; 
 
	if (dz > dx) 
	{ 
		D3DXVECTOR3 v1((float)m_nCxBlockLength, (float)HeightD - HeightC, 0.0f); 
		D3DXVECTOR3 v2(0.0f, (float)HeightA - HeightC, (float)m_nCzBlockLength); 
		D3DXVec3Cross(vNormal, &v2, &v1); 
	} 
	else 
	{ 
		D3DXVECTOR3 v1((float)-m_nCxBlockLength, (float)HeightA - HeightB, 0.0f); 
		D3DXVECTOR3 v2(0.0f, (float)HeightD - HeightB, (float)-m_nCzBlockLength); 
		D3DXVec3Cross(vNormal, &v2, &v1); 
	} 
} 
 
BOOL CTerrainInfo::IsInTerrain(float x, float z) 
{ 
	if (x > m_BoundingBox.m_vMin.x && x < m_BoundingBox.m_vMax.x  
		&& z > m_BoundingBox.m_vMin.z && z < m_BoundingBox.m_vMax.z) 
		return TRUE; 
	else 
		return FALSE; 
}