2024-12-21 10:04:04 +08:00
# include "StdAfx.h"
# include "EtConvexVolume.h"
# include "EtCollisionFunc.h"
# include "EtLoader.h"
# include "EtTerrainArea.h"
# include "EtLayeredMultiUVTerrain.h"
# include "EtOptionController.h"
# include "EtGrassBlock.h"
# include "EtDrawQuad.h"
# include "EtWater.h"
# include "EtShadowMap.h"
# ifdef _DEBUG
# define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
# endif
using namespace EternityEngine ;
DECL_SMART_PTR_STATIC ( CEtTerrainArea , 20 )
extern CSyncLock * g_pEtRenderLock ;
bool CEtTerrainArea : : s_bOptimize = false ;
bool CEtTerrainArea : : s_bEnableFrustumCull = true ;
CEtTerrainArea : : CEtTerrainArea ( void )
{
m_BoundingBox . Reset ( ) ;
m_pCommonIndexBuffer = NULL ;
m_pCommonLowIndexBuffer = NULL ;
m_pLightMapInfluenceBuffer = NULL ;
m_nLightMapInfluenceStride = 0 ;
m_bShow = true ;
m_nBlockCountX = 0 ;
m_nBlockCountY = 0 ;
m_nBlockSizeX = 0 ;
m_nBlockSizeY = 0 ;
m_nGrassBlockCountX = 0 ;
m_nGrassBlockCountY = 0 ;
}
CEtTerrainArea : : ~ CEtTerrainArea ( void )
{
Clear ( ) ;
}
void CEtTerrainArea : : Clear ( )
{
SAFE_DELETE_PVEC ( m_vecTerrain ) ;
SAFE_DELETE_PVEC ( m_vecGrassBlock ) ;
SAFE_RELEASE ( m_pCommonIndexBuffer ) ;
SAFE_RELEASE ( m_pCommonLowIndexBuffer ) ;
SAFE_DELETEA ( m_pLightMapInfluenceBuffer ) ;
}
void CEtTerrainArea : : CalcSelectCount ( int nBlockIndex , int & nStart , int & nEnd )
{
if ( nBlockIndex = = - 1 )
{
nStart = 0 ;
nEnd = ( int ) m_vecTerrain . size ( ) ;
}
else
{
nStart = nBlockIndex ;
nEnd = nStart + 1 ;
}
}
void CEtTerrainArea : : DrawGrid ( bool bDraw , int nBlockIndex )
{
int i , nStart , nEnd ;
CalcSelectCount ( nBlockIndex , nStart , nEnd ) ;
for ( i = nStart ; i < nEnd ; i + + )
{
m_vecTerrain [ i ] - > DrawGrid ( bDraw ) ;
}
}
void CEtTerrainArea : : SetGridColor ( DWORD dwColor , int nBlockIndex )
{
int i , nStart , nEnd ;
CalcSelectCount ( nBlockIndex , nStart , nEnd ) ;
for ( i = nStart ; i < nEnd ; i + + )
{
m_vecTerrain [ i ] - > SetGridColor ( dwColor ) ;
}
}
void CEtTerrainArea : : SetTextureDistance ( int nTexLayer , float fDistance , int nBlockIndex )
{
int i , nStart , nEnd ;
CalcSelectCount ( nBlockIndex , nStart , nEnd ) ;
for ( i = nStart ; i < nEnd ; i + + )
{
m_vecTerrain [ i ] - > SetTextureDistance ( nTexLayer , fDistance ) ;
}
}
void CEtTerrainArea : : SetTextureRotation ( int nTexLayer , float fRotation , int nBlockIndex )
{
int i , nStart , nEnd ;
CalcSelectCount ( nBlockIndex , nStart , nEnd ) ;
for ( i = nStart ; i < nEnd ; i + + )
{
m_vecTerrain [ i ] - > SetTextureRotation ( nTexLayer , fRotation ) ;
}
}
void CEtTerrainArea : : Initialize ( STerrainInfo * pInfo )
{
CEtTerrain * pTerrain ;
int i , j ;
Clear ( ) ;
m_TerrainInfo = * pInfo ;
// <20> <> Ƽ <EFBFBD> <C6BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ķ<EFBFBD> <C4B7> ̾<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ؾ<EFBFBD> <20> ؼ<EFBFBD> .. <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ..
if ( s_bOptimize )
{
int nSize = ( m_TerrainInfo . nSizeX + 1 ) * ( m_TerrainInfo . nSizeY + 1 ) ;
DWORD * pAlphaLayer = new DWORD [ nSize ] ;
memcpy ( pAlphaLayer , m_TerrainInfo . pLayerDensity , nSize * sizeof ( DWORD ) ) ;
m_TerrainInfo . pLayerDensity = pAlphaLayer ;
}
m_nBlockCountX = pInfo - > nSizeX / DEFAULT_TERRAIN_SIZE ;
if ( pInfo - > nSizeX % DEFAULT_TERRAIN_SIZE )
{
m_nBlockCountX + + ;
}
m_nBlockSizeX = DEFAULT_TERRAIN_SIZE ;
m_nBlockCountY = pInfo - > nSizeY / DEFAULT_TERRAIN_SIZE ;
if ( pInfo - > nSizeY % DEFAULT_TERRAIN_SIZE )
{
m_nBlockCountY + + ;
}
m_nBlockSizeY = DEFAULT_TERRAIN_SIZE ;
STerrainInfo TerrainInfo ;
memcpy ( & TerrainInfo , & m_TerrainInfo , sizeof ( STerrainInfo ) ) ;
TerrainInfo . nSizeX = m_nBlockSizeX ;
TerrainInfo . nSizeY = m_nBlockSizeY ;
for ( i = 0 ; i < m_nBlockCountY ; i + + )
{
for ( j = 0 ; j < m_nBlockCountX ; j + + )
{
TerrainInfo . pHeight = pInfo - > pHeight + ( i * m_nBlockSizeY ) * ( pInfo - > nSizeX + 1 ) + j * m_nBlockSizeX ;
TerrainInfo . pLayerDensity = pInfo - > pLayerDensity + ( i * m_nBlockSizeY ) * ( pInfo - > nSizeX + 1 ) + j * m_nBlockSizeX ;
TerrainInfo . TerrainOffset = pInfo - > TerrainOffset
+ EtVector3 ( pInfo - > fTileSize * j * m_nBlockSizeX , 0.0f , pInfo - > fTileSize * i * m_nBlockSizeY ) ;
pTerrain = CreateBlock ( pInfo - > Type ) ;
pTerrain - > SetBlockOffset ( j * m_nBlockSizeX , i * m_nBlockSizeY ) ;
pTerrain - > SetStride ( pInfo - > nSizeX + 1 , pInfo - > nSizeY + 1 ) ;
pTerrain - > SetTerrainInfo ( & TerrainInfo ) ;
m_vecTerrain . push_back ( pTerrain ) ;
}
}
float fWorldSizeX , fWorldSizeY , fWorldSizeZ ;
fWorldSizeX = m_TerrainInfo . nSizeX * m_TerrainInfo . fTileSize ;
fWorldSizeY = m_TerrainInfo . nSizeY * m_TerrainInfo . fTileSize ;
fWorldSizeZ = pInfo - > fHeightMultiply * 65535.f ;
CEtObject : : SetWorldSize ( EtVector3 ( fWorldSizeX * 0.5f , 0.0f , fWorldSizeY * 0.5f ) , max ( max ( fWorldSizeX , fWorldSizeY ) , fWorldSizeZ ) ) ;
CalcBoundingBox ( ) ;
SGraphicOption Option ;
GetEtOptionController ( ) - > GetGraphicOption ( Option ) ;
if ( Option . bDrawGrass )
{
CreateGrassBlock ( ) ;
}
if ( s_bOptimize )
{
delete [ ] m_TerrainInfo . pLayerDensity ;
}
}
void CEtTerrainArea : : CreateCommonIndexBuffer ( )
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ɼ<EFBFBD> <C9BC> ̶<EFBFBD> <CCB6> <EFBFBD> low <20> <> <EFBFBD> ÷<EFBFBD> <C3B7> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ƴ<EFBFBD> <20> <> <EFBFBD> 쿡 <20> <> <EFBFBD> <EFBFBD> <20> ʿ<EFBFBD> <CABF> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ϳ <EFBFBD> <CFB3> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ѵ <EFBFBD> .
SGraphicOption Option ;
GetEtOptionController ( ) - > GetGraphicOption ( Option ) ;
// #40097 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ɼ<EFBFBD> <C9BC> ̰ų<CCB0> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ̰<EFBFBD> , 2<> <32> ¥<EFBFBD> <C2A5> <20> <> <EFBFBD> ÷<EFBFBD> <C3B7> <EFBFBD> <20> <> <EFBFBD> ̴<EFBFBD> <CCB4> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <20> <EFBFBD> <D7B7> <EFBFBD> ī<> <C4AB> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> . <20> <EFBFBD> <D7B7> <EFBFBD> <20> <> <EFBFBD> ؼ<EFBFBD> m_pCommonIndexBuffer <20> <> <20> ʿ<EFBFBD> <CABF> ϴ<EFBFBD> .
if ( true = = Option . bUseSplatting | |
( false = = Option . bUseSplatting & & true = = Option . bIsOnlyLowShaderAvailable ) )
{
if ( m_pCommonIndexBuffer = = NULL )
{
int i , j , nIndexCount ;
WORD * pIndexBuffer ;
int nFaceCount ;
nFaceCount = m_nBlockSizeX * m_nBlockSizeY * 2 ;
nIndexCount = 0 ;
m_pCommonIndexBuffer = GetEtDevice ( ) - > CreateIndexBuffer ( nFaceCount * 3 * sizeof ( WORD ) ) ;
m_pCommonIndexBuffer - > Lock ( 0 , sizeof ( WORD ) * nFaceCount * 3 , ( void * * ) & pIndexBuffer , 0 ) ;
for ( i = 0 ; i < m_nBlockSizeY ; i + + )
{
for ( j = 0 ; j < m_nBlockSizeX ; j + + )
{
int nOffset ;
nOffset = ( m_nBlockSizeX + 1 ) * i + j ;
pIndexBuffer [ nIndexCount ] = nOffset ;
nIndexCount + + ;
pIndexBuffer [ nIndexCount ] = nOffset + m_nBlockSizeX + 1 ;
nIndexCount + + ;
pIndexBuffer [ nIndexCount ] = nOffset + m_nBlockSizeX + 2 ;
nIndexCount + + ;
pIndexBuffer [ nIndexCount ] = nOffset ;
nIndexCount + + ;
pIndexBuffer [ nIndexCount ] = nOffset + m_nBlockSizeX + 2 ;
nIndexCount + + ;
pIndexBuffer [ nIndexCount ] = nOffset + 1 ;
nIndexCount + + ;
}
}
m_pCommonIndexBuffer - > Unlock ( ) ;
}
}
if ( false = = Option . bUseSplatting )
{
if ( m_pCommonLowIndexBuffer = = NULL )
{
int i , j , nIndexCount ;
WORD * pIndexBuffer ;
int nFaceCount ;
nFaceCount = ( m_nBlockSizeX / 2 ) * ( m_nBlockSizeY / 2 ) * 2 ;
nIndexCount = 0 ;
m_pCommonLowIndexBuffer = GetEtDevice ( ) - > CreateIndexBuffer ( nFaceCount * 3 * sizeof ( WORD ) ) ;
m_pCommonLowIndexBuffer - > Lock ( 0 , sizeof ( WORD ) * nFaceCount * 3 , ( void * * ) & pIndexBuffer , 0 ) ;
for ( i = 0 ; i < m_nBlockSizeY / 2 ; i + + )
{
for ( j = 0 ; j < m_nBlockSizeX / 2 ; j + + )
{
int nOffset ;
nOffset = ( m_nBlockSizeX / 2 + 1 ) * i + j ;
pIndexBuffer [ nIndexCount ] = nOffset ;
nIndexCount + + ;
pIndexBuffer [ nIndexCount ] = nOffset + m_nBlockSizeX / 2 + 1 ;
nIndexCount + + ;
pIndexBuffer [ nIndexCount ] = nOffset + m_nBlockSizeX / 2 + 2 ;
nIndexCount + + ;
pIndexBuffer [ nIndexCount ] = nOffset ;
nIndexCount + + ;
pIndexBuffer [ nIndexCount ] = nOffset + m_nBlockSizeX / 2 + 2 ;
nIndexCount + + ;
pIndexBuffer [ nIndexCount ] = nOffset + 1 ;
nIndexCount + + ;
}
}
m_pCommonLowIndexBuffer - > Unlock ( ) ;
}
}
}
void CEtTerrainArea : : InitializeBlock ( int nBlockIndex )
{
SGraphicOption Option ;
GetEtOptionController ( ) - > GetGraphicOption ( Option ) ;
int i , nStart , nEnd ;
CreateCommonIndexBuffer ( ) ;
CalcSelectCount ( nBlockIndex , nStart , nEnd ) ;
for ( i = nStart ; i < nEnd ; i + + )
{
if ( true = = Option . bUseSplatting | |
( false = = Option . bUseSplatting & & true = = Option . bIsOnlyLowShaderAvailable ) )
{
m_vecTerrain [ i ] - > SetCommonIndexBuffer ( m_pCommonIndexBuffer , m_nBlockSizeX * m_nBlockSizeY * 2 ) ;
}
else
{
m_vecTerrain [ i ] - > SetCommonIndexBuffer ( m_pCommonLowIndexBuffer , ( m_nBlockSizeX / 2 ) * ( m_nBlockSizeY / 2 ) * 2 ) ;
}
m_vecTerrain [ i ] - > Initialize ( ) ;
m_vecTerrain [ i ] - > Enable ( true ) ;
if ( ! m_vecGrassBlock . empty ( ) )
{
int nGrassBlockIndex ;
nGrassBlockIndex = ( i % m_nBlockCountX ) * 2 + ( i / m_nBlockCountX ) * m_nBlockCountX * 4 ;
if ( m_vecGrassBlock [ nGrassBlockIndex ] )
{
m_vecGrassBlock [ nGrassBlockIndex ] - > Initialize ( this ) ;
}
nGrassBlockIndex + + ;
if ( m_vecGrassBlock [ nGrassBlockIndex ] )
{
m_vecGrassBlock [ nGrassBlockIndex ] - > Initialize ( this ) ;
}
nGrassBlockIndex + = m_nBlockCountX * 2 ;
if ( m_vecGrassBlock [ nGrassBlockIndex ] )
{
m_vecGrassBlock [ nGrassBlockIndex ] - > Initialize ( this ) ;
}
nGrassBlockIndex - - ;
if ( m_vecGrassBlock [ nGrassBlockIndex ] )
{
m_vecGrassBlock [ nGrassBlockIndex ] - > Initialize ( this ) ;
}
}
}
CalcBoundingBox ( ) ;
}
CEtTerrain * CEtTerrainArea : : CreateBlock ( TerrainType Type )
{
SGraphicOption Option ;
GetEtOptionController ( ) - > GetGraphicOption ( Option ) ;
if ( ! Option . bUseSplatting )
{
if ( Option . bIsOnlyLowShaderAvailable )
{
return new CEtLowDetailTerrain ( ) ;
}
else
{
return new CEtLowSplatTerrain ( ) ;
}
}
if ( s_bOptimize )
{
return new CEtTerrainOpti ( ) ;
}
else
{
switch ( Type )
{
case TT_NORMAL :
return new CEtTerrain ( ) ;
case TT_DETAILNORMAL :
return new CEtDetailTerrain ( ) ;
case TT_CLIFF :
return new CEtCliffTerrain ( ) ;
case TT_DETAILCLIFF :
return new CEtDetailCliffTerrain ( ) ;
}
}
return NULL ;
}
void CEtTerrainArea : : ChangeBlockType ( TerrainType Type , int nBlockIndex )
{
// <20> <> Ƽ <EFBFBD> <C6BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ÿ<> <C5B8> <20> ϳ <EFBFBD> <CFB3> <EFBFBD> .. <20> <> <EFBFBD> <EFBFBD> Ÿ<EFBFBD> <C5B8> <20> ٲ<EFBFBD> <20> ʿ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> ..
if ( s_bOptimize )
{
return ;
}
bool bEnable ;
int i , j , nStart , nEnd , nTexCount ;
STerrainInfo TerrainInfo ;
std : : vector < std : : string > vecTexName ;
std : : vector < float > vecTexDist ;
std : : vector < float > vecTexRotation ;
CalcSelectCount ( nBlockIndex , nStart , nEnd ) ;
for ( i = nStart ; i < nEnd ; i + + )
{
bEnable = m_vecTerrain [ i ] - > IsEnable ( ) ;
memcpy ( & TerrainInfo , m_vecTerrain [ i ] - > GetTerrainInfo ( ) , sizeof ( STerrainInfo ) ) ;
TerrainInfo . Type = Type ;
vecTexName . clear ( ) ;
vecTexDist . clear ( ) ;
const char * szTextureName ;
for ( j = 0 ; j < m_vecTerrain [ i ] - > GetTextureCount ( ) ; j + + )
{
szTextureName = m_vecTerrain [ i ] - > GetTextureName ( j ) ;
if ( szTextureName )
vecTexName . push_back ( szTextureName ) ;
else
vecTexName . push_back ( " " ) ;
vecTexDist . push_back ( m_vecTerrain [ i ] - > GetTextureDistance ( j ) ) ;
vecTexRotation . push_back ( m_vecTerrain [ i ] - > GetTextureRotation ( j ) ) ;
}
delete m_vecTerrain [ i ] ;
m_vecTerrain [ i ] = CreateBlock ( Type ) ;
m_vecTerrain [ i ] - > SetStride ( m_TerrainInfo . nSizeX + 1 , m_TerrainInfo . nSizeY + 1 ) ;
m_vecTerrain [ i ] - > SetBlockOffset ( i % m_nBlockCountX * m_nBlockSizeX , i / m_nBlockCountX * m_nBlockSizeY ) ;
m_vecTerrain [ i ] - > SetTerrainInfo ( & TerrainInfo ) ;
m_vecTerrain [ i ] - > SetCommonIndexBuffer ( m_pCommonIndexBuffer , m_nBlockSizeX * m_nBlockSizeY * 2 ) ;
if ( bEnable )
{
m_vecTerrain [ i ] - > Initialize ( ) ;
m_vecTerrain [ i ] - > Enable ( true ) ;
}
nTexCount = min ( m_vecTerrain [ i ] - > GetTextureCount ( ) , ( int ) vecTexName . size ( ) ) ;
for ( j = 0 ; j < nTexCount ; j + + )
{
if ( vecTexName [ j ] . size ( ) )
{
m_vecTerrain [ i ] - > SetTexture ( j , vecTexName [ j ] . c_str ( ) ) ;
}
m_vecTerrain [ i ] - > SetTextureDistance ( j , vecTexDist [ j ] ) ;
m_vecTerrain [ i ] - > SetTextureRotation ( j , vecTexRotation [ j ] ) ;
}
}
}
TerrainType CEtTerrainArea : : GetBlockType ( int nBlockIndex )
{
return m_vecTerrain [ nBlockIndex ] - > GetTerrainInfo ( ) - > Type ;
}
void CEtTerrainArea : : Render ( CEtConvexVolume * pFrustum )
{
int i , nSize ;
EtVector3 Origin , Extent ;
static std : : vector < bool > vecFrustumCull ;
nSize = ( int ) m_vecTerrain . size ( ) ;
vecFrustumCull . clear ( ) ;
vecFrustumCull . resize ( nSize ) ;
for ( i = 0 ; i < nSize ; i + + )
{
if ( m_vecTerrain [ i ] - > IsEnable ( ) = = false )
{
vecFrustumCull [ i ] = false ;
continue ;
}
if ( s_bEnableFrustumCull ) {
m_vecTerrain [ i ] - > GetExtent ( Origin , Extent ) ;
if ( pFrustum - > TesToBox ( Origin , Extent ) = = false )
{
vecFrustumCull [ i ] = false ;
continue ;
}
}
vecFrustumCull [ i ] = true ;
}
nSize = ( int ) m_vecGrassBlock . size ( ) ;
for ( i = 0 ; i < nSize ; i + + )
{
if ( ( m_vecGrassBlock [ i ] ) & & ( m_vecGrassBlock [ i ] - > GetGrassCount ( ) > 0 ) )
{
int nTerrainIndex ;
nTerrainIndex = i / ( m_nGrassBlockCountX * 2 ) * m_nBlockCountX + i % ( m_nGrassBlockCountX ) / 2 ;
if ( ! vecFrustumCull [ nTerrainIndex ] )
{
continue ;
}
m_vecGrassBlock [ i ] - > GetExtent ( Origin , Extent ) ;
if ( pFrustum - > TesToBox ( Origin , Extent ) = = true | | ! s_bEnableFrustumCull )
{
m_vecGrassBlock [ i ] - > Render ( ) ;
}
}
}
nSize = ( int ) m_vecTerrain . size ( ) ;
for ( i = 0 ; i < nSize ; i + + )
{
if ( ! vecFrustumCull [ i ] )
{
continue ;
}
m_vecTerrain [ i ] - > Render ( ) ;
}
}
void CEtTerrainArea : : RenderWater ( int index , CEtConvexVolume * pFrustum )
{
int i ;
EtVector3 Origin , Extent ;
static std : : vector < bool > vecFrustumCull ;
int nSize = ( int ) m_vecTerrain . size ( ) ;
vecFrustumCull . clear ( ) ;
vecFrustumCull . resize ( nSize ) ;
for ( i = 0 ; i < nSize ; i + + )
{
if ( m_vecTerrain [ i ] - > IsEnable ( ) = = false )
{
vecFrustumCull [ i ] = false ;
continue ;
}
if ( s_bEnableFrustumCull ) {
m_vecTerrain [ i ] - > GetExtent ( Origin , Extent ) ;
if ( pFrustum - > TesToBox ( Origin , Extent ) = = false )
{
vecFrustumCull [ i ] = false ;
continue ;
}
}
vecFrustumCull [ i ] = true ;
}
for ( i = 0 ; i < nSize ; i + + )
{
if ( ! vecFrustumCull [ i ] )
{
continue ;
}
m_vecTerrain [ i ] - > RenderWater ( index ) ;
}
}
void CEtTerrainArea : : GetExtent ( EtVector3 & Origin , EtVector3 & Extent )
{
Origin = ( m_BoundingBox . Max + m_BoundingBox . Min ) / 2 ;
Extent = ( m_BoundingBox . Max - m_BoundingBox . Min ) / 2 ;
}
void CEtTerrainArea : : CalcBoundingBox ( )
{
int i ;
SAABox * pBoundingBox ;
for ( i = 0 ; i < ( int ) m_vecTerrain . size ( ) ; i + + )
{
pBoundingBox = m_vecTerrain [ i ] - > GetBoundingBox ( ) ;
if ( m_BoundingBox . Min . y > pBoundingBox - > Min . y )
{
m_BoundingBox . Min . y = pBoundingBox - > Min . y ;
}
if ( m_BoundingBox . Max . y < pBoundingBox - > Max . y )
{
m_BoundingBox . Max . y = pBoundingBox - > Max . y ;
}
}
m_BoundingBox . Max . x = m_TerrainInfo . TerrainOffset . x + m_TerrainInfo . nSizeX * m_TerrainInfo . fTileSize ;
m_BoundingBox . Max . z = m_TerrainInfo . TerrainOffset . z + m_TerrainInfo . nSizeY * m_TerrainInfo . fTileSize ;
m_BoundingBox . Min . x = m_TerrainInfo . TerrainOffset . x ;
m_BoundingBox . Min . z = m_TerrainInfo . TerrainOffset . z ;
}
void CEtTerrainArea : : RenderTerrainBlockList ( CEtConvexVolume * pFrustum )
{
int i , nCount , nWaterCount ;
EtVector3 Origin , Extent ;
EtTerrainHandle hHandle ;
nWaterCount = GetEtWater ( ) - > GetWaterCount ( ) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Water <20> ø<EFBFBD> <20> Ÿ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ߴ <EFBFBD> <DFB4> <EFBFBD> <20> <> <EFBFBD> ߰<EFBFBD> <DFB0> <EFBFBD> <20> Ÿ<EFBFBD> <C5B8> <EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ڰŸ<DAB0> <C5B8> <EFBFBD> ..
float fWaterRatio = CEtCamera : : GetActiveCamera ( ) - > GetWaterFarRatio ( ) ;
CEtCamera : : GetActiveCamera ( ) - > SetWaterFarRatio ( 1.0f ) ;
std : : vector < CEtConvexVolume > vecWaterFrustum ;
vecWaterFrustum . resize ( nWaterCount ) ;
for ( int j = 0 ; j < nWaterCount ; j + + )
{
vecWaterFrustum [ j ] . Initialize ( GetEtWater ( ) - > GetViewProjMat ( j ) ) ;
}
CEtCamera : : GetActiveCamera ( ) - > SetWaterFarRatio ( fWaterRatio ) ;
ScopeLock < CSyncLock > Lock ( s_SmartPtrLock ) ;
nCount = GetItemCount ( ) ;
for ( i = 0 ; i < nCount ; i + + )
{
hHandle = GetItem ( i ) ;
if ( ( hHandle ) & & ( hHandle - > IsShow ( ) ) )
{
hHandle - > GetExtent ( Origin , Extent ) ;
if ( pFrustum - > TesToBox ( Origin , Extent ) | | ! s_bEnableFrustumCull )
{
hHandle - > Render ( pFrustum ) ;
}
if ( GetEtOptionController ( ) - > GetWaterQuality ( ) ! = WQ_LOW )
{
for ( int j = 0 ; j < nWaterCount ; j + + )
{
if ( GetEtWater ( ) - > GetWaterIgnoreBake ( j ) )
continue ;
if ( vecWaterFrustum [ j ] . TesToBox ( Origin , Extent ) | | ! s_bEnableFrustumCull )
{
hHandle - > RenderWater ( j , & vecWaterFrustum [ j ] ) ;
}
}
}
}
}
}
void CEtTerrainArea : : UpdateHeight ( int nStartX , int nStartY , int nEndX , int nEndY )
{
int i , j ;
int nStartBlockX , nStartBlockY , nEndBlockX , nEndBlockY ;
nStartBlockX = nStartX / m_nBlockSizeX ;
nStartBlockY = nStartY / m_nBlockSizeY ;
nEndBlockX = nEndX / m_nBlockSizeX ;
nEndBlockY = nEndY / m_nBlockSizeY ;
if ( nStartBlockX < 0 ) nStartBlockX = 0 ;
else if ( nStartBlockX > = m_nBlockCountX ) nStartBlockX = m_nBlockCountX - 1 ;
if ( nStartBlockY < 0 ) nStartBlockY = 0 ;
else if ( nStartBlockY > = m_nBlockCountY ) nStartBlockY = m_nBlockCountY - 1 ;
if ( nEndBlockX < 0 ) nEndBlockX = 0 ;
else if ( nEndBlockX > = m_nBlockCountX ) nEndBlockX = m_nBlockCountX - 1 ;
if ( nEndBlockY < 0 ) nStartBlockY = 0 ;
else if ( nEndBlockY > = m_nBlockCountY ) nEndBlockY = m_nBlockCountY - 1 ;
for ( i = nStartBlockY ; i < = nEndBlockY ; i + + )
{
for ( j = nStartBlockX ; j < = nEndBlockX ; j + + )
{
if ( m_vecTerrain [ i * m_nBlockCountX + j ] - > IsEnable ( ) = = false )
{
continue ;
}
m_vecTerrain [ i * m_nBlockCountX + j ] - > UpdateHeight ( ) ;
}
}
CalcBoundingBox ( ) ;
}
void CEtTerrainArea : : UpdateLayer ( int nStartX , int nStartY , int nEndX , int nEndY )
{
int i , j ;
int nStartBlockX , nStartBlockY , nEndBlockX , nEndBlockY ;
nStartBlockX = nStartX / m_nBlockSizeX ;
nStartBlockY = nStartY / m_nBlockSizeY ;
nEndBlockX = nEndX / m_nBlockSizeX ;
nEndBlockY = nEndY / m_nBlockSizeY ;
if ( nStartBlockX < 0 ) nStartBlockX = 0 ;
else if ( nStartBlockX > = m_nBlockCountX ) nStartBlockX = m_nBlockCountX - 1 ;
if ( nStartBlockY < 0 ) nStartBlockY = 0 ;
else if ( nStartBlockY > = m_nBlockCountY ) nStartBlockY = m_nBlockCountY - 1 ;
if ( nEndBlockX < 0 ) nEndBlockX = 0 ;
else if ( nEndBlockX > = m_nBlockCountX ) nEndBlockX = m_nBlockCountX - 1 ;
if ( nEndBlockY < 0 ) nStartBlockY = 0 ;
else if ( nEndBlockY > = m_nBlockCountY ) nEndBlockY = m_nBlockCountY - 1 ;
for ( i = nStartBlockY ; i < = nEndBlockY ; i + + )
{
for ( j = nStartBlockX ; j < = nEndBlockX ; j + + )
{
if ( m_vecTerrain [ i * m_nBlockCountX + j ] - > IsEnable ( ) = = false )
{
continue ;
}
m_vecTerrain [ i * m_nBlockCountX + j ] - > UpdateLayer ( ) ;
}
}
}
void CEtTerrainArea : : UpdateNormal ( int nStartX , int nStartY , int nEndX , int nEndY )
{
int i , j ;
int nStartBlockX , nStartBlockY , nEndBlockX , nEndBlockY ;
nStartBlockX = nStartX / m_nBlockSizeX ;
nStartBlockY = nStartY / m_nBlockSizeY ;
nEndBlockX = nEndX / m_nBlockSizeX ;
nEndBlockY = nEndY / m_nBlockSizeY ;
if ( nStartBlockX < 0 ) nStartBlockX = 0 ;
else if ( nStartBlockX > = m_nBlockCountX ) nStartBlockX = m_nBlockCountX - 1 ;
if ( nStartBlockY < 0 ) nStartBlockY = 0 ;
else if ( nStartBlockY > = m_nBlockCountY ) nStartBlockY = m_nBlockCountY - 1 ;
if ( nEndBlockX < 0 ) nEndBlockX = 0 ;
else if ( nEndBlockX > = m_nBlockCountX ) nEndBlockX = m_nBlockCountX - 1 ;
if ( nEndBlockY < 0 ) nStartBlockY = 0 ;
else if ( nEndBlockY > = m_nBlockCountY ) nEndBlockY = m_nBlockCountY - 1 ;
for ( i = nStartBlockY ; i < = nEndBlockY ; i + + )
{
for ( j = nStartBlockX ; j < = nEndBlockX ; j + + )
{
if ( m_vecTerrain [ i * m_nBlockCountX + j ] - > IsEnable ( ) = = false )
{
continue ;
}
m_vecTerrain [ i * m_nBlockCountX + j ] - > UpdateNormal ( ) ;
}
}
}
void CEtTerrainArea : : UpdateTextureCoord ( int nStartX , int nStartY , int nEndX , int nEndY )
{
int i , j ;
int nStartBlockX , nStartBlockY , nEndBlockX , nEndBlockY ;
nStartBlockX = nStartX / m_nBlockSizeX ;
nStartBlockY = nStartY / m_nBlockSizeY ;
nEndBlockX = nEndX / m_nBlockSizeX ;
nEndBlockY = nEndY / m_nBlockSizeY ;
if ( nStartBlockX < 0 ) nStartBlockX = 0 ;
else if ( nStartBlockX > = m_nBlockCountX ) nStartBlockX = m_nBlockCountX - 1 ;
if ( nStartBlockY < 0 ) nStartBlockY = 0 ;
else if ( nStartBlockY > = m_nBlockCountY ) nStartBlockY = m_nBlockCountY - 1 ;
if ( nEndBlockX < 0 ) nEndBlockX = 0 ;
else if ( nEndBlockX > = m_nBlockCountX ) nEndBlockX = m_nBlockCountX - 1 ;
if ( nEndBlockY < 0 ) nStartBlockY = 0 ;
else if ( nEndBlockY > = m_nBlockCountY ) nEndBlockY = m_nBlockCountY - 1 ;
for ( i = nStartBlockY ; i < = nEndBlockY ; i + + )
{
for ( j = nStartBlockX ; j < = nEndBlockX ; j + + )
{
if ( m_vecTerrain [ i * m_nBlockCountX + j ] - > IsEnable ( ) = = false )
{
continue ;
}
m_vecTerrain [ i * m_nBlockCountX + j ] - > GenerateTexureCoord ( ) ;
}
}
}
void CEtTerrainArea : : UpdateGrassBlock ( int nStartX , int nStartY , int nEndX , int nEndY )
{
int i , j ;
int nStartBlockX , nStartBlockY , nEndBlockX , nEndBlockY ;
nStartBlockX = nStartX / ( m_nBlockSizeX / 2 ) ;
nStartBlockY = nStartY / ( m_nBlockSizeY / 2 ) ;
nEndBlockX = nEndX / ( m_nBlockSizeX / 2 ) ;
nEndBlockY = nEndY / ( m_nBlockSizeY / 2 ) ;
if ( nStartBlockX < 0 ) nStartBlockX = 0 ;
else if ( nStartBlockX > = m_nGrassBlockCountX ) nStartBlockX = m_nGrassBlockCountX - 1 ;
if ( nStartBlockY < 0 ) nStartBlockY = 0 ;
else if ( nStartBlockY > = m_nGrassBlockCountY ) nStartBlockY = m_nGrassBlockCountY - 1 ;
if ( nEndBlockX < 0 ) nEndBlockX = 0 ;
else if ( nEndBlockX > = m_nGrassBlockCountX ) nEndBlockX = m_nGrassBlockCountX - 1 ;
if ( nEndBlockY < 0 ) nStartBlockY = 0 ;
else if ( nEndBlockY > = m_nGrassBlockCountY ) nEndBlockY = m_nGrassBlockCountY - 1 ;
for ( i = nStartBlockY ; i < = nEndBlockY ; i + + )
{
for ( j = nStartBlockX ; j < = nEndBlockX ; j + + )
{
if ( ! m_vecGrassBlock [ i * m_nGrassBlockCountX + j ] )
{
continue ;
}
m_vecGrassBlock [ i * m_nGrassBlockCountX + j ] - > Initialize ( this ) ;
}
}
}
int CEtTerrainArea : : GetGrassBlockCount ( )
{
return ( int ) m_vecGrassBlock . size ( ) ;
}
void CEtTerrainArea : : SetGrassInfo ( int nBlockIndex , SGrassBlockInfo & Info )
{
if ( nBlockIndex = = - 1 )
{
for ( DWORD i = 0 ; i < m_vecGrassBlock . size ( ) ; i + + )
{
m_vecGrassBlock [ i ] - > SetGrassBlockInfo ( & Info ) ;
m_vecGrassBlock [ i ] - > Initialize ( this ) ;
}
}
else
{
m_vecGrassBlock [ nBlockIndex ] - > SetGrassBlockInfo ( & Info ) ;
m_vecGrassBlock [ nBlockIndex ] - > Initialize ( this ) ;
}
}
SGrassBlockInfo * CEtTerrainArea : : GetGrassInfo ( int nBlockIndex )
{
if ( nBlockIndex < 0 | | nBlockIndex > = ( int ) m_vecGrassBlock . size ( ) ) return NULL ;
return m_vecGrassBlock [ nBlockIndex ] - > GetGrassBlockInfo ( ) ;
}
bool CEtTerrainArea : : Pick ( EtVector3 & Origin , EtVector3 & Direction , EtVector3 & PickPos )
{
int i ;
float fMinDist , fFindDist , fDistToBox ;
EtVector3 FindPos , ModifyOrigin ;
fMinDist = FLT_MAX ;
for ( i = 0 ; i < ( int ) m_vecTerrain . size ( ) ; i + + )
{
SAABox * pBoundingBox ;
pBoundingBox = m_vecTerrain [ i ] - > GetBoundingBox ( ) ;
if ( ! TestLineToBox ( Origin , Direction , * pBoundingBox , fDistToBox ) )
{
continue ;
}
if ( fDistToBox = = 0.0f )
{
ModifyOrigin = Origin ;
}
else
{
ModifyOrigin = Origin + Direction * fDistToBox ;
}
fFindDist = m_vecTerrain [ i ] - > Pick ( ModifyOrigin , Direction , FindPos ) + fDistToBox ;
if ( fFindDist < fMinDist )
{
fMinDist = fFindDist ;
PickPos = FindPos ;
}
}
if ( fMinDist ! = FLT_MAX )
{
return true ;
}
return false ;
}
bool CEtTerrainArea : : Pick ( int nX , int nY , EtVector3 & PickPos , int nCameraIndex )
{
EtVector3 Direction , Origin ;
CEtCamera : : GetItem ( nCameraIndex ) - > CalcPositionAndDir ( nX , nY , Origin , Direction ) ;
return Pick ( Origin , Direction , PickPos ) ;
}
bool CEtTerrainArea : : SetTexture ( int nTexIndex , const char * pTexName , int nBlockIndex )
{
int i , nStart , nEnd ;
bool bRet ;
bRet = true ;
CalcSelectCount ( nBlockIndex , nStart , nEnd ) ;
for ( i = nStart ; i < nEnd ; i + + )
{
if ( m_vecTerrain [ i ] - > SetTexture ( nTexIndex , pTexName ) = = false )
{
bRet = false ;
}
}
return bRet ;
}
void CEtTerrainArea : : SetGrassTexture ( const char * pFileName )
{
int i ;
for ( i = 0 ; i < ( int ) m_vecGrassBlock . size ( ) ; i + + )
{
if ( m_vecGrassBlock [ i ] )
{
m_vecGrassBlock [ i ] - > SetTexture ( pFileName ) ;
}
}
}
const char * CEtTerrainArea : : GetGrassTexture ( )
{
if ( m_vecGrassBlock . empty ( ) ) return NULL ;
return m_vecGrassBlock [ 0 ] - > GetTextureName ( ) ;
}
bool CEtTerrainArea : : IsInside ( float fX , float fZ )
{
if ( fX < m_TerrainInfo . TerrainOffset . x )
{
return false ;
}
if ( fX > m_TerrainInfo . TerrainOffset . x + m_TerrainInfo . nSizeX * m_TerrainInfo . fTileSize )
{
return false ;
}
if ( fZ < m_TerrainInfo . TerrainOffset . z )
{
return false ;
}
if ( fZ > m_TerrainInfo . TerrainOffset . z + m_TerrainInfo . nSizeY * m_TerrainInfo . fTileSize )
{
return false ;
}
return true ;
}
void CEtTerrainArea : : BakeLightMap ( int nBlockIndex , int nWidth , int nHeight , float fBlurSize , int nBakeRange , float fSlopeBias )
{
SBakeLightMapParam Param ;
Param . nBlockIndex = nBlockIndex ;
Param . nWidth = nWidth ;
Param . nHeight = nHeight ;
Param . fBlurSize = fBlurSize ;
Param . nBakeRange = nBakeRange ;
Param . fSlopeBias = fSlopeBias ;
m_vecBakeLightMapParam . push_back ( Param ) ;
}
void CEtTerrainArea : : _BakeLightMap ( int nBlockIndex , int nWidth , int nHeight , float fBlurSize , int nBakeRange , float fSlopeBias )
{
if ( ! CEtLight : : GetShadowCastDirLightInfo ( ) ) return ;
SGraphicOption Option ;
GetEtOptionController ( ) - > GetGraphicOption ( Option ) ;
if ( ! Option . bUseTerrainLightMap )
{
Option . bUseTerrainLightMap = true ;
GetEtOptionController ( ) - > SetGraphicOption ( Option ) ;
}
# ifdef PRE_FIX_MATERIAL_DUMP
EtMaterialHandle hBakeLightMapMaterial = LoadResource ( " BakeTerrainLightMap.fx " , RT_SHADER ) ;
EtMaterialHandle hGaussianFilter = LoadResource ( " GaussianFilter.fx " , RT_SHADER ) ;
if ( ! hBakeLightMapMaterial ) return ;
if ( ! hGaussianFilter ) return ;
# endif
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> ũ<> ⸦ <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> .
bool bBakeLightMap = true ;
if ( false = = Option . bUseSplatting )
{
if ( false = = Option . bIsOnlyLowShaderAvailable )
{
nWidth / = 2 ;
nHeight / = 2 ;
}
else
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ɼ<EFBFBD> <C9BC> ̶<EFBFBD> <CCB6> <EFBFBD> 2<> 常 <20> <> <EFBFBD> ÷<EFBFBD> <C3B7> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ,
// <20> <> <EFBFBD> ÷<EFBFBD> <C3B7> <EFBFBD> <20> <> <EFBFBD> ̴<EFBFBD> <CCB4> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ϴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <EFBFBD> <D7B7> <EFBFBD> ī<> 带 <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> Ĵ<EFBFBD> <C4B4> <EFBFBD> <20> ׳ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> ó<> <C3B3> .
BakeLowDetailMap ( ) ;
bBakeLightMap = false ;
}
}
if ( bBakeLightMap )
{
int i , nStart , nEnd ;
static EtMatrix LightMapViewProjMat ;
EtTextureHandle hBlurLightMap = CEtTexture : : CreateRenderTargetTexture ( nWidth * 2 , nHeight * 2 , FMT_A8R8G8B8 ) ;
EtTextureHandle hBlurMoreLightMap = CEtTexture : : CreateRenderTargetTexture ( nWidth * 2 , nHeight * 2 , FMT_A8R8G8B8 ) ;
EtTextureHandle hRoughLightMap = CEtTexture : : CreateRenderTargetTexture ( nWidth * 2 , nHeight * 2 , FMT_A8R8G8B8 ) ;
EtTextureHandle hFinalLightMap = CEtTexture : : CreateRenderTargetTexture ( nWidth , nHeight , FMT_A8R8G8B8 ) ;
EtTextureHandle hDepthLightMap = CEtTexture : : CreateRenderTargetTexture ( nWidth * 2 , nHeight * 2 , FMT_R32F ) ;
LPD3DXRENDERTOSURFACE pBlurSurfaceMng = NULL , pFinalSurfaceMng = NULL , pDepthSurfaceMng = NULL ;
GetEtDevice ( ) - > CreateRenderToSurface ( nWidth * 2 , nHeight * 2 , FMT_A8R8G8B8 , FALSE , FMT_UNKNOWN , & pBlurSurfaceMng ) ;
GetEtDevice ( ) - > CreateRenderToSurface ( nWidth * 2 , nHeight * 2 , FMT_R32F , TRUE , FMT_D24S8 , & pDepthSurfaceMng ) ;
GetEtDevice ( ) - > CreateRenderToSurface ( nWidth , nHeight , FMT_A8R8G8B8 , FALSE , FMT_UNKNOWN , & pFinalSurfaceMng ) ;
EtTextureHandle hInfluenceMap = CEtTexture : : CreateNormalTexture ( nWidth , nHeight , FMT_A8R8G8B8 , USAGE_DEFAULT , POOL_SYSTEMMEM ) ;
//EtDepthHandle hDepth = CEtDepth::CreateDepthStencil( nWidth * 2, nHeight * 2 );
# ifdef PRE_FIX_MATERIAL_DUMP
# else
EtMaterialHandle hBakeLightMapMaterial = LoadResource ( " BakeTerrainLightMap.fx " , RT_SHADER ) ;
EtMaterialHandle hGaussianFilter = LoadResource ( " GaussianFilter.fx " , RT_SHADER ) ;
# endif
SCameraInfo CameraInfo ;
EtCameraHandle hCamera ;
CameraInfo . fViewWidth = m_TerrainInfo . fTileSize * m_nBlockSizeX ;
CameraInfo . fViewHeight = m_TerrainInfo . fTileSize * m_nBlockSizeY ;
CameraInfo . fWidth = ( float ) nWidth ;
CameraInfo . fHeight = ( float ) nHeight ;
CameraInfo . Type = CT_ORTHOGONAL ;
CameraInfo . Target = CT_RENDERTARGET_NO_GENERATE_BACKBUFFER ;
hCamera = CreateCamera ( & CameraInfo ) ;
EtViewPort viewPort ;
GetEtDevice ( ) - > GetViewport ( & viewPort ) ;
CalcSelectCount ( nBlockIndex , nStart , nEnd ) ;
for ( i = nStart ; i < nEnd ; i + + )
{
std : : vector < SCustomParam > vecCustomParam ;
SAABox BoundingBox ;
int nTexIndex ;
EtVector3 Eye , At , TerrainOffset ;
BakeDepthLightMap ( i , hDepthLightMap , pDepthSurfaceMng , hBakeLightMapMaterial , LightMapViewProjMat , nBakeRange , fSlopeBias ) ;
BakeRoughLightMap ( i , hRoughLightMap , hDepthLightMap , pBlurSurfaceMng , hBakeLightMapMaterial , hCamera , nWidth * 2 , nHeight * 2 , LightMapViewProjMat ) ;
float fStart , fEnd ;
EtVector4 FilterRadius ;
GetEtDevice ( ) - > EnableZ ( false ) ;
GetEtDevice ( ) - > SetCullMode ( CULL_NONE ) ;
//GetEtDevice()->SetDepthStencilSurface( NULL );
vecCustomParam . clear ( ) ;
FilterRadius . x = fBlurSize * 2 / nWidth ;
FilterRadius . y = fBlurSize * 2 / nHeight ;
AddCustomParam ( vecCustomParam , EPT_VECTOR , hGaussianFilter , " g_fBlurRadius " , & FilterRadius ) ;
nTexIndex = hRoughLightMap - > GetMyIndex ( ) ;
AddCustomParam ( vecCustomParam , EPT_TEX , hGaussianFilter , " g_GaussianSource " , & nTexIndex ) ;
if ( SUCCEEDED ( pBlurSurfaceMng - > BeginScene ( hBlurLightMap - > GetSurfaceLevel ( ) , NULL ) ) ) {
DrawQuadIm ( hGaussianFilter , vecCustomParam , 0 , EtVector2 ( 0.0f , 0.0f ) , EtVector2 ( 1.0f , 1.0f ) , EtVector2 ( 0.0f , 0.0f ) , EtVector2 ( 1.0f , 1.0f ) ) ;
pBlurSurfaceMng - > EndScene ( 0 ) ;
}
nTexIndex = hBlurLightMap - > GetMyIndex ( ) ;
AddCustomParam ( vecCustomParam , EPT_TEX , hGaussianFilter , " g_GaussianSource " , & nTexIndex ) ;
if ( SUCCEEDED ( pBlurSurfaceMng - > BeginScene ( hBlurMoreLightMap - > GetSurfaceLevel ( ) , NULL ) ) ) {
DrawQuadIm ( hGaussianFilter , vecCustomParam , 1 , EtVector2 ( 0.0f , 0.0f ) , EtVector2 ( 1.0f , 1.0f ) , EtVector2 ( 0.0f , 0.0f ) , EtVector2 ( 1.0f , 1.0f ) ) ;
pBlurSurfaceMng - > EndScene ( 0 ) ;
}
vecCustomParam . clear ( ) ;
nTexIndex = hBlurMoreLightMap - > GetMyIndex ( ) ;
AddCustomParam ( vecCustomParam , EPT_TEX , hBakeLightMapMaterial , " g_LightMapTex " , & nTexIndex ) ;
if ( SUCCEEDED ( pFinalSurfaceMng - > BeginScene ( hFinalLightMap - > GetSurfaceLevel ( ) , NULL ) ) ) {
fStart = ( nWidth / 2.0f - 1.0f ) / ( nWidth * 2.0f ) ;
fEnd = ( nWidth * 3.0f / 2.0f + 1.0f ) / ( nWidth * 2.0f ) ;
DrawQuadIm ( hBakeLightMapMaterial , vecCustomParam , 2 , EtVector2 ( 0.0f , 0.0f ) , EtVector2 ( 1.0f , 1.0f ) , EtVector2 ( fStart , fStart ) , EtVector2 ( fEnd , fEnd ) ) ;
pFinalSurfaceMng - > EndScene ( 0 ) ;
}
GetEtDevice ( ) - > SetCullMode ( CULL_CCW ) ;
GetEtDevice ( ) - > EnableZ ( true ) ;
HRESULT hResult = ( ( IDirect3DDevice9 * ) GetEtDevice ( ) - > GetDevicePtr ( ) ) - > GetRenderTargetData ( hFinalLightMap - > GetSurfaceLevel ( ) , hInfluenceMap - > GetSurfaceLevel ( ) ) ;
if ( SUCCEEDED ( hResult ) ) {
int nTexStride ;
char * pTexBuffer ;
pTexBuffer = ( char * ) hInfluenceMap - > Lock ( nTexStride ) ;
SetLightMapInfluence ( i , pTexBuffer , nTexStride , hFinalLightMap - > Width ( ) , hFinalLightMap - > Height ( ) ) ;
hInfluenceMap - > Unlock ( ) ;
EtTextureHandle hLightMap = CEtTexture : : CreateNormalTexture ( nWidth , nHeight , FMT_DXT1 , USAGE_DEFAULT , POOL_MANAGED ) ;
hLightMap - > Copy ( hInfluenceMap ) ;
m_vecTerrain [ i ] - > SetLightMap ( hLightMap ) ;
}
}
GetEtDevice ( ) - > SetViewport ( & viewPort ) ;
SAFE_RELEASE_SPTR ( hCamera ) ;
SAFE_RELEASE_SPTR ( hGaussianFilter ) ;
SAFE_RELEASE_SPTR ( hInfluenceMap ) ;
SAFE_RELEASE_SPTR ( hFinalLightMap ) ;
SAFE_RELEASE_SPTR ( hRoughLightMap ) ;
SAFE_RELEASE_SPTR ( hBakeLightMapMaterial ) ;
SAFE_RELEASE_SPTR ( hDepthLightMap ) ;
SAFE_RELEASE_SPTR ( hBlurLightMap ) ;
SAFE_RELEASE_SPTR ( hBlurMoreLightMap ) ;
SAFE_RELEASE ( pBlurSurfaceMng ) ;
SAFE_RELEASE ( pFinalSurfaceMng ) ;
SAFE_RELEASE ( pDepthSurfaceMng ) ;
}
CEtObject : : RecalcLightMapInfluence ( ) ;
}
bool CEtTerrainArea : : _BakeLightMapFromFile ( int nBlockIndex , EtTextureHandle hTexture )
{
EtTextureHandle hInfluenceMap = CEtTexture : : CreateNormalTexture ( hTexture - > Width ( ) , hTexture - > Height ( ) , FMT_A8R8G8B8 , USAGE_DEFAULT , POOL_SYSTEMMEM ) ;
if ( ! hInfluenceMap ) return false ;
hInfluenceMap - > Copy ( hTexture ) ;
int nTexStride ;
char * pTexBuffer ;
pTexBuffer = ( char * ) hInfluenceMap - > Lock ( nTexStride ) ;
SetLightMapInfluence ( nBlockIndex , pTexBuffer , nTexStride , hTexture - > Width ( ) , hTexture - > Height ( ) ) ;
hInfluenceMap - > Unlock ( ) ;
m_vecTerrain [ nBlockIndex ] - > SetLightMap ( hTexture ) ;
SAFE_RELEASE_SPTR ( hInfluenceMap ) ;
return true ;
}
void CEtTerrainArea : : BakeLowDetailMap ( )
{
GetEtShadowMap ( ) - > ResetShadowMap ( ) ;
int i , nSize ;
nSize = ( int ) m_vecTerrain . size ( ) ;
for ( i = 0 ; i < nSize ; i + + ) {
m_vecTerrain [ i ] - > BakeLowDetailMap ( ) ;
m_vecTerrain [ i ] - > SetCommonIndexBuffer ( m_pCommonLowIndexBuffer , ( m_nBlockSizeX / 2 ) * ( m_nBlockSizeY / 2 ) * 2 ) ;
}
}
void CEtTerrainArea : : CreateLightCamera ( int nBlockIndex , EtCameraHandle & hCamera , int nWidth , int nHeight , EtMatrix & LightMapViewProjMat )
{
SAABox BoundingBox ;
SCameraInfo CameraInfo ;
EtVector3 Eye , At , LightDir , TerrainOffset ;
EtMatrix ScaleMat , TransMat , * pProjMat , * pViewMat ;
LightDir = - CEtLight : : GetShadowCastDirLightInfo ( ) - > Direction ;
TerrainOffset = m_vecTerrain [ nBlockIndex ] - > GetTerrainInfo ( ) - > TerrainOffset ;
BoundingBox = * GetBoundingBox ( nBlockIndex ) ;
BoundingBox . Max . y = m_BoundingBox . Max . y ;
BoundingBox . Min . y = m_BoundingBox . Min . y ;
BoundingBox . Max . x - = TerrainOffset . x ;
BoundingBox . Max . z - = TerrainOffset . z ;
BoundingBox . Min . x - = TerrainOffset . x ;
BoundingBox . Min . z - = TerrainOffset . z ;
if ( BoundingBox . Max . y - BoundingBox . Min . y < 3000.0f )
{
BoundingBox . Max . y = BoundingBox . Min . y + 3000.0f ;
}
BoundingBox . Max . y + = ( BoundingBox . Max . y - BoundingBox . Min . y ) * 0.05f ;
BoundingBox . Min . y - = ( BoundingBox . Max . y - BoundingBox . Min . y ) * 0.05f ;
CameraInfo . fViewWidth = m_TerrainInfo . fTileSize * m_nBlockSizeX ;
CameraInfo . fViewHeight = m_TerrainInfo . fTileSize * m_nBlockSizeY ;
CameraInfo . fWidth = ( float ) nWidth ;
CameraInfo . fHeight = ( float ) nHeight ;
CameraInfo . Target = CT_RENDERTARGET_NO_GENERATE_BACKBUFFER ;
CameraInfo . Type = CT_ORTHOGONAL ;
CameraInfo . fFar = ( BoundingBox . Max . y - BoundingBox . Min . y ) ;
hCamera = CreateCamera ( & CameraInfo ) ;
At = ( BoundingBox . Max + BoundingBox . Min ) / 2.0f ;
At . y = BoundingBox . Min . y ;
Eye = At + LightDir * ( BoundingBox . Max . y - BoundingBox . Min . y ) ;
hCamera - > LookAt ( Eye , At , EtVector3 ( 0.0f , 1.0f , 0.0f ) ) ;
pViewMat = hCamera - > GetViewMat ( ) ;
pViewMat - > _13 = 0.0f ;
pViewMat - > _23 = - 1.0f ;
pViewMat - > _33 = 0.0f ;
BoundingBox . Transform ( * hCamera - > GetViewProjMat ( ) ) ;
EtMatrixScaling ( & ScaleMat , 1.0f / ( BoundingBox . Max . x - BoundingBox . Min . x ) , 1.0f / ( BoundingBox . Max . y - BoundingBox . Min . y ) ,
1.0f / ( BoundingBox . Max . z - BoundingBox . Min . z ) ) ;
EtMatrixTranslation ( & TransMat , - ( BoundingBox . Max . x + BoundingBox . Min . x ) / ( BoundingBox . Max . x - BoundingBox . Min . x ) ,
- ( BoundingBox . Max . y + BoundingBox . Min . y ) / ( BoundingBox . Max . y - BoundingBox . Min . y ) , - BoundingBox . Min . z ) ;
pProjMat = hCamera - > GetProjMat ( ) ;
EtMatrixMultiply ( pProjMat , pProjMat , & ScaleMat ) ;
EtMatrixMultiply ( pProjMat , pProjMat , & TransMat ) ;
LightMapViewProjMat = * hCamera - > GetViewProjMat ( ) ;
}
EtTextureHandle CEtTerrainArea : : BakeDepthLightMap ( int nBlockIndex , EtTextureHandle hLightMap , LPD3DXRENDERTOSURFACE pDepthSurface , EtMaterialHandle hMaterial ,
EtMatrix & LightMapViewProjMat , int nBakeRange , float fSlopeBias )
{
EtCameraHandle hCamera ;
CreateLightCamera ( nBlockIndex , hCamera , hLightMap - > Width ( ) , hLightMap - > Height ( ) , LightMapViewProjMat ) ;
hCamera - > Activate ( ) ;
if ( SUCCEEDED ( pDepthSurface - > BeginScene ( hLightMap - > GetSurfaceLevel ( ) , NULL ) ) )
{
GetEtDevice ( ) - > EnableZ ( true ) ;
GetEtDevice ( ) - > ClearBuffer ( 0xffffffff , 1.0f , 0 ) ;
GetEtDevice ( ) - > SetCullMode ( CULL_CW ) ;
int i , j , nCount ;
EtMatrix WorldMat ;
EtVector3 TerrainOffset ;
float fBlockWidth , fBlockHeight ;
fBlockWidth = m_nBlockSizeX * m_TerrainInfo . fTileSize ;
fBlockHeight = m_nBlockSizeY * m_TerrainInfo . fTileSize ;
TerrainOffset = m_vecTerrain [ nBlockIndex ] - > GetTerrainInfo ( ) - > TerrainOffset ;
{
ScopeLock < CSyncLock > Lock ( s_SmartPtrLock ) ;
nCount = CEtObject : : GetItemCount ( ) ;
for ( i = 0 ; i < nCount ; i + + )
{
EtObjectHandle hObject ;
EtSkinHandle hSkin ;
hObject = CEtObject : : GetItem ( i ) ;
if ( ! hObject )
{
continue ;
}
if ( ! hObject - > IsLightMapCast ( ) )
{
continue ;
}
WorldMat = * hObject - > GetWorldMat ( ) ;
WorldMat . _41 - = TerrainOffset . x ;
WorldMat . _43 - = TerrainOffset . z ;
if ( ( WorldMat . _41 > - fBlockWidth ) & & ( WorldMat . _41 < fBlockWidth * 2 ) & & ( WorldMat . _43 > - fBlockHeight ) & & ( WorldMat . _43 < fBlockHeight * 2 ) )
{
int nTexIndex ;
hSkin = hObject - > GetSkin ( ) ;
if ( hSkin & & hSkin - > GetMeshHandle ( ) )
{
std : : vector < std : : vector < SCustomParam > > vecCustomParam ;
vecCustomParam . resize ( hSkin - > GetMeshHandle ( ) - > GetSubMeshCount ( ) ) ;
for ( int j = 0 ; j < hSkin - > GetMeshHandle ( ) - > GetSubMeshCount ( ) ; j + + ) {
AddCustomParam ( vecCustomParam [ j ] , EPT_FLOAT , hMaterial , " g_fSlopeBias " , & fSlopeBias ) ;
nTexIndex = hSkin - > GetDiffuseTexIndex ( j ) ;
AddCustomParam ( vecCustomParam [ j ] , EPT_TEX , hMaterial , " g_DiffuseTex " , & nTexIndex ) ;
}
hSkin - > SetExternalMaterial ( hMaterial , NULL , & vecCustomParam ) ;
hSkin - > Render ( WorldMat , WorldMat , 1.0f , false ) ;
hSkin - > ClearExternalMaterial ( ) ;
}
}
}
}
std : : vector < SCustomParam > vecCustomParam ;
AddCustomParam ( vecCustomParam , EPT_FLOAT , hMaterial , " g_fSlopeBias " , & fSlopeBias ) ;
int nTexIndex = - 1 ;
AddCustomParam ( vecCustomParam , EPT_TEX , hMaterial , " g_DiffuseTex " , & nTexIndex ) ;
for ( i = - nBakeRange ; i < = nBakeRange ; i + + )
{
for ( j = - nBakeRange ; j < = nBakeRange ; j + + )
{
int nCurTerrainIndex ;
EtMatrixIdentity ( & WorldMat ) ;
nCurTerrainIndex = nBlockIndex + i * m_nBlockCountX + j ;
if ( ( nCurTerrainIndex < 0 ) | | ( nCurTerrainIndex > = ( int ) m_vecTerrain . size ( ) ) )
{
continue ;
}
EtMatrixTranslation ( & WorldMat , j * m_nBlockSizeX * m_TerrainInfo . fTileSize , 0.0f , i * m_nBlockSizeY * m_TerrainInfo . fTileSize ) ;
hMaterial - > SetTechnique ( 0 ) ;
hMaterial - > SetWorldMatParams ( & WorldMat , & WorldMat ) ;
hMaterial - > SetCustomParamList ( vecCustomParam ) ;
int nPasses ;
hMaterial - > BeginEffect ( nPasses ) ;
hMaterial - > BeginPass ( 0 ) ;
hMaterial - > CommitChanges ( ) ;
m_vecTerrain [ nCurTerrainIndex ] - > GetMeshStream ( ) . Draw ( hMaterial - > GetVertexDeclIndex ( 0 , 0 ) ) ;
hMaterial - > EndPass ( ) ;
hMaterial - > EndEffect ( ) ;
}
}
pDepthSurface - > EndScene ( 0 ) ;
}
GetEtDevice ( ) - > SetCullMode ( CULL_NONE ) ;
SAFE_RELEASE_SPTR ( hCamera ) ;
return hLightMap ;
}
void CEtTerrainArea : : BakeRoughLightMap ( int nBlockIndex , EtTextureHandle hRoughLightMap , EtTextureHandle hDepthLightMap , LPD3DXRENDERTOSURFACE pRoughSurface , EtMaterialHandle hMaterial , EtCameraHandle hCamera , int nWidth , int nHeight , EtMatrix & LightMapViewProjMat )
{
std : : vector < SCustomParam > vecCustomParam ;
SAABox BoundingBox ;
int i , j , nTexIndex ;
EtVector3 Eye , At , TerrainOffset ;
EtMatrix WorldLightViewProjMat ;
SCameraInfo CameraInfo ;
CameraInfo . fViewWidth = m_TerrainInfo . fTileSize * m_nBlockSizeX * 2.0f ;
CameraInfo . fViewHeight = m_TerrainInfo . fTileSize * m_nBlockSizeY * 2.0f ;
CameraInfo . fWidth = ( float ) nWidth ;
CameraInfo . fHeight = ( float ) nHeight ;
CameraInfo . Type = CT_ORTHOGONAL ;
CameraInfo . Target = CT_RENDERTARGET_NO_GENERATE_BACKBUFFER ;
TerrainOffset = m_vecTerrain [ nBlockIndex ] - > GetTerrainInfo ( ) - > TerrainOffset ;
BoundingBox = * GetBoundingBox ( nBlockIndex ) ;
BoundingBox . Max . y = m_BoundingBox . Max . y ;
BoundingBox . Min . y = m_BoundingBox . Min . y ;
BoundingBox . Max . x - = TerrainOffset . x ;
BoundingBox . Max . z - = TerrainOffset . z ;
BoundingBox . Min . x - = TerrainOffset . x ;
BoundingBox . Min . z - = TerrainOffset . z ;
if ( BoundingBox . Max . y - BoundingBox . Min . y < 1000.0f )
{
BoundingBox . Max . y = BoundingBox . Min . y + 1000.0f ;
}
CameraInfo . fFar = ( BoundingBox . Max . y - BoundingBox . Min . y ) * 1.1f ;
hCamera - > Initialize ( & CameraInfo ) ;
At = ( BoundingBox . Max + BoundingBox . Min ) / 2.0f ;
At . y = BoundingBox . Min . y ;
Eye = At ;
Eye . y + = ( BoundingBox . Max . y - BoundingBox . Min . y ) * 1.05f ;
hCamera - > LookAt ( Eye , At , EtVector3 ( 0.0f , 0.0f , 1.0f ) ) ;
nTexIndex = hDepthLightMap - > GetMyIndex ( ) ;
AddCustomParam ( vecCustomParam , EPT_TEX , hMaterial , " g_LightMapTex " , & nTexIndex ) ;
AddCustomParam ( vecCustomParam , EPT_MATRIX_PTR , hMaterial , " g_BakeLightViewProjMat " , & WorldLightViewProjMat ) ;
EtMatrix WorldMat ;
int nPasses ;
GetEtDevice ( ) - > EnableZ ( false ) ;
GetEtDevice ( ) - > SetCullMode ( CULL_NONE ) ;
hCamera - > Activate ( ) ;
if ( SUCCEEDED ( pRoughSurface - > BeginScene ( hRoughLightMap - > GetSurfaceLevel ( ) , NULL ) ) )
{
GetEtDevice ( ) - > ClearBuffer ( 0xffffffff , 1.0f , 0 ) ;
CEtLight : : SetDirLightAttenuation ( 1.0f ) ;
for ( i = - 1 ; i < = 1 ; i + + )
{
for ( j = - 1 ; j < = 1 ; j + + )
{
int nCurTerrainIndex ;
EtMatrixIdentity ( & WorldMat ) ;
nCurTerrainIndex = nBlockIndex + i * m_nBlockCountX + j ;
if ( ( nCurTerrainIndex < 0 ) | | ( nCurTerrainIndex > = ( int ) m_vecTerrain . size ( ) ) )
{
continue ;
}
EtMatrixTranslation ( & WorldMat , j * m_nBlockSizeX * m_TerrainInfo . fTileSize , 0.0f , i * m_nBlockSizeY * m_TerrainInfo . fTileSize ) ;
EtMatrixMultiply ( & WorldLightViewProjMat , & WorldMat , & LightMapViewProjMat ) ;
hMaterial - > SetTechnique ( 1 ) ;
hMaterial - > SetGlobalParams ( ) ;
hMaterial - > SetWorldMatParams ( & WorldMat , & WorldMat ) ;
hMaterial - > SetCustomParamList ( vecCustomParam ) ;
hMaterial - > BeginEffect ( nPasses ) ;
hMaterial - > BeginPass ( 0 ) ;
hMaterial - > CommitChanges ( ) ;
m_vecTerrain [ nCurTerrainIndex ] - > GetMeshStream ( ) . Draw ( hMaterial - > GetVertexDeclIndex ( 1 , 0 ) ) ;
hMaterial - > EndPass ( ) ;
hMaterial - > EndEffect ( ) ;
}
}
GetEtDevice ( ) - > SetCullMode ( CULL_CCW ) ;
GetEtDevice ( ) - > EnableZ ( true ) ;
pRoughSurface - > EndScene ( 0 ) ;
}
}
void CEtTerrainArea : : CreateLightMapInfluenceBuffer ( )
{
if ( m_pLightMapInfluenceBuffer )
{
return ;
}
m_nLightMapInfluenceStride = m_TerrainInfo . nSizeX / 8 ;
if ( m_TerrainInfo . nSizeX % 8 )
{
m_nLightMapInfluenceStride + + ;
}
m_pLightMapInfluenceBuffer = new char [ m_nLightMapInfluenceStride * ( m_TerrainInfo . nSizeY + 1 ) ] ;
memset ( m_pLightMapInfluenceBuffer , 0 , m_nLightMapInfluenceStride * ( m_TerrainInfo . nSizeY + 1 ) ) ;
}
void CEtTerrainArea : : SetLightMapInfluence ( int nBlockIndex , char * pTexBuffer , int nTexStride , int nTexWidth , int nTexHeight )
{
CreateLightMapInfluenceBuffer ( ) ;
int i , j , nBlockStartX , nBlockStartY ;
nBlockStartX = nBlockIndex % m_nBlockCountX * m_nBlockSizeX ;
nBlockStartY = nBlockIndex / m_nBlockCountX * m_nBlockSizeY ;
for ( i = 0 ; i < m_nBlockSizeY ; i + + )
{
for ( j = 0 ; j < m_nBlockSizeX ; j + + )
{
int nHori , nVert ;
int nOffset , nTexOffset ;
char cShift ;
nHori = ( int ) ( j / ( m_nBlockSizeX - 1.0f ) * ( nTexWidth - 1 ) ) ;
nVert = ( int ) ( i / ( m_nBlockSizeY - 1.0f ) * ( nTexHeight - 1 ) ) ;
nTexOffset = nVert * nTexStride + nHori * 4 ;
if ( pTexBuffer [ nTexOffset + 1 ] = = 0 )
{
nOffset = ( i + nBlockStartY ) * m_nLightMapInfluenceStride + ( j + nBlockStartX ) / 8 ;
cShift = ( ( char ) ( 0x1 ) ) < < ( ( j + nBlockStartX ) % 8 ) ;
m_pLightMapInfluenceBuffer [ nOffset ] | = cShift ;
}
}
}
if ( ! m_vecGrassBlock . empty ( ) )
{
int nGrassBlockIndex ;
nGrassBlockIndex = ( nBlockIndex % m_nBlockCountX ) * 2 + ( nBlockIndex / m_nBlockCountX ) * m_nBlockCountX * 4 ;
if ( m_vecGrassBlock [ nGrassBlockIndex ] )
{
m_vecGrassBlock [ nGrassBlockIndex ] - > SetLightMapInfluence ( pTexBuffer , nTexStride , nTexWidth , nTexHeight , 0.0f , 0.0f ) ;
}
nGrassBlockIndex + + ;
if ( m_vecGrassBlock [ nGrassBlockIndex ] )
{
m_vecGrassBlock [ nGrassBlockIndex ] - > SetLightMapInfluence ( pTexBuffer , nTexStride , nTexWidth , nTexHeight , 0.5f , 0.0f ) ;
}
nGrassBlockIndex + = m_nBlockCountX * 2 ;
if ( m_vecGrassBlock [ nGrassBlockIndex ] )
{
m_vecGrassBlock [ nGrassBlockIndex ] - > SetLightMapInfluence ( pTexBuffer , nTexStride , nTexWidth , nTexHeight , 0.5f , 0.5f ) ;
}
nGrassBlockIndex - - ;
if ( m_vecGrassBlock [ nGrassBlockIndex ] )
{
m_vecGrassBlock [ nGrassBlockIndex ] - > SetLightMapInfluence ( pTexBuffer , nTexStride , nTexWidth , nTexHeight , 0.0f , 0.5f ) ;
}
}
}
float CEtTerrainArea : : GetLightMapInfluence ( float fX , float fZ )
{
if ( m_pLightMapInfluenceBuffer = = NULL )
{
return 1.0f ;
}
int nCellX = 0 , nCellZ = 0 ;
float fWeight [ 4 ] , fValue ;
char cShift ;
CalcCellPosition ( fX , fZ , nCellX , nCellZ , fWeight ) ;
if ( nCellX < 0 | | nCellZ < 0 )
return 1.0f ;
cShift = ( ( char ) ( 0x1 ) ) < < ( nCellX % 8 ) ;
fValue = m_pLightMapInfluenceBuffer [ nCellZ * m_nLightMapInfluenceStride + nCellX / 8 ] & cShift ? fWeight [ 0 ] : 0.0f ;
nCellX + + ;
cShift = ( ( char ) ( 0x1 ) ) < < ( nCellX % 8 ) ;
fValue + = m_pLightMapInfluenceBuffer [ nCellZ * m_nLightMapInfluenceStride + nCellX / 8 ] & cShift ? fWeight [ 1 ] : 0.0f ;
nCellZ + + ;
cShift = ( ( char ) ( 0x1 ) ) < < ( nCellX % 8 ) ;
fValue + = m_pLightMapInfluenceBuffer [ nCellZ * m_nLightMapInfluenceStride + nCellX / 8 ] & cShift ? fWeight [ 3 ] : 0.0f ;
nCellX - - ;
cShift = ( ( char ) ( 0x1 ) ) < < ( nCellX % 8 ) ;
fValue + = m_pLightMapInfluenceBuffer [ nCellZ * m_nLightMapInfluenceStride + nCellX / 8 ] & cShift ? fWeight [ 2 ] : 0.0f ;
return 1.0f - fValue ;
}
float CEtTerrainArea : : CalcLightMapInfluence ( float fX , float fZ )
{
ScopeLock < CSyncLock > Lock ( s_SmartPtrLock ) ;
int i ;
for ( i = 0 ; i < GetItemCount ( ) ; i + + )
{
EtTerrainHandle hTerrainArea ;
hTerrainArea = GetItem ( i ) ;
if ( hTerrainArea - > IsInside ( fX , fZ ) )
{
return hTerrainArea - > GetLightMapInfluence ( fX , fZ ) ;
}
}
return 1.0f ;
}
void CEtTerrainArea : : CalcCellPosition ( float fX , float fZ , int & nCellX , int & nCellZ , float * pWeight , int nScale )
{
float fModX , fModZ ;
fX - = m_TerrainInfo . TerrainOffset . x ;
fZ - = m_TerrainInfo . TerrainOffset . z ;
if ( fX < 0.0f )
{
fX = 0.f ;
}
else if ( fX > = m_TerrainInfo . nSizeX * m_TerrainInfo . fTileSize )
{
fX = m_TerrainInfo . nSizeX * m_TerrainInfo . fTileSize - 0.1f ;
}
if ( fZ < 0.f )
{
fZ = 0.f ;
}
else if ( fZ > = m_TerrainInfo . nSizeY * m_TerrainInfo . fTileSize )
{
fZ = m_TerrainInfo . nSizeY * m_TerrainInfo . fTileSize - 0.1f ;
}
nCellX = ( int ) ( fX / ( m_TerrainInfo . fTileSize * nScale ) ) ;
nCellZ = ( int ) ( fZ / ( m_TerrainInfo . fTileSize * nScale ) ) ;
fModX = fX / ( m_TerrainInfo . fTileSize * nScale ) - nCellX ;
fModZ = fZ / ( m_TerrainInfo . fTileSize * nScale ) - nCellZ ;
if ( fModX > fModZ )
{
pWeight [ 0 ] = 1.0f - fModX ;
pWeight [ 1 ] = fModX - fModZ ;
pWeight [ 2 ] = 0.0f ;
pWeight [ 3 ] = fModZ ;
}
else if ( fModX < fModZ )
{
pWeight [ 0 ] = 1.0f - fModZ ;
pWeight [ 1 ] = 0.0f ;
pWeight [ 2 ] = fModZ - fModX ;
pWeight [ 3 ] = fModX ;
}
else
{
pWeight [ 0 ] = 1.0f - fModZ ;
pWeight [ 1 ] = 0.0f ;
pWeight [ 2 ] = 0.0f ;
pWeight [ 3 ] = fModZ ;
}
}
float CEtTerrainArea : : GetLandHeight ( float fX , float fZ , EtVector3 * pNormal , int nScale )
{
int i ;
float fRet ;
int nCellX , nCellZ ;
float fHeight [ 4 ] , fWeight [ 4 ] ;
DWORD dwSectorWidth = m_TerrainInfo . nSizeX + 1 ;
CalcCellPosition ( fX , fZ , nCellX , nCellZ , fWeight , nScale ) ;
fHeight [ 0 ] = m_TerrainInfo . pHeight [ nCellZ * dwSectorWidth + nCellX ] ;
fHeight [ 1 ] = m_TerrainInfo . pHeight [ nCellZ * dwSectorWidth + nCellX + nScale ] ;
fHeight [ 2 ] = m_TerrainInfo . pHeight [ ( nCellZ + nScale ) * dwSectorWidth + nCellX ] ;
fHeight [ 3 ] = m_TerrainInfo . pHeight [ ( nCellZ + nScale ) * dwSectorWidth + nCellX + nScale ] ;
fRet = 0.0f ;
for ( i = 0 ; i < 4 ; i + + )
{
fRet + = fHeight [ i ] * fWeight [ i ] ;
}
if ( pNormal )
{
GetVertexNormal ( * pNormal , nCellX , nCellZ ) ;
}
return fRet * m_TerrainInfo . fHeightMultiply ;
}
void CEtTerrainArea : : GetLandNormal ( EtVector3 & Normal , float fX , float fZ )
{
int i ;
EtVector3 ReturnVec , VertexNormal [ 4 ] ;
int nCellX , nCellZ ;
float fWeight [ 4 ] ;
CalcCellPosition ( fX , fZ , nCellX , nCellZ , fWeight ) ;
GetVertexNormal ( VertexNormal [ 0 ] , nCellX , nCellZ ) ;
GetVertexNormal ( VertexNormal [ 1 ] , nCellX + 1 , nCellZ ) ;
GetVertexNormal ( VertexNormal [ 2 ] , nCellX , nCellZ + 1 ) ;
GetVertexNormal ( VertexNormal [ 3 ] , nCellX + 1 , nCellZ + 1 ) ;
ReturnVec = EtVector3 ( 0.0f , 0.0f , 0.0f ) ; ;
for ( i = 0 ; i < 4 ; i + + )
{
ReturnVec + = VertexNormal [ i ] * fWeight [ i ] ;
}
EtVec3Normalize ( & Normal , & ReturnVec ) ;
}
void CEtTerrainArea : : GetVertexNormal ( EtVector3 & Normal , int nCellX , int nCellZ )
{
int nHeightIndex ;
float fDX , fDZ ;
EtVector3 Return ;
DWORD dwTileWidth = m_TerrainInfo . nSizeX + 1 ;
DWORD dwTileHeight = m_TerrainInfo . nSizeY + 1 ;
nHeightIndex = dwTileWidth * nCellZ + nCellX ;
if ( nCellX = = 0 )
{
fDX = ( m_TerrainInfo . pHeight [ nHeightIndex ] - m_TerrainInfo . pHeight [ nHeightIndex + 1 ] ) / m_TerrainInfo . fTileSize ;
}
else if ( nCellX = = dwTileWidth - 1 )
{
fDX = ( m_TerrainInfo . pHeight [ nHeightIndex - 1 ] - m_TerrainInfo . pHeight [ nHeightIndex ] ) / m_TerrainInfo . fTileSize ;
}
else
{
fDX = ( m_TerrainInfo . pHeight [ nHeightIndex - 1 ] - m_TerrainInfo . pHeight [ nHeightIndex + 1 ] ) / ( m_TerrainInfo . fTileSize * 2 ) ;
}
if ( nCellZ = = 0 )
{
fDZ = ( m_TerrainInfo . pHeight [ nHeightIndex ] - m_TerrainInfo . pHeight [ nHeightIndex + dwTileWidth ] ) / m_TerrainInfo . fTileSize ;
}
else if ( nCellZ = = dwTileHeight - 1 )
{
fDZ = ( m_TerrainInfo . pHeight [ nHeightIndex - dwTileWidth ] - m_TerrainInfo . pHeight [ nHeightIndex ] ) / m_TerrainInfo . fTileSize ;
}
else
{
fDZ = ( m_TerrainInfo . pHeight [ nHeightIndex - dwTileWidth ] - m_TerrainInfo . pHeight [ nHeightIndex + dwTileWidth ] ) / ( m_TerrainInfo . fTileSize * 2 ) ;
}
Return . x = fDX ;
Return . y = 1.414f ;
Return . z = fDZ ;
EtVec3Normalize ( & Normal , & Return ) ;
}
void CEtTerrainArea : : CreateGrassBlock ( )
{
if ( m_TerrainInfo . pGrassBuffer = = NULL )
{
return ;
}
int i , j ;
int nGrassBlockSize ;
m_nGrassBlockCountX = m_nBlockCountX * 2 ;
m_nGrassBlockCountY = m_nBlockCountY * 2 ;
nGrassBlockSize = DEFAULT_TERRAIN_SIZE / 2 ;
for ( i = 0 ; i < m_nGrassBlockCountY ; i + + )
{
for ( j = 0 ; j < m_nGrassBlockCountX ; j + + )
{
CEtGrassBlock * pGrassBlock ;
SGrassBlockInfo BlockInfo ;
if ( ( j + 1 ) * nGrassBlockSize < = m_TerrainInfo . nSizeX )
{
BlockInfo . nSizeX = nGrassBlockSize ;
}
else
{
BlockInfo . nSizeX = m_TerrainInfo . nSizeX - j * nGrassBlockSize ;
}
if ( ( i + 1 ) * nGrassBlockSize < = m_TerrainInfo . nSizeY )
{
BlockInfo . nSizeY = nGrassBlockSize ;
}
else
{
BlockInfo . nSizeY = m_TerrainInfo . nSizeY - i * nGrassBlockSize ;
}
if ( ( BlockInfo . nSizeX > 0 ) & & ( BlockInfo . nSizeY > 0 ) )
{
pGrassBlock = new CEtGrassBlock ( ) ;
// int nDivide = ( m_TerrainInfo.nSizeX / ( nGrassBlockSize * i ) ) ;
BlockInfo . pGrassBuffer = m_TerrainInfo . pGrassBuffer + ( i * m_TerrainInfo . nSizeX * nGrassBlockSize ) + ( j * nGrassBlockSize ) ;
BlockInfo . nStride = m_TerrainInfo . nSizeX ;
BlockInfo . fTileSize = m_TerrainInfo . fTileSize ;
BlockInfo . GrassOffset . x = m_TerrainInfo . TerrainOffset . x + nGrassBlockSize * j * m_TerrainInfo . fTileSize ;
BlockInfo . GrassOffset . y = m_TerrainInfo . TerrainOffset . y ;
BlockInfo . GrassOffset . z = m_TerrainInfo . TerrainOffset . z + nGrassBlockSize * i * m_TerrainInfo . fTileSize ;
memcpy ( BlockInfo . fGrassWidth , m_TerrainInfo . fGrassWidth , sizeof ( float ) * 4 ) ;
memcpy ( BlockInfo . fMaxGrassHeight , m_TerrainInfo . fMaxGrassHeight , sizeof ( float ) * 4 ) ; ;
memcpy ( BlockInfo . fMinGrassHeight , m_TerrainInfo . fMinGrassHeight , sizeof ( float ) * 4 ) ; ; ;
BlockInfo . fMaxShake = m_TerrainInfo . fMaxShake ;
BlockInfo . fMinShake = m_TerrainInfo . fMinShake ;
pGrassBlock - > SetGrassBlockInfo ( & BlockInfo ) ;
}
else
{
pGrassBlock = NULL ;
}
m_vecGrassBlock . push_back ( pGrassBlock ) ;
}
}
}
void CEtTerrainArea : : CheckBakeLightMap ( )
{
ScopeLock < CSyncLock > Lock ( s_SmartPtrLock ) ;
int i , j , nCount ;
nCount = GetItemCount ( ) ;
for ( i = 0 ; i < nCount ; i + + )
{
EtTerrainHandle hTerrainArea ;
hTerrainArea = GetItem ( i ) ;
if ( hTerrainArea )
{
int nBakeLightMapCount = hTerrainArea - > GetBakeLightMapParamCount ( ) ;
SBakeLightMapParam Param ;
for ( j = 0 ; j < nBakeLightMapCount ; j + + )
{
hTerrainArea - > GetBakeLightMapParam ( j , Param ) ;
hTerrainArea - > _BakeLightMap ( Param . nBlockIndex , Param . nWidth , Param . nHeight , Param . fBlurSize , Param . nBakeRange , Param . fSlopeBias ) ;
}
hTerrainArea - > m_vecBakeLightMapParam . clear ( ) ;
}
}
}
void CEtTerrainArea : : ReloadMaterial ( )
{
CEtResource : : FlushWaitDelete ( ) ; // RefCount 0 <20> <> Material <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> .
EtMaterialHandle hMaterial ;
hMaterial = CEtResource : : GetResource ( " LayeredTerrain.fx " ) ;
if ( hMaterial )
{
hMaterial - > Reload ( ) ;
// SAFE_RELEASE_SPTR( hMaterial );
//ASSERT( hMaterial->GetRefCount() > 0 );
}
hMaterial = CEtResource : : GetResource ( " LayeredCliffTerrain.fx " ) ;
if ( hMaterial )
{
hMaterial - > Reload ( ) ;
// SAFE_RELEASE_SPTR( hMaterial );
//ASSERT( hMaterial->GetRefCount() > 0 );b
}
}
EtTerrainHandle CEtTerrainArea : : GetTerrainArea ( float fX , float fZ )
{
ScopeLock < CSyncLock > Lock ( s_SmartPtrLock ) ;
int i ;
for ( i = 0 ; i < GetItemCount ( ) ; i + + )
{
EtTerrainHandle hTerrainArea ;
hTerrainArea = GetItem ( i ) ;
if ( hTerrainArea - > IsInside ( fX , fZ ) )
{
return hTerrainArea ;
}
}
return CEtTerrainArea : : Identity ( ) ;
}
void CEtTerrainArea : : SetInteractivePos ( EtVector3 * vPos , float fDelta )
{
int i , nSize ;
nSize = ( int ) m_vecGrassBlock . size ( ) ;
for ( i = 0 ; i < nSize ; i + + )
{
if ( ( m_vecGrassBlock [ i ] ) & & ( m_vecGrassBlock [ i ] - > GetGrassCount ( ) > 0 ) )
{
m_vecGrassBlock [ i ] - > SetInteractivePos ( vPos , fDelta ) ;
}
}
}