Files
Leviathan/Client/Game/engine/TerrainEngine/TerrainFaceNormalInfo.h
T
2026-06-01 12:46:52 +02:00

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