102 lines
3.1 KiB
C++
102 lines
3.1 KiB
C++
#pragma once
|
|
|
|
#include "TerrainDefine.h"
|
|
|
|
|
|
class CTerrainFaceNormalInfo
|
|
{
|
|
public:
|
|
struct FACENORMAL_STRUCT
|
|
{
|
|
K3DVector vtFaceNormalLower;
|
|
K3DVector vtFaceNormalUpper;
|
|
};
|
|
|
|
CTerrainFaceNormalInfo()
|
|
: m_rcTerrainArea( KRect( 0, 0, 0, 0 ) )
|
|
, m_pFaceNormals( NULL )
|
|
{
|
|
m_DefaultFaceNormal.vtFaceNormalLower = c_DefaultNormal;
|
|
m_DefaultFaceNormal.vtFaceNormalUpper = c_DefaultNormal;
|
|
}
|
|
CTerrainFaceNormalInfo( const KRect& rTerrainArea, const CTerrainInfo* pTerrainInfo = NULL )
|
|
: m_pFaceNormals( NULL )
|
|
{
|
|
m_DefaultFaceNormal.vtFaceNormalLower = c_DefaultNormal;
|
|
m_DefaultFaceNormal.vtFaceNormalUpper = c_DefaultNormal;
|
|
|
|
Initialize( rTerrainArea, pTerrainInfo );
|
|
}
|
|
virtual ~CTerrainFaceNormalInfo() { Release(); }
|
|
|
|
void Initialize( const KRect& rTerrainArea, const CTerrainInfo* pTerrainInfo = NULL )
|
|
{
|
|
Release();
|
|
m_rcTerrainArea = rTerrainArea;
|
|
|
|
int nTotalFaceNormalCount = (m_rcTerrainArea.GetWidth() * m_rcTerrainArea.GetHeight());
|
|
m_pFaceNormals = new FACENORMAL_STRUCT[ nTotalFaceNormalCount ];
|
|
|
|
Refresh( m_rcTerrainArea, pTerrainInfo );
|
|
}
|
|
void Release()
|
|
{
|
|
m_rcTerrainArea = KRect( 0, 0, 0, 0 );
|
|
SAFE_DELETE_ARRAY( m_pFaceNormals );
|
|
}
|
|
|
|
const FACENORMAL_STRUCT* GetFaceNormalData( int nX, int nY ) const
|
|
{
|
|
nX -= m_rcTerrainArea.left;
|
|
nY -= m_rcTerrainArea.top;
|
|
|
|
return ( 0 <= nX && nX < m_rcTerrainArea.GetWidth() && 0 <= nY && nY < m_rcTerrainArea.GetHeight() )
|
|
? (m_pFaceNormals + (nY * m_rcTerrainArea.GetWidth()) + nX) : &m_DefaultFaceNormal;
|
|
}
|
|
|
|
void Refresh( const KRect& rRefreshArea, const CTerrainInfo* pTerrainInfo = NULL )
|
|
{
|
|
int nSX = (rRefreshArea.left < m_rcTerrainArea.left ) ? m_rcTerrainArea.left : rRefreshArea.left ;
|
|
int nSY = (rRefreshArea.top < m_rcTerrainArea.top ) ? m_rcTerrainArea.top : rRefreshArea.top ;
|
|
int nEX = (rRefreshArea.right > m_rcTerrainArea.right ) ? m_rcTerrainArea.right : rRefreshArea.right ;
|
|
int nEY = (rRefreshArea.bottom > m_rcTerrainArea.bottom ) ? m_rcTerrainArea.bottom : rRefreshArea.bottom;
|
|
|
|
FACENORMAL_STRUCT* pStruct = m_pFaceNormals + ( (nSY - m_rcTerrainArea.left) * m_rcTerrainArea.GetWidth() ) + (nSX - m_rcTerrainArea.top);
|
|
|
|
if( NULL != pTerrainInfo )
|
|
{
|
|
for( int nY( nSY ); nY < nEY; ++nY )
|
|
{
|
|
for( int nX( nSX ); nX < nEX; ++nX )
|
|
{
|
|
K3DVertex v0 = pTerrainInfo->GetVertex( nX, nY );
|
|
K3DVertex v1 = pTerrainInfo->GetVertex( nX + 1, nY );
|
|
K3DVertex v2 = pTerrainInfo->GetVertex( nX, nY + 1 );
|
|
K3DVertex v3 = pTerrainInfo->GetVertex( nX + 1, nY + 1 );
|
|
|
|
pStruct->vtFaceNormalLower = CTerrainInfo::BuildNormalVector( v1, v0, v2 );
|
|
pStruct->vtFaceNormalUpper = CTerrainInfo::BuildNormalVector( v1, v2, v3 );
|
|
pStruct++;
|
|
}
|
|
pStruct += (m_rcTerrainArea.GetWidth() - (nEX - nSX));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( int nY( nSY ); nY < nEY; ++nY )
|
|
{
|
|
for( int nX( nSX ); nX < nEX; ++nX )
|
|
*pStruct++ = m_DefaultFaceNormal;
|
|
|
|
pStruct += (m_rcTerrainArea.GetWidth() - (nEX - nSX));
|
|
}
|
|
}
|
|
}
|
|
|
|
private:
|
|
KRect m_rcTerrainArea;
|
|
|
|
FACENORMAL_STRUCT* m_pFaceNormals;
|
|
FACENORMAL_STRUCT m_DefaultFaceNormal;
|
|
};
|