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;
}