Files
2026-06-01 12:46:52 +02:00

3759 lines
83 KiB
C++

#include "stdafx.h"
#include "KRenderDevice.h"
#include "SGameCloud.h"
#include "SEnvPrimitive.h"
#include "K3DTypes.h"
#include "KSeqModel.h"
#include "K3DCamera.h"
#include "KResourceManager.h"
#include "KRenderObjectEtc.h"
#include <dump/XException.h>
#include <mmo/ArTime.h>
#include "TerrainPrimitive.h"
//#include "SDebug_Util.h"
#include "SGameWeather.h" // [sonador] to include 'lerp' function in namespace 'env_fx'
#include "SGameLightning.h"
#include <toolkit/XStringUtil.h>
#include <kfile/KFileManager.h>
//#include "SGameMilesSoundMgr.h"
#ifdef CLOUD_LUA
#include "SGameSystem.h"
#include "SGameAvatarEx.h"
#include "SGameWorld.h"
CCloudKindDB* g_pCloudKindDB = NULL;
CCloudThicknessDB* g_pCloudThicknesDB = NULL;
CCloudThicknessGapDB* g_pCloudThicknessGapDB = NULL;
CCloudSizeDB* g_pCloudSizeDB = NULL;
CCloudTxrGroupDB* g_pCloudTxrGroupDB = NULL;
CCloudDistributionDB* g_pCloudDistributionDB = NULL;
CCloudHeightRadomGapDB* g_pCloudHeightRadomGapDB = NULL;
CCloudLayerGapDB* g_pCloudCloudLayerGapDB = NULL;
CCloudMoveDirDB* g_pCloudCloudMoveDirDB = NULL;
CCloudPathDB* g_pCloudPathDB = NULL;
CCloudTypeInfoDB* g_pCloudTypeInfoDB = NULL;
CCloudLayerDB* g_pCloudLayerDB = NULL;
CCloudLayerSetDB* g_pCloudLayerSetDB = NULL;
float g_fMyPlayerHeight = 0.0f;
extern SGameSystem * g_pCurrentGameSystem;
int g_nFadeState = 0;
float g_fRateG = 1.0f;
float g_fRate = 1.0f;
float g_fRateScale= 1.0f;
float g_fTestX = 0.0f;
float g_fTestY = 0.0f;
float g_fTestZ = 0.0f;
float g_fTestG = 3.0f;
bool g_bUseWorldTM = false;
float g_fZ = 0.0f;
float g_fX = 0.0f;
float g_fY = 0.0f;
#endif
#ifdef SKYBOX_CLOUD
const int CLOUD_MAX = 190;
const float START_TIME = 6000.f;
const float END_TIME = 4000.f;
const float DEFAULT_HEIGHT = 500.0f;
// { [sonador]
const int THUNDER_CLOUD_MAX = 3;
const float DEFAULT_HEIGHT_THUNDER_CLOUD = 510.0f;
// }
float fRotSpeed[] =
{
0.2f,
// 0.2f,
// 0.3f,
// 0.4f,
// 0.5f,
};
bool SGameCloud::m_bProcessPause = false;
float SCloudEx::s_fFactor = 0.1f;
float SCloudEx::s_fLightningFactor = 1.0f;
DWORD SCloudEx::s_dwDuration = 250;
int SCloudEx::s_nFlashCount = 3;
K3DColor SCloudEx::s_sDestColor = K3DColor( 0xffdae7fe );
SCloudEx::SCloudEx()
{
InitVariable();
}
SCloudEx::SCloudEx(int nType, int nCount, int nDepth, int nZoneWidth, int nZoneHeight)
{
InitVariable();
}
SCloudEx::~SCloudEx()
{
Destroy();
}
void SCloudEx::InitVariable()
{
nWidth = 0;
nHeight = 0;
vPosition = K3DVector(0, 0, 0);
vStartPosition = K3DVector(0, 0, 0);
fVisibilityCap = 1;
fVisibility = 0;
color = 0x00000000;
bActive = false;
pVecCloud = 0;
dwStartTime = 0;
dwOldTime = 0;
fRotSpeed = 0.1f;
eStep = APPEAR;
}
void SCloudEx::Init( K3DRenderDevice *pDevice, K3DIndexBuffer * pIndexBuf )
{
m_pDevice = pDevice;
/*
DWORD dwFormat = 0;
m_pVB = m_pDevice->CreateVertexBufferUsePoolDefault( sizeof(K3DVERTEX_CLOUD), dwFormat, 4 * nDepth, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY );
if( m_pVB && m_pVB->IsValidVtx() )
{
K3DVERTEX_CLOUD* vtx = NULL;
int nVtxSize;
m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD );
assert(vtx && "m_pVB->Lock( (void**)&vtx, nVtxSize );");
if( vtx == NULL ) return;
for( int n=0; 4 * nDepth > n; )
{
int nRand = rand() % 150 + 255;
vtx[n].position = K3DVector( (float)-m_nWidth/2.f, (float)-m_nHeight/2.f, 0 );
vtx[n].color = m_CloudColor;
vtx[n].color.a = nRand;
vtx[n].normal = K3DVector( 0.f, 0.f, -1.f);
vtx[n].texcoord0.x = 0.f;
vtx[n].texcoord0.y = 0.f;
n++;
vtx[n].position = K3DVector( m_nWidth / 2.f, (float)-m_nHeight/2.f, 0 );
vtx[n].color = m_CloudColor;
vtx[n].color.a = nRand;
vtx[n].normal = K3DVector( 0.f, 0.f, -1.f);
vtx[n].texcoord0.x = 1.f;
vtx[n].texcoord0.y = 0.f;
n++;
vtx[n].position = K3DVector( (float)-m_nWidth/2.f, m_nHeight / 2.f, 0 );
vtx[n].color = m_CloudColor;
vtx[n].color.a = nRand;
vtx[n].normal = K3DVector( 0.f, 0.f, -1.f);
vtx[n].texcoord0.x = 0.0f;
vtx[n].texcoord0.y = 1.f;
n++;
vtx[n].position = K3DVector( m_nWidth / 2.f, m_nHeight / 2.f, 0 );
vtx[n].color = m_CloudColor;
vtx[n].color.a = nRand;
vtx[n].normal = K3DVector( 0.f, 0.f, -1.f);
vtx[n].texcoord0.x = 1.0f;
vtx[n].texcoord0.y = 1.f;
n++;
}
m_pVB->Unlock();
m_pVB->Backup();
m_spIB = NULL; // Index Buf
m_spTexture = NULL;
m_spAlphaTexture = NULL;
m_pMat = new K3DMaterial;
m_pMat->SetAmbient( K3DColor( 1.f, 1.f, 1.f, 1.f ) );
m_pMat->SetDiffuse( K3DColor( 1.f, 1.f, 1.f, 1.f ) );
m_pMat->SetSpecular( K3DColor( 0.f, 0.f, 0.f, 1.f ) );
m_pMat->SetSpecularPower( 1.0f );
m_pParentMat = NULL; // SkyBox 위치
K3DMatrixIdentity( m_LocalMat ); // 구름 위치
K3DMatrixIdentity( m_WorldMat );
m_pPrimitive = new SCloudPrimitive; // Render Object
m_pPrimitive->SetTransparent( true );
m_pPrimitive->SetTransform( &m_LocalMat, &m_WorldMat );
m_pPrimitive->SetVertexBuffer( m_pVB );
m_pPrimitive->SetMaterial( m_pMat );
this->initCloudObjects();
}
*/
}
void SCloudEx::Process( DWORD dwTime )
{
/* if( IsProcessPause() ) return;
if( m_pVB == NULL || !m_pVB->IsValidVtx() ) return;
m_dwTime = dwTime;
// [sonador] Lock / Unlock 을 짧은 시간에 수행하기 위해 update 를 분리하였음.
for( int it = 0; it < m_nCloudCount; ++it )
{
if( m_pCloud[ it ].IsActive() )
this->procesSCloudEx( it );
}
K3DVERTEX_CLOUD* vtx = NULL;
int nVtxSize;
int nPrimCnt = 0;
//D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨.
#if defined( _DEBUG )
m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD );
#else
m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_DISCARD );
#endif
assert(vtx && "m_pVB->Lock( (void**)&vtx, nVtxSize );");
if( vtx == NULL ) return;
for(int it = 0; it < m_nCloudCount; ++it)
{
if( m_pCloud[ it ].IsActive() )
{
this->updateVB( &vtx[ nPrimCnt * 4 ], m_pCloud[ it ] );
}
else
{
vtx[ nPrimCnt * 4 + 0 ].color.a = 0;
vtx[ nPrimCnt * 4 + 1 ].color.a = 0;
vtx[ nPrimCnt * 4 + 2 ].color.a = 0;
vtx[ nPrimCnt * 4 + 3 ].color.a = 0;
}
++nPrimCnt;
}
m_pVB->Unlock();
m_pPrimitive->SetVertexCnt( nPrimCnt * 4 );
*/
/*K3DMatrix mat;
K3DMatrixIdentity( mat );
//K3DMatrixRotationAxis( &mat, m_pVecCloud, (10.f*K3D_PI/180.f) );
K3DMatrixIdentity( m_LocalMat );
K3DMatrixSetPosVector( m_LocalMat, m_Pos );
K3DMatrixMultiply( &m_LocalMat, &mat, &m_LocalMat );
if( m_pParentMat )
K3DMatrixMultiply( &m_LocalMat, &m_LocalMat, m_pParentMat );*/
}
void SCloudEx::Render( KViewportObject *viewport )
{
if( m_pPrimitive && m_pPrimitive->GetVertexCnt() > 0 )
{
viewport->Register( m_pPrimitive, KRenderObject::RENDEREFX_CLOUD );
}
}
void SCloudEx::Create(int nType, int nCount, int nDepth, int nZoneWidth, int nZoneHeight)
{
if ( nType == 0 )
{
;
}
else if( nType == 0 )
{
}
else if( nType == 0 )
{
}
}
void SCloudEx::Destroy()
{
}
void SCloudEx::SetPosition( float x, float y, float z )
{
if( vStartPosition.x == 0.f &&
vStartPosition.y == 0.f &&
vStartPosition.z == 0.f )
vStartPosition = vPosition;
vPosition.Set( x, y, z );
}
void SCloudEx::SetColor( const K3DColor& _color )
{
color.r = (unsigned char)(_color.r * 255);
color.g = (unsigned char)(_color.g * 255);
color.b = (unsigned char)(_color.b * 255);
}
void SCloudEx::SetColor( const KColor& _color )
{
color.r = _color.r;
color.g = _color.g;
color.b = _color.b;
}
void SCloudEx::SetVisibility( float _visibility )
{
fVisibility = std::min( _visibility, fVisibilityCap );
fVisibility = std::max( 0.f, std::min( 1.0f, fVisibility ) );
color.a = (unsigned char)( 255 * fVisibility );
}
void SCloudEx::SetVisibilityCap( float _cap )
{
fVisibilityCap = _cap;
}
K3DVector SCloudEx::GetVertexPosition( EVtxPos _pos_type ) const
{
K3DVector vResult;
switch( _pos_type )
{
case UL:
vResult.Set( vPosition.x - nWidth / 2.f, vPosition.y - nHeight / 2.f, vPosition.z );
break;
case UR:
vResult.Set( vPosition.x + nWidth / 2.f, vPosition.y - nHeight / 2.f, vPosition.z );
break;
case BL:
vResult.Set( vPosition.x - nWidth / 2.f, vPosition.y + nHeight / 2.f, vPosition.z );
break;
case BR:
vResult.Set( vPosition.x + nWidth / 2.f, vPosition.y + nHeight / 2.f, vPosition.z );
break;
}
return vResult;
}
void SCloudEx::checkStartTime( DWORD dwTime_msec_ )
{
if( dwStartTime == 0 )
dwStartTime = dwTime_msec_;
}
void SCloudEx::ResetStartTime()
{
dwStartTime = 0;
}
void SCloudEx::resetPosition()
{
vPosition.x = (K3DVALUE)(-rand()%8000);
vPosition.y = (K3DVALUE)(-rand()%8000);
}
void SCloudEx::ChangeStep( EStep step )
{
eStep = step;
//dwStartTime = 0;
}
void SCloudEx::processByStep( DWORD elapsed_time , const KColor& _cloud_color )
{
//1)처음 나타나면, 0~1 서서히 나타난다.
//2)모두 보이면, 이동 시작
//3)이동이 끝나면 1~0 서서히 사라진다.
switch( eStep )
{
case APPEAR:
this->onAppear( elapsed_time );
break;
case DISAPPEAR:
this->onDisappear( elapsed_time );
break;
case MOVE:
this->onMove( elapsed_time );
break;
default:
break;
}
}
void SCloudEx::movePosition()
{
vPosition.x += fRotSpeed;
vPosition.y += fRotSpeed;
}
bool SCloudEx::IsOutOfBound() const
{
return ( vPosition.x > 1800.f || vPosition.y > 1800.f );
}
void SCloudEx::Update( DWORD _time, const KColor& _cloud_color )
{
this->checkStartTime( _time );
DWORD elapsed_time = _time - dwStartTime;
this->SetColor( _cloud_color );
this->SetVisibilityCap( (float)_cloud_color.a / 255 );
this->processByStep( elapsed_time, _cloud_color );
this->movePosition();
if( this->IsOutOfBound() && !this->IsStep( DISAPPEAR ) )
{
this->ChangeStep( DISAPPEAR );
this->ResetStartTime();
}
}
void SCloudEx::onAppear( DWORD elapsed_time )
{
if ( elapsed_time > START_TIME )
{
//종료
this->ChangeStep( MOVE );
this->ResetStartTime();
}
else
{
this->SetVisibility( (float)elapsed_time / START_TIME );
}
}
void SCloudEx::onDisappear( DWORD elapsed_time )
{
if( elapsed_time < END_TIME )
{
this->SetVisibility( 1.f - ( (float)elapsed_time / END_TIME ) );
}
else
{
//this->SetActivity( (rand() % 2) == 1 ); // 랜덤하게 활동여부를 설정하는 이유는?
this->resetPosition();
this->ResetStartTime();
this->ChangeStep( APPEAR );
}
}
void SCloudEx::onMove( DWORD elapsed_time )
{
this->SetVisibility( fVisibilityCap );
}
// =======================================================================
// SGameCloud
// =======================================================================
SGameCloud::SGameCloud( int cloud_count )
: m_dwTime ( 0 )
, m_nCloudCount ( cloud_count )
, m_CloudColor ( 255, 255, 255, 255 )
, m_pSoundMgr ( 0 )
, m_pDevice ( 0 )
{
}
SGameCloud::~SGameCloud()
{
SAFE_DELETE( m_pMat );
SAFE_DELETE_ARRAY( m_pCloud );
if( m_pVB )
m_pDevice->DelReloadVertexList( m_pVB );
}
void SGameCloud::Init( K3DRenderDevice *pDevice, K3DIndexBuffer * pIndexBuf )
{
m_pDevice = pDevice;
DWORD dwFormat = 0;
m_pVB = pDevice->CreateVertexBufferUsePoolDefault( sizeof(K3DVERTEX_CLOUD), dwFormat, 4*m_nCloudCount, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY ); //기본 사각형
if( m_pVB && m_pVB->IsValidVtx() )
{
// m_spVB = pDevice->CreateVertexBufferBlend( sizeof(K3DBLENDEDBUMPVERTEX), dwFormat, 4*m_nCloudCount ); //기본 사각형
this->initVB();
m_spIB = NULL; // Index Buf
m_spTexture = NULL;
m_spAlphaTexture = NULL;
m_pMat = new K3DMaterial;
m_pMat->SetAmbient( K3DColor( 1.f, 1.f, 1.f, 1.f ) );
m_pMat->SetDiffuse( K3DColor( 1.f, 1.f, 1.f, 1.f ) );
m_pMat->SetSpecular( K3DColor( 0.f, 0.f, 0.f, 1.f ) );
m_pMat->SetSpecularPower( 1.0f );
m_pParentMat = NULL; // SkyBox 위치
K3DMatrixIdentity( m_LocalMat ); // 구름 위치
K3DMatrixIdentity( m_WorldMat );
m_pPrimitive = new SCloudPrimitive; // Render Object
m_pPrimitive->SetTransparent( true );
m_pPrimitive->SetTransform( &m_LocalMat, &m_WorldMat );
m_pPrimitive->SetVertexBuffer( m_pVB );
m_pPrimitive->SetMaterial( m_pMat );
this->initCloudObjects();
}
}
void SGameCloud::Process( DWORD dwTime )
{
if( IsProcessPause() ) return;
if( m_pVB == NULL || !m_pVB->IsValidVtx() ) return;
m_dwTime = dwTime;
// [sonador] Lock / Unlock 을 짧은 시간에 수행하기 위해 update 를 분리하였음.
for( int it = 0; it < m_nCloudCount; ++it )
{
if( m_pCloud[ it ].IsActive() )
this->procesSCloudEx( it );
}
K3DVERTEX_CLOUD* vtx = NULL;
int nVtxSize;
int nPrimCnt = 0;
//D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨.
#if defined( _DEBUG )
m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD );
#else
m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_DISCARD );
#endif
assert(vtx && "m_pVB->Lock( (void**)&vtx, nVtxSize );");
if( vtx == NULL ) return;
for(int it = 0; it < m_nCloudCount; ++it)
{
if( m_pCloud[ it ].IsActive() )
{
this->updateVB( &vtx[ nPrimCnt * 4 ], m_pCloud[ it ] );
}
else
{
vtx[ nPrimCnt * 4 + 0 ].color.a = 0;
vtx[ nPrimCnt * 4 + 1 ].color.a = 0;
vtx[ nPrimCnt * 4 + 2 ].color.a = 0;
vtx[ nPrimCnt * 4 + 3 ].color.a = 0;
}
++nPrimCnt;
}
m_pVB->Unlock();
m_pPrimitive->SetVertexCnt( nPrimCnt * 4 );
/*K3DMatrix mat;
K3DMatrixIdentity( mat );
//K3DMatrixRotationAxis( &mat, m_pVecCloud, (10.f*K3D_PI/180.f) );
K3DMatrixIdentity( m_LocalMat );
K3DMatrixSetPosVector( m_LocalMat, m_Pos );
K3DMatrixMultiply( &m_LocalMat, &mat, &m_LocalMat );
if( m_pParentMat )
K3DMatrixMultiply( &m_LocalMat, &m_LocalMat, m_pParentMat );*/
}
void SGameCloud::Render( KViewportObject *viewport )
{
if( m_pPrimitive && m_pPrimitive->GetVertexCnt() > 0 )
{
viewport->Register( m_pPrimitive, KRenderObject::RENDEREFX_CLOUD );
}
}
void SGameCloud::SetHeight( int i, float fz )
{
if( i >=0 && i < m_nCloudCount )
{
m_pCloud[i].vPosition.z = fz;
}
else
{
assert( !"SGameCloud : refered wrong index" );
}
//if( m_pThunderCloud )
// m_pThunderCloud->SetHeight( i, fz );
}
void SGameCloud::SetPosition( int i, float fx, float fy, float fz )
{
if( i >=0 && i < m_nCloudCount )
{
m_pCloud[i].SetPosition( fx, fy, fz );
}
else
{
assert( !"SGameCloud : refered wrong index" );
}
//if( m_pThunderCloud )
// m_pThunderCloud->SetPosition( i, fz, fy, fz );
}
void SGameCloud::SetMaxVisibility( int i, float fVis )
{
if( i >=0 && i < m_nCloudCount )
{
m_pCloud[i].SetVisibilityCap( fVis );
}
else
{
assert( !"SGameCloud : refered wrong index" );
}
//if( m_pThunderCloud )
// m_pThunderCloud->SetMaxVisibility( i, fVis );
}
void SGameCloud::SetVisibility( int i, float fVis )
{
if( i >=0 && i < m_nCloudCount )
{
m_pCloud[i].SetVisibility( fVis );
}
else
{
assert( !"SGameCloud : refered wrong index" );
}
//if( m_pThunderCloud )
// m_pThunderCloud->SetVisibility( i, fVis );
}
void SGameCloud::SetCloudColor( int i, K3DColor & color )
{
if( i >=0 && i < m_nCloudCount )
{
m_pCloud[ i ].SetColor( color );
}
else
{
assert(0);
}
//if( m_pThunderCloud )
// m_pThunderCloud->SetCloudColor( i, color );
}
void SGameCloud::SetCloudColor( KColor & color )
{
m_CloudColor = color;
}
void SGameCloud::SetTransform( K3DMatrix* pParentMatrix )
{
SetParentMat( pParentMatrix );
m_pPrimitive->SetTransform( pParentMatrix, pParentMatrix );
}
SCloudEx* SGameCloud::GetFirstDeactiveCloud()
{
SCloudEx* pCloud = std::find_if(
&m_pCloud[ 0 ], &m_pCloud[ m_nCloudCount ], SFindFirstDeactiveCloud() );
if( pCloud != &m_pCloud[ m_nCloudCount ] )
return pCloud;
return 0;
}
void SGameCloud::SetSoundManager( SGameMilesSoundMgr* pSoundMgr )
{
m_pSoundMgr = pSoundMgr;
}
void SGameCloud::initVB()
{
K3DVERTEX_CLOUD* vtx = NULL;
int nVtxSize;
m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD );
assert(vtx && "m_pVB->Lock( (void**)&vtx, nVtxSize );");
if( vtx == NULL ) return;
for( int n=0; 4 * m_nCloudCount > n; )
{
int nRand = rand() % 150 + 255;
vtx[n].position = K3DVector( (float)-m_nWidth/2.f, (float)-m_nHeight/2.f, 0 );
vtx[n].color = m_CloudColor;
vtx[n].color.a = nRand;
vtx[n].normal = K3DVector( 0.f, 0.f, -1.f);
vtx[n].texcoord0.x = 0.f;
vtx[n].texcoord0.y = 0.f;
//vtx[n].texcoord1.x = 0.f;
//vtx[n].texcoord1.y = 0.f;
n++;
vtx[n].position = K3DVector( m_nWidth / 2.f, (float)-m_nHeight/2.f, 0 );
vtx[n].color = m_CloudColor;
vtx[n].color.a = nRand;
vtx[n].normal = K3DVector( 0.f, 0.f, -1.f);
vtx[n].texcoord0.x = 1.f;
vtx[n].texcoord0.y = 0.f;
//vtx[n].texcoord1.x = 1.f;
//vtx[n].texcoord1.y = 0.f;
n++;
vtx[n].position = K3DVector( (float)-m_nWidth/2.f, m_nHeight / 2.f, 0 );
vtx[n].color = m_CloudColor;
vtx[n].color.a = nRand;
vtx[n].normal = K3DVector( 0.f, 0.f, -1.f);
vtx[n].texcoord0.x = 0.0f;
vtx[n].texcoord0.y = 1.f;
//vtx[n].texcoord1.x = 0.0f;
//vtx[n].texcoord1.y = 1.f;
n++;
vtx[n].position = K3DVector( m_nWidth / 2.f, m_nHeight / 2.f, 0 );
vtx[n].color = m_CloudColor;
vtx[n].color.a = nRand;
vtx[n].normal = K3DVector( 0.f, 0.f, -1.f);
vtx[n].texcoord0.x = 1.0f;
vtx[n].texcoord0.y = 1.f;
//vtx[n].texcoord1.x = 1.0f;
//vtx[n].texcoord1.y = 1.f;
n++;
}
m_pVB->Unlock();
m_pVB->Backup();
}
void SGameCloud::updateVB( K3DVERTEX_CLOUD* vtx, const SCloudEx& cloud )
{
vtx[ 0 ].position = cloud.GetVertexPosition( SCloudEx::UL );
vtx[ 1 ].position = cloud.GetVertexPosition( SCloudEx::UR );
vtx[ 2 ].position = cloud.GetVertexPosition( SCloudEx::BL );
vtx[ 3 ].position = cloud.GetVertexPosition( SCloudEx::BR );
for( short p = 0; p < 4; p++)
{
vtx[ p ].color = cloud.color;
vtx[ p ].normal = K3DVector( 0.f, 0.f, -1.f);
}
vtx[ 0 ].texcoord0.Set( 0, 0 );
vtx[ 1 ].texcoord0.Set( 1, 0 );
vtx[ 2 ].texcoord0.Set( 0, 1 );
vtx[ 3 ].texcoord0.Set( 1, 1 );
//vtx[ 0 ].texcoord1.Set( 0, 0 );
//vtx[ 1 ].texcoord1.Set( 1, 0 );
//vtx[ 2 ].texcoord1.Set( 0, 1 );
//vtx[ 3 ].texcoord1.Set( 1, 1 );
}
void SGameCloud::initCloudObjects()
{
m_pCloud = new SCloudEx[ m_nCloudCount ];
for(int i = 0; i < m_nCloudCount; ++i)
{
m_pCloud[i].nWidth = 1000+rand()/16000;//(float)(rand()/10000)+1400;
m_pCloud[i].nHeight = 1000+rand()/10000;//(float)(rand()/10000)+1400;
m_pCloud[i].dwStartTime = 0;
m_pCloud[i].dwOldTime = 0;
m_pCloud[i].fRotSpeed = fRotSpeed[0/*rand()%5*/];
m_pCloud[i].fVisibility = 0.8f;
m_pCloud[i].eStep = SCloudEx::MOVE;
}
}
void SGameCloud::procesSCloudEx( int nIndex )
{
assert( nIndex >= 0 && nIndex < m_nCloudCount && "wrong index" );
m_pCloud[ nIndex ].Update( m_dwTime, m_CloudColor );
}
void SGameCloud::_addSoundEvent( const K3DVector& addedPosition )
{
SSoundEvent* se = new SSoundEvent();
se->activeTime = m_dwTime
+ (DWORD)( addedPosition.Magnitude() );
se->activePos = addedPosition;
m_ctSoundEvents.push( se );
}
void SGameCloud::_procSoundEvent()
{
while( !m_ctSoundEvents.empty() )
{
SSoundEvent* se = 0;
se = m_ctSoundEvents.front();
if( se->activeTime >= m_dwTime )
{
//if( m_pSoundMgr )
//{
// m_pSoundMgr->PlaySound3D(
// SCloudEx::s_strSound.c_str(),
// se->activePos.x, se->activePos.y, se->activePos.z,
// 100, false, false, false );
//
//}
SAFE_DELETE( se );
m_ctSoundEvents.pop();
continue;
}
break;
}
}
void SGameCloud::CreateCloudByType( int type )
{
DestroyCloud();
if(type == 0)
{
int nCount = 15;
m_vcCloud.resize(nCount);
for(int x=0; x<nCount; x++)
{
SCloudEx* pCloud = new SCloudEx;
m_vcCloud[x] = pCloud;
}
}
}
void SGameCloud::DestroyCloud()
{
int nCount = m_vcCloud.size();
for(int x=0; x<nCount; x++)
{
SCloudEx* pCloud = m_vcCloud[x];
SAFE_DELETE( pCloud );
}
m_vcCloud.clear();
}
SGameThunderCloud::SGameThunderCloud( int cloud_count )
: SGameCloud ( cloud_count )
{
}
SGameThunderCloud::~SGameThunderCloud()
{
}
void SGameThunderCloud::initCloudObjects()
{
}
#else
const int CLOUD_MAX = 190;
const float START_TIME = 6000.f;
const float END_TIME = 4000.f;
const float DEFAULT_HEIGHT = 500.0f;
// { [sonador]
const int THUNDER_CLOUD_MAX = 3;
const float DEFAULT_HEIGHT_THUNDER_CLOUD = 510.0f;
float fRotSpeed[] =
{
0.2f,
// 0.2f,
// 0.3f,
// 0.4f,
// 0.5f,
};
bool SGameCloud::m_bProcessPause = false;
float SCloudObject::s_fFactor = 0.1f;
float SCloudObject::s_fLightningFactor = 1.0f;
DWORD SCloudObject::s_dwDuration = 250;
int SCloudObject::s_nFlashCount = 3;
K3DColor SCloudObject::s_sDestColor = K3DColor( 0xffdae7fe );
std::string SCloudObject::s_strSound = "";
float SCloudObject::s_fSoundSpeed = 0;
SCloudObject::SCloudObject()
: nWidth ( 0 )
, nHeight ( 0 )
, vPosition ( 0, 0, 0 )
, vStartPosition ( 0, 0, 0 )
, fVisibilityCap ( 1 )
, fVisibility ( 0 )
, color ( 0x00000000 )
, bActive ( false )
, pVecCloud ( 0 )
, dwStartTime ( 0 )
, dwOldTime ( 0 )
, fRotSpeed ( 0.1f )
, eStep ( APPEAR )
, dwThunderBegin ( 0 )
, bLightningEnable ( false )
{
}
void SCloudObject::SetPosition( float x, float y, float z )
{
if( vStartPosition.x == 0.f &&
vStartPosition.y == 0.f &&
vStartPosition.z == 0.f )
vStartPosition = vPosition;
vPosition.Set( x, y, z );
}
void SCloudObject::SetColor( const K3DColor& _color )
{
color.r = (unsigned char)(_color.r * 255);
color.g = (unsigned char)(_color.g * 255);
color.b = (unsigned char)(_color.b * 255);
}
void SCloudObject::SetColor( const KColor& _color )
{
color.r = _color.r;
color.g = _color.g;
color.b = _color.b;
}
void SCloudObject::SetVisibility( float _visibility )
{
fVisibility = std::min( _visibility, fVisibilityCap );
fVisibility = std::max( 0.f, std::min( 1.0f, fVisibility ) );
color.a = (unsigned char)( 255 * fVisibility );
}
void SCloudObject::SetVisibilityCap( float _cap )
{
fVisibilityCap = _cap;
}
K3DVector SCloudObject::GetVertexPosition( EVtxPos _pos_type ) const
{
K3DVector vResult;
switch( _pos_type )
{
case UL:
vResult.Set( vPosition.x - nWidth / 2.f, vPosition.y - nHeight / 2.f, vPosition.z );
break;
case UR:
vResult.Set( vPosition.x + nWidth / 2.f, vPosition.y - nHeight / 2.f, vPosition.z );
break;
case BL:
vResult.Set( vPosition.x - nWidth / 2.f, vPosition.y + nHeight / 2.f, vPosition.z );
break;
case BR:
vResult.Set( vPosition.x + nWidth / 2.f, vPosition.y + nHeight / 2.f, vPosition.z );
break;
}
return vResult;
}
void SCloudObject::checkStartTime( DWORD dwTime_msec_ )
{
if( dwStartTime == 0 )
dwStartTime = dwTime_msec_;
}
void SCloudObject::ResetStartTime()
{
dwStartTime = 0;
}
void SCloudObject::resetPosition()
{
vPosition.x = (K3DVALUE)(-rand()%8000);
vPosition.y = (K3DVALUE)(-rand()%8000);
}
void SCloudObject::ChangeStep( EStep step )
{
eStep = step;
//dwStartTime = 0;
}
void SCloudObject::processByStep( DWORD elapsed_time , const KColor& _cloud_color )
{
//1)처음 나타나면, 0~1 서서히 나타난다.
//2)모두 보이면, 이동 시작
//3)이동이 끝나면 1~0 서서히 사라진다.
switch( eStep )
{
case APPEAR:
this->onAppear( elapsed_time );
break;
case DISAPPEAR:
this->onDisappear( elapsed_time );
break;
case MOVE:
this->onMove( elapsed_time );
break;
case THUNDER:
this->onThunder( elapsed_time );
break;
default:
break;
}
}
void SCloudObject::movePosition()
{
vPosition.x += fRotSpeed;
vPosition.y += fRotSpeed;
}
bool SCloudObject::IsOutOfBound() const
{
return ( vPosition.x > 1800.f || vPosition.y > 1800.f );
}
void SCloudObject::Update( DWORD _time, const KColor& _cloud_color )
{
this->checkStartTime( _time );
DWORD elapsed_time = _time - dwStartTime;
this->SetColor( _cloud_color );
this->SetVisibilityCap( (float)_cloud_color.a / 255 );
this->processByStep( elapsed_time, _cloud_color );
this->movePosition();
if( this->IsOutOfBound() && !this->IsStep( DISAPPEAR ) )
{
this->ChangeStep( DISAPPEAR );
this->ResetStartTime();
}
}
void SCloudObject::onAppear( DWORD elapsed_time )
{
if ( elapsed_time > START_TIME )
{
//종료
this->ChangeStep( MOVE );
this->ResetStartTime();
}
else
{
this->SetVisibility( (float)elapsed_time / START_TIME );
}
}
void SCloudObject::onDisappear( DWORD elapsed_time )
{
if( elapsed_time < END_TIME )
{
this->SetVisibility( 1.f - ( (float)elapsed_time / END_TIME ) );
}
else
{
//this->SetActivity( (rand() % 2) == 1 ); // 랜덤하게 활동여부를 설정하는 이유는?
this->resetPosition();
this->ResetStartTime();
this->ChangeStep( APPEAR );
}
}
void SCloudObject::onMove( DWORD elapsed_time )
{
this->SetVisibility( fVisibilityCap );
}
void SCloudObject::onThunder( DWORD elapsed_time )
{
this->SetVisibility( fVisibilityCap );
if( elapsed_time <= s_dwDuration + dwThunderBegin )
{
float ftheta = K3D_PI * (float)( elapsed_time - dwThunderBegin )
* s_nFlashCount / (float)s_dwDuration;
float fwave = sinf( ftheta );
fwave = fabs( fwave );
color.a = (unsigned char)( fwave * 255.0f );
}
else
{
this->ChangeStep( MOVE );
}
}
SThunderCloudObject::SThunderCloudObject()
: SCloudObject()
{
}
SThunderCloudObject::~SThunderCloudObject()
{
}
void SThunderCloudObject::onAppear( DWORD elapsed_time )
{
this->SetActivity( false );
}
void SThunderCloudObject::onDisappear( DWORD elapsed_time )
{
this->SetActivity( false );
}
void SThunderCloudObject::onMove( DWORD elapsed_time )
{
this->SetActivity( false );
}
void SThunderCloudObject::onThunder( DWORD elapsed_time )
{
this->SetVisibility( fVisibilityCap );
if( elapsed_time <= s_dwDuration + dwThunderBegin )
{
float ftheta = K3D_PI * (float)( elapsed_time - dwThunderBegin )
* s_nFlashCount / (float)s_dwDuration;
float fwave = sinf( ftheta );
fwave = fabs( fwave );
color.a = (unsigned char)( fwave * 255.0f );
}
else
{
this->SetActivity( false );
}
}
SGameCloud::SGameCloud( int cloud_count )
: m_dwTime ( 0 )
, m_nCloudCount ( cloud_count )
, m_CloudColor ( 255, 255, 255, 255 )
, m_bEnableThunder ( false )
, m_pThunderCloud ( 0 )
, m_pLightning ( 0 )
, m_pSoundMgr ( 0 )
, m_pDevice ( 0 )
{
}
SGameCloud::~SGameCloud()
{
SAFE_DELETE( m_pMat );
SAFE_DELETE_ARRAY( m_pCloud );
if( m_pVB )
m_pDevice->DelReloadVertexList( m_pVB );
}
void SGameCloud::Init( K3DRenderDevice *pDevice, K3DIndexBuffer * pIndexBuf )
{
m_pDevice = pDevice;
DWORD dwFormat = 0;
m_pVB = pDevice->CreateVertexBufferUsePoolDefault( sizeof(K3DVERTEX_CLOUD), dwFormat, 4*m_nCloudCount, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY ); //기본 사각형
if( m_pVB && m_pVB->IsValidVtx() )
{
// m_spVB = pDevice->CreateVertexBufferBlend( sizeof(K3DBLENDEDBUMPVERTEX), dwFormat, 4*m_nCloudCount ); //기본 사각형
this->initVB();
m_spIB = NULL; // Index Buf
m_spTexture = NULL;
m_spAlphaTexture = NULL;
m_pMat = new K3DMaterial;
m_pMat->SetAmbient( K3DColor( 1.f, 1.f, 1.f, 1.f ) );
m_pMat->SetDiffuse( K3DColor( 1.f, 1.f, 1.f, 1.f ) );
m_pMat->SetSpecular( K3DColor( 0.f, 0.f, 0.f, 1.f ) );
m_pMat->SetSpecularPower( 1.0f );
m_pParentMat = NULL; // SkyBox 위치
K3DMatrixIdentity( m_LocalMat ); // 구름 위치
K3DMatrixIdentity( m_WorldMat );
m_pPrimitive = new SCloudPrimitive; // Render Object
m_pPrimitive->SetTransparent( true );
m_pPrimitive->SetTransform( &m_LocalMat, &m_WorldMat );
m_pPrimitive->SetVertexBuffer( m_pVB );
m_pPrimitive->SetMaterial( m_pMat );
this->initCloudObjects();
}
}
void SGameCloud::Process( DWORD dwTime )
{
if( IsProcessPause() ) return;
if( m_pVB == NULL || !m_pVB->IsValidVtx() ) return;
m_dwTime = dwTime;
// [sonador] Lock / Unlock 을 짧은 시간에 수행하기 위해 update 를 분리하였음.
for( int it = 0; it < m_nCloudCount; ++it )
{
if( m_pCloud[ it ].IsActive() )
this->processCloudObject( it );
}
K3DVERTEX_CLOUD* vtx = NULL;
int nVtxSize;
int nPrimCnt = 0;
//D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨.
#if defined( _DEBUG )
m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD );
#else
m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_DISCARD );
#endif
assert(vtx && "m_pVB->Lock( (void**)&vtx, nVtxSize );");
if( vtx == NULL ) return;
for(int it = 0; it < m_nCloudCount; ++it)
{
if( m_pCloud[ it ].IsActive() )
{
this->updateVB( &vtx[ nPrimCnt * 4 ], m_pCloud[ it ] );
}
else
{
vtx[ nPrimCnt * 4 + 0 ].color.a = 0;
vtx[ nPrimCnt * 4 + 1 ].color.a = 0;
vtx[ nPrimCnt * 4 + 2 ].color.a = 0;
vtx[ nPrimCnt * 4 + 3 ].color.a = 0;
}
++nPrimCnt;
}
m_pVB->Unlock();
m_pPrimitive->SetVertexCnt( nPrimCnt * 4 );
/*K3DMatrix mat;
K3DMatrixIdentity( mat );
//K3DMatrixRotationAxis( &mat, m_pVecCloud, (10.f*K3D_PI/180.f) );
K3DMatrixIdentity( m_LocalMat );
K3DMatrixSetPosVector( m_LocalMat, m_Pos );
K3DMatrixMultiply( &m_LocalMat, &mat, &m_LocalMat );
if( m_pParentMat )
K3DMatrixMultiply( &m_LocalMat, &m_LocalMat, m_pParentMat );*/
}
void SGameCloud::Render( KViewportObject *viewport )
{
if( m_pPrimitive && m_pPrimitive->GetVertexCnt() > 0 )
{
viewport->Register( m_pPrimitive, KRenderObject::RENDEREFX_CLOUD );
}
}
void SGameCloud::SetHeight( int i, float fz )
{
if( i >=0 && i < m_nCloudCount )
{
m_pCloud[i].vPosition.z = fz;
}
else
{
assert( !"SGameCloud : refered wrong index" );
}
//if( m_pThunderCloud )
// m_pThunderCloud->SetHeight( i, fz );
}
void SGameCloud::SetPosition( int i, float fx, float fy, float fz )
{
if( i >=0 && i < m_nCloudCount )
{
m_pCloud[i].SetPosition( fx, fy, fz );
}
else
{
assert( !"SGameCloud : refered wrong index" );
}
//if( m_pThunderCloud )
// m_pThunderCloud->SetPosition( i, fz, fy, fz );
}
void SGameCloud::SetMaxVisibility( int i, float fVis )
{
if( i >=0 && i < m_nCloudCount )
{
m_pCloud[i].SetVisibilityCap( fVis );
}
else
{
assert( !"SGameCloud : refered wrong index" );
}
//if( m_pThunderCloud )
// m_pThunderCloud->SetMaxVisibility( i, fVis );
}
void SGameCloud::SetVisibility( int i, float fVis )
{
if( i >=0 && i < m_nCloudCount )
{
m_pCloud[i].SetVisibility( fVis );
}
else
{
assert( !"SGameCloud : refered wrong index" );
}
//if( m_pThunderCloud )
// m_pThunderCloud->SetVisibility( i, fVis );
}
void SGameCloud::SetCloudColor( int i, K3DColor & color )
{
if( i >=0 && i < m_nCloudCount )
{
m_pCloud[ i ].SetColor( color );
}
else
{
assert(0);
}
//if( m_pThunderCloud )
// m_pThunderCloud->SetCloudColor( i, color );
}
void SGameCloud::SetCloudColor( KColor & color )
{
m_CloudColor = color;
if( m_pThunderCloud )
m_pThunderCloud->SetCloudColor( color );
}
void SGameCloud::SetEnableThunderFx( bool bEnable )
{
m_bEnableThunder = bEnable;
}
void SGameCloud::SetThunderCloud( SGameCloud* pThunderCloud )
{
m_pThunderCloud = pThunderCloud;
}
void SGameCloud::SetLightning( env_fx::SGameLightning* pLightning )
{
m_pLightning = pLightning;
}
void SGameCloud::SetTransform( K3DMatrix* pParentMatrix )
{
SetParentMat( pParentMatrix );
m_pPrimitive->SetTransform( pParentMatrix, pParentMatrix );
if( m_pThunderCloud )
m_pThunderCloud->SetTransform( pParentMatrix );
if( m_pLightning )
m_pLightning->SetParentMatrix( pParentMatrix );
}
SCloudObject* SGameCloud::GetFirstDeactiveCloud()
{
SCloudObject* pCloud = std::find_if(
&m_pCloud[ 0 ], &m_pCloud[ m_nCloudCount ], SFindFirstDeactiveCloud() );
if( pCloud != &m_pCloud[ m_nCloudCount ] )
return pCloud;
return 0;
}
void SGameCloud::SetSoundManager( SGameMilesSoundMgr* pSoundMgr )
{
m_pSoundMgr = pSoundMgr;
}
void SGameCloud::initVB()
{
K3DVERTEX_CLOUD* vtx = NULL;
int nVtxSize;
m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD );
assert(vtx && "m_pVB->Lock( (void**)&vtx, nVtxSize );");
if( vtx == NULL ) return;
for( int n=0; 4 * m_nCloudCount > n; )
{
int nRand = rand() % 150 + 255;
vtx[n].position = K3DVector( (float)-m_nWidth/2.f, (float)-m_nHeight/2.f, 0 );
vtx[n].color = m_CloudColor;
vtx[n].color.a = nRand;
vtx[n].normal = K3DVector( 0.f, 0.f, -1.f);
vtx[n].texcoord0.x = 0.f;
vtx[n].texcoord0.y = 0.f;
//vtx[n].texcoord1.x = 0.f;
//vtx[n].texcoord1.y = 0.f;
n++;
vtx[n].position = K3DVector( m_nWidth / 2.f, (float)-m_nHeight/2.f, 0 );
vtx[n].color = m_CloudColor;
vtx[n].color.a = nRand;
vtx[n].normal = K3DVector( 0.f, 0.f, -1.f);
vtx[n].texcoord0.x = 1.f;
vtx[n].texcoord0.y = 0.f;
//vtx[n].texcoord1.x = 1.f;
//vtx[n].texcoord1.y = 0.f;
n++;
vtx[n].position = K3DVector( (float)-m_nWidth/2.f, m_nHeight / 2.f, 0 );
vtx[n].color = m_CloudColor;
vtx[n].color.a = nRand;
vtx[n].normal = K3DVector( 0.f, 0.f, -1.f);
vtx[n].texcoord0.x = 0.0f;
vtx[n].texcoord0.y = 1.f;
//vtx[n].texcoord1.x = 0.0f;
//vtx[n].texcoord1.y = 1.f;
n++;
vtx[n].position = K3DVector( m_nWidth / 2.f, m_nHeight / 2.f, 0 );
vtx[n].color = m_CloudColor;
vtx[n].color.a = nRand;
vtx[n].normal = K3DVector( 0.f, 0.f, -1.f);
vtx[n].texcoord0.x = 1.0f;
vtx[n].texcoord0.y = 1.f;
//vtx[n].texcoord1.x = 1.0f;
//vtx[n].texcoord1.y = 1.f;
n++;
}
m_pVB->Unlock();
m_pVB->Backup();
}
void SGameCloud::updateVB( K3DVERTEX_CLOUD* vtx, const SCloudObject& cloud )
{
vtx[ 0 ].position = cloud.GetVertexPosition( SCloudObject::UL );
vtx[ 1 ].position = cloud.GetVertexPosition( SCloudObject::UR );
vtx[ 2 ].position = cloud.GetVertexPosition( SCloudObject::BL );
vtx[ 3 ].position = cloud.GetVertexPosition( SCloudObject::BR );
for( short p = 0; p < 4; p++)
{
vtx[ p ].color = cloud.color;
vtx[ p ].normal = K3DVector( 0.f, 0.f, -1.f);
}
vtx[ 0 ].texcoord0.Set( 0, 0 );
vtx[ 1 ].texcoord0.Set( 1, 0 );
vtx[ 2 ].texcoord0.Set( 0, 1 );
vtx[ 3 ].texcoord0.Set( 1, 1 );
//vtx[ 0 ].texcoord1.Set( 0, 0 );
//vtx[ 1 ].texcoord1.Set( 1, 0 );
//vtx[ 2 ].texcoord1.Set( 0, 1 );
//vtx[ 3 ].texcoord1.Set( 1, 1 );
}
void SGameCloud::initCloudObjects()
{
m_pCloud = new SCloudObject[ m_nCloudCount ];
for(int i = 0; i < m_nCloudCount; ++i)
{
m_pCloud[i].nWidth = 1000+rand()/16000;//(float)(rand()/10000)+1400;
m_pCloud[i].nHeight = 1000+rand()/10000;//(float)(rand()/10000)+1400;
m_pCloud[i].dwStartTime = 0;
m_pCloud[i].dwOldTime = 0;
m_pCloud[i].fRotSpeed = fRotSpeed[0/*rand()%5*/];
m_pCloud[i].fVisibility = 0.8f;
m_pCloud[i].eStep = SCloudObject::MOVE;
}
}
void SGameCloud::processCloudObject( int nIndex )
{
assert( nIndex >= 0 && nIndex < m_nCloudCount && "wrong index" );
m_pCloud[ nIndex ].Update( m_dwTime, m_CloudColor );
if( m_bEnableThunder && m_pThunderCloud &&
m_pCloud[ nIndex ].IsStep( SCloudObject::MOVE ) &&
(float)( rand() % 100000 ) * 0.001f <= SCloudObject::s_fFactor )
{
SCloudObject* pCloud = m_pThunderCloud->GetFirstDeactiveCloud();
if( pCloud )
{
pCloud->SetActivity( true );
pCloud->ResetStartTime();
pCloud->vPosition = m_pCloud[ nIndex ].vPosition;
pCloud->vPosition.z = DEFAULT_HEIGHT_THUNDER_CLOUD;
pCloud->ChangeStep( SCloudObject::THUNDER );
pCloud->nWidth = m_pCloud[ nIndex ].nWidth;
pCloud->nHeight = m_pCloud[ nIndex ].nHeight;
}
// make lightning effect
if( m_pLightning )
{
float fRand = env_fx::util::GetRandomNumberInRange( 0.0f, 100.0f );
if( fRand <= SCloudObject::s_fLightningFactor )
{
//bLightningEnable = true;
m_pLightning->Emit( m_pCloud[ nIndex ].vPosition );
if( SCloudObject::s_strSound.size() > 0 )
_addSoundEvent( m_pCloud[ nIndex ].vPosition );
}
}
}
}
void SGameCloud::_addSoundEvent( const K3DVector& addedPosition )
{
SSoundEvent* se = new SSoundEvent();
se->activeTime = m_dwTime
+ (DWORD)( SCloudObject::s_fSoundSpeed * addedPosition.Magnitude() );
se->activePos = addedPosition;
m_ctSoundEvents.push( se );
}
void SGameCloud::_procSoundEvent()
{
while( !m_ctSoundEvents.empty() )
{
SSoundEvent* se = 0;
se = m_ctSoundEvents.front();
if( se->activeTime >= m_dwTime )
{
//if( m_pSoundMgr )
//{
// m_pSoundMgr->PlaySound3D(
// SCloudObject::s_strSound.c_str(),
// se->activePos.x, se->activePos.y, se->activePos.z,
// 100, false, false, false );
//
//}
SAFE_DELETE( se );
m_ctSoundEvents.pop();
continue;
}
break;
}
}
SGameThunderCloud::SGameThunderCloud( int cloud_count )
: SGameCloud ( cloud_count )
{
}
SGameThunderCloud::~SGameThunderCloud()
{
}
void SGameThunderCloud::initCloudObjects()
{
m_pCloud = new SThunderCloudObject[ m_nCloudCount ];
for(int i = 0; i < m_nCloudCount; ++i)
{
m_pCloud[i].nWidth = 1000+rand()/16000;//(float)(rand()/10000)+1400;
m_pCloud[i].nHeight = 1000+rand()/10000;//(float)(rand()/10000)+1400;
m_pCloud[i].dwStartTime = 0;
m_pCloud[i].dwOldTime = 0;
m_pCloud[i].fRotSpeed = fRotSpeed[0/*rand()%5*/];
m_pCloud[i].fVisibility = 0.8f;
m_pCloud[i].eStep = SCloudObject::MOVE;
}
}
#endif
#ifdef CLOUD_LUA
//---------------------------------------------------------------------------------------
// Kind
CCloudKindDB& GetCloudKindDB()
{
return *g_pCloudKindDB;
}
CCloudKindDB::CCloudKindDB()
{
}
CCloudKindDB::~CCloudKindDB()
{
clear();
}
void CCloudKindDB::add(int id, SCloudKind* pKind)
{
if( pKind )
m_vcKind.push_back( pKind );
}
void CCloudKindDB::clear()
{
for(int i = 0; i < (int)m_vcKind.size(); ++i)
{
SCloudKind* p = m_vcKind[ i ];
SAFE_DELETE( p );
}
m_vcKind.clear();
}
void CCloudKindDB::size(int sz)
{
clear();
}
SCloudKind* CCloudKindDB::find(int id)
{
int k=0;
return m_vcKind[ id ];
}
float CCloudKindDB::calculateRate(int nKindID, int nGrade, int nMaxGrade)
{
// 9 : nTickness = ? : k
// ? = 9 x k / nTickness
// 9 : 33 = ? : 4
// ? = 9 * 4 / 33
double dbMock = 0.0f;
double nKindGapID = double( ( (float)nGrade * MAX_KIND_GRADE_F ) / (float)nMaxGrade );
float fNamujiRate = (float)modf(nKindGapID, &dbMock);
int nMock = (int)dbMock;
float fSZ0, fSZ1;
if ( nMock >= MAX_KIND_GRADE - 1 ) // 몫이 마지막이면
{
fSZ1 = (float)m_vcKind[ nKindID ]->v[ MAX_KIND_GRADE - 1 ] * RATE_CONVERT_100;
fSZ0 = (float)m_vcKind[ nKindID ]->v[ MAX_KIND_GRADE - 2 ] * RATE_CONVERT_100;
}
else if( nMock == 0 ) // 몫이 처음이면
{
fSZ1 = (float)m_vcKind[ nKindID ]->v[ 1 ] * RATE_CONVERT_100;
fSZ0 = (float)m_vcKind[ nKindID ]->v[ 0 ] * RATE_CONVERT_100;
}
else
{
fSZ1 = (float)m_vcKind[ nKindID ]->v[ nMock + 1 ] * RATE_CONVERT_100;
fSZ0 = (float)m_vcKind[ nKindID ]->v[ nMock ] * RATE_CONVERT_100;
}
float fRate = fSZ0 - ( (fSZ0 - fSZ1) * fNamujiRate );
if( fRate > 1.0f ) // 사실 이건 에러임!!
fRate = 1.0f;
return fRate;
}
//---------------------------------------------------------------------------------------
// thickness
CCloudThicknessDB& GetCloudThicknessDB()
{
return *g_pCloudThicknesDB;
}
CCloudThicknessDB::CCloudThicknessDB()
{
}
CCloudThicknessDB::~CCloudThicknessDB()
{
clear();
}
void CCloudThicknessDB::add(int id, int nThickness)
{
if( nThickness )
m_vcTickness.push_back( nThickness );
}
void CCloudThicknessDB::clear()
{
m_vcTickness.clear();
}
void CCloudThicknessDB::size(int sz)
{
clear();
}
int CCloudThicknessDB::find(int id)
{
return m_vcTickness[ id ];
}
//---------------------------------------------------------------------------------------
// thickness gap
CCloudThicknessGapDB& GetCloudThicknessGapDB()
{
return *g_pCloudThicknessGapDB;
}
CCloudThicknessGapDB::CCloudThicknessGapDB()
{
}
CCloudThicknessGapDB::~CCloudThicknessGapDB()
{
clear();
}
void CCloudThicknessGapDB::add(int id, float fThickness)
{
if( fThickness > 0.0f )
m_vcTicknessGap.push_back( fThickness );
}
void CCloudThicknessGapDB::clear()
{
m_vcTicknessGap.clear();
}
void CCloudThicknessGapDB::size(int sz)
{
clear();
}
float CCloudThicknessGapDB::find(int id)
{
return m_vcTicknessGap[ id ];
}
//---------------------------------------------------------------------------------------
// Size
CCloudSizeDB& GetCloudSizeDB()
{
return *g_pCloudSizeDB;
}
CCloudSizeDB::CCloudSizeDB()
{
}
CCloudSizeDB::~CCloudSizeDB()
{
clear();
}
void CCloudSizeDB::add(int id, SCloudSize* pSize)
{
int k=0;
if( pSize )
m_vcSize.push_back( pSize );
}
void CCloudSizeDB::clear()
{
for(int i = 0; i < (int)m_vcSize.size(); ++i)
{
SCloudSize* p = m_vcSize[ i ];
SAFE_DELETE( p );
}
m_vcSize.clear();
}
void CCloudSizeDB::size(int sz)
{
clear();
m_vcSize.resize(sz);
}
SCloudSize* CCloudSizeDB::find(int id)
{
int k=0;
return m_vcSize[ id ];
}
//---------------------------------------------------------------------------------------
// texture names
CCloudTxrNames::CCloudTxrNames()
{
}
CCloudTxrNames::~CCloudTxrNames()
{
clear();
}
void CCloudTxrNames::add(int id, std::string* pStrTxrName)
{
if( pStrTxrName )
m_vcName.push_back( pStrTxrName );
}
void CCloudTxrNames::clear()
{
for(int i = 0; i < (int)m_vcName.size(); ++i)
{
std::string* p = m_vcName[ i ];
SAFE_DELETE( p );
}
m_vcName.clear();
}
void CCloudTxrNames::size(int sz)
{
clear();
}
std::string* CCloudTxrNames::find(int id)
{
if( id >= 0 && id < (int)m_vcName.size() )
return m_vcName[ id ];
return NULL;
}
// texture name group
CCloudTxrGroupDB& GetCloudTxrGroupDB()
{
return *g_pCloudTxrGroupDB;;
}
CCloudTxrGroupDB::CCloudTxrGroupDB()
{
}
CCloudTxrGroupDB::~CCloudTxrGroupDB()
{
clear();
}
int CCloudTxrGroupDB::get_size(int brightness_type)
{
if ( brightness_type == NORMAL )
return (int)m_vcNormal.size();
else if( brightness_type == MIDDLE )
return (int)m_vcMiddle.size();
else if( brightness_type == DARK )
return (int)m_vcDark.size();
return 0;
}
void CCloudTxrGroupDB::add(int brightness_type, int id, CCloudTxrNames* pTxrNames)
{
int k=0;
if (brightness_type == NORMAL)
{
m_vcNormal.push_back( pTxrNames );
}
else if(brightness_type == MIDDLE)
{
m_vcMiddle.push_back( pTxrNames );
}
else if(brightness_type == DARK)
{
m_vcDark.push_back( pTxrNames );
}
}
void CCloudTxrGroupDB::clear(int brightness_type)
{
if (brightness_type == NORMAL)
{
for(int i = 0; i < (int)m_vcNormal.size(); ++i)
{
CCloudTxrNames* p = m_vcNormal[ i ];
SAFE_DELETE( p );
}
m_vcNormal.clear();
}
else if(brightness_type == MIDDLE)
{
for(int i = 0; i < (int)m_vcMiddle.size(); ++i)
{
CCloudTxrNames* p = m_vcMiddle[ i ];
SAFE_DELETE( p );
}
m_vcMiddle.clear();
}
else if(brightness_type == DARK)
{
for(int i = 0; i < (int)m_vcDark.size(); ++i)
{
CCloudTxrNames* p = m_vcDark[ i ];
SAFE_DELETE( p );
}
m_vcDark.clear();
}
else if(brightness_type == END)
{
clear( NORMAL );
clear( MIDDLE );
clear( DARK );
}
}
void CCloudTxrGroupDB::size(int brightness_type, int sz)
{
if (brightness_type == NORMAL)
{
clear( brightness_type );
}
else if(brightness_type == MIDDLE)
{
clear( brightness_type );
}
else if(brightness_type == DARK)
{
clear( brightness_type );
}
}
CCloudTxrNames* CCloudTxrGroupDB::find(int brightness_type, int id)
{
if (brightness_type == NORMAL)
{
if( id >= 0 && id < (int)m_vcNormal.size() )
return m_vcNormal[ id ];
}
else if(brightness_type == MIDDLE)
{
if( id >= 0 && id < (int)m_vcMiddle.size() )
return m_vcMiddle[ id ];
}
else if(brightness_type == DARK)
{
if( id >= 0 && id < (int)m_vcDark.size() )
return m_vcDark[ id ];
}
return NULL;
}
std::string* CCloudTxrGroupDB::find_str(int brightness_type, int id)
{
CCloudTxrNames* pCloudTxrName = GetCloudTxrGroupDB().find( brightness_type, id );
if( pCloudTxrName )
{
return pCloudTxrName->find( GetSafeTickCount() % (pCloudTxrName->get_size()) );
}
else
{
_oprint( "CCloudTxrNames : not find texturename" );
}
}
//---------------------------------------------------------------------------------------
// thickness
CCloudDistributionDB& GetCloudDistributionDB()
{
return *g_pCloudDistributionDB;
}
CCloudDistributionDB::CCloudDistributionDB()
{
}
CCloudDistributionDB::~CCloudDistributionDB()
{
clear();
}
void CCloudDistributionDB::add(int id, int nDistribution)
{
if( nDistribution )
m_vcDistribution.push_back( nDistribution );
}
void CCloudDistributionDB::clear()
{
m_vcDistribution.clear();
}
void CCloudDistributionDB::size(int sz)
{
clear();
}
int CCloudDistributionDB::find(int id)
{
return m_vcDistribution[ id ];
}
//---------------------------------------------------------------------------------------
// distribution
CCloudHeightRadomGapDB& GetCloudHeightRadomGapDB()
{
return *g_pCloudHeightRadomGapDB;
}
CCloudHeightRadomGapDB::CCloudHeightRadomGapDB()
{
}
CCloudHeightRadomGapDB::~CCloudHeightRadomGapDB()
{
clear();
}
void CCloudHeightRadomGapDB::add(int id, int nRadomGap)
{
m_vcRadomGap.push_back( nRadomGap );
}
void CCloudHeightRadomGapDB::clear()
{
m_vcRadomGap.clear();
}
void CCloudHeightRadomGapDB::size(int sz)
{
clear();
}
int CCloudHeightRadomGapDB::find(int id)
{
return m_vcRadomGap[ id ];
}
//---------------------------------------------------------------------------------------
// layer gap
CCloudLayerGapDB& GetCloudLayerGapDB()
{
return *g_pCloudCloudLayerGapDB;
}
CCloudLayerGapDB::CCloudLayerGapDB()
{
}
CCloudLayerGapDB::~CCloudLayerGapDB()
{
clear();
}
void CCloudLayerGapDB::add(int id, int nLayerGap)
{
m_vcLayerGap.push_back( nLayerGap );
}
void CCloudLayerGapDB::clear()
{
m_vcLayerGap.clear();
}
void CCloudLayerGapDB::size(int sz)
{
clear();
}
int CCloudLayerGapDB::find(int id)
{
return m_vcLayerGap[ id ];
}
//---------------------------------------------------------------------------------------
// layer gap
CCloudMoveDirDB& GetCloudMoveDirDB()
{
return *g_pCloudCloudMoveDirDB;
}
CCloudMoveDirDB::CCloudMoveDirDB()
{
}
CCloudMoveDirDB::~CCloudMoveDirDB()
{
clear();
}
void CCloudMoveDirDB::add(int id, int nMoveDir)
{
m_vcMoveDir.push_back( nMoveDir );
}
void CCloudMoveDirDB::clear()
{
m_vcMoveDir.clear();
}
void CCloudMoveDirDB::size(int sz)
{
clear();
}
int CCloudMoveDirDB::find(int id)
{
return m_vcMoveDir[ id ];
}
//---------------------------------------------------------------------------------------
// path
CCloudPathDB& GetCloudPathDB()
{
return *g_pCloudPathDB;
}
CCloudPathDB::CCloudPathDB()
{
}
CCloudPathDB::~CCloudPathDB()
{
clear();
}
void CCloudPathDB::add(int id, SCloudPath* pPath)
{
if( pPath )
m_vcPath.push_back( pPath );
}
void CCloudPathDB::clear()
{
for(int i = 0; i < (int)m_vcPath.size(); ++i)
{
SCloudPath* p = m_vcPath[ i ];
SAFE_DELETE( p );
}
m_vcPath.clear();
}
void CCloudPathDB::size(int sz)
{
clear();
}
SCloudPath* CCloudPathDB::find(int id)
{
return m_vcPath[ id ];
}
float CCloudPathDB::calculateHeight(SCalculateHeightParam& sParam)
{
//-----------------------------------------------
// y
// ↑┌─────┐ N
// ││ → → → │ ↑
// ││ ← ← ← │ │
// ││ ↓ ↑ │ W ←─┼─→ E
// ││ ↓ ↑ │ │
// ││ │ ↓
// │└─────┘ S
// 0 ──────→x
//-----------------------------------------------
// max
// *
// * *
// * *
// * *
// start finish
//-----------------------------------------------
if( sParam.nPathType < 0 || sParam.nPathType >= (int)m_vcPath.size() )
return 0.0f;
int nLayerGap = 0;
if( sParam.nLayerGapType > 0 ) // 0번 타입은 기본 경로를 사용, 0번 타입보다 클때만 적용한다
nLayerGap = GetCloudLayerGapDB().find( sParam.nLayerGapType );
// x : (zonex / 2) = ? : max
// ? = max * x / (zonex / 2)
SCloudPath* pPath = m_vcPath[ sParam.nPathType ];
int max = pPath->max + nLayerGap;
float fMaxHeight = float(max);
float fHalfWidth = sParam.zoneX / 2.0f;
float fHalfHeight = sParam.zoneY / 2.0f;
float fResultHeight = 0.0f;
if (sParam.nDir == 0 || sParam.nDir == 1) // 동→ 서←
{
if( sParam.x < fHalfWidth )
{
fResultHeight = ( ( fMaxHeight * sParam.x ) / fHalfWidth );
if( sParam.y < fHalfHeight )
{
// fResultHeight : fHalfHeight = h : sParam.y
// h = sParam.y * fResultHeight / fHalfHeight;
float fH = fResultHeight * sParam.y / fHalfHeight;
fResultHeight = fH + pPath->start;
}
else
{
float ty = sParam.y - fHalfHeight;
float fH = fResultHeight * (fHalfHeight - ty) / fHalfHeight;
fResultHeight = fH + pPath->start;
}
}
else
{
float tx = sParam.x - fHalfWidth;
fResultHeight = ( fMaxHeight - ( ( fMaxHeight * tx ) / fHalfWidth ) );
if( sParam.y < fHalfHeight )
{
float fH = fResultHeight * sParam.y / fHalfHeight;
fResultHeight = fH + pPath->start;
}
else
{
float ty = sParam.y - fHalfHeight;
float fH = fResultHeight * (fHalfHeight - ty) / fHalfHeight;
fResultHeight = fH + pPath->start;
}
}
}
else if(sParam.nDir == 2 || sParam.nDir == 3) // 남↓ 북↑
{
if( sParam.y < fHalfHeight )
{
fResultHeight = ( ( fMaxHeight * sParam.y ) / fHalfHeight );
if( sParam.x < fHalfWidth )
{
// fResultHeight : fHalfWidth = x : sParam.x
// x = sParam.x * fResultHeight / fHalfWidth;
float fW = fResultHeight * sParam.x / fHalfWidth;
fResultHeight = fW + pPath->start;
}
else
{
float tx = sParam.x - fHalfHeight;
float fW = fResultHeight * (fHalfWidth - tx) / fHalfWidth;
fResultHeight = fW + pPath->start;
}
}
else
{
float ty = sParam.y - fHalfHeight;
fResultHeight = ( fMaxHeight - ( ( fMaxHeight * ty ) / fHalfHeight ) );
if( sParam.x < fHalfWidth )
{
float fW = fResultHeight * sParam.x / fHalfWidth;
fResultHeight = fW + pPath->start;
}
else
{
float tx = sParam.x - fHalfWidth;
float fW = fResultHeight * (fHalfWidth - tx) / fHalfWidth;
fResultHeight = fW + pPath->start;
}
}
}
return fResultHeight;
}
//---------------------------------------------------------------------------------------
// cloud
CCloudTypeInfoDB& GetCloudTypeInfoDB()
{
return *g_pCloudTypeInfoDB;
}
CCloudTypeInfoDB::CCloudTypeInfoDB()
{
}
CCloudTypeInfoDB::~CCloudTypeInfoDB()
{
clear();
}
void CCloudTypeInfoDB::add(int id, SCloudTypeInfo* pTypeInfo)
{
m_vcTypeInfo.push_back( pTypeInfo );
}
void CCloudTypeInfoDB::clear()
{
for(int i = 0; i < (int)m_vcTypeInfo.size(); ++i)
{
SCloudTypeInfo* p = m_vcTypeInfo[ i ];
SAFE_DELETE( p );
}
m_vcTypeInfo.clear();
}
void CCloudTypeInfoDB::size(int sz)
{
clear();
}
SCloudTypeInfo* CCloudTypeInfoDB::find(int id)
{
return m_vcTypeInfo[ id ];
}
//---------------------------------------------------------------------------------------
// appear layer
void SCloudLayer::add(int id, SCloudShowInfo* pLayer)
{
vcShowInfo.push_back( pLayer );
}
void SCloudLayer::clear()
{
for(int i = 0; i < (int)vcShowInfo.size(); ++i)
{
SCloudShowInfo* p = vcShowInfo[ i ];
SAFE_DELETE( p );
}
vcShowInfo.clear();
}
void SCloudLayer::size(int sz)
{
clear();
}
SCloudShowInfo* SCloudLayer::find(int id)
{
return vcShowInfo[ id ];
}
// appear layer
CCloudLayerDB* GetCloudLayerDB()
{
return g_pCloudLayerDB;
}
CCloudLayerDB::CCloudLayerDB()
{
int k=0;
}
CCloudLayerDB::~CCloudLayerDB()
{
clear();
}
void CCloudLayerDB::add(int id, SCloudLayer* pLayer)
{
m_vcLayer.push_back( pLayer );
}
void CCloudLayerDB::clear()
{
for(int i = 0; i < (int)m_vcLayer.size(); ++i)
{
SCloudLayer* p = m_vcLayer[ i ];
SAFE_DELETE( p );
}
m_vcLayer.clear();
}
void CCloudLayerDB::size(int sz)
{
clear();
}
SCloudLayer* CCloudLayerDB::find(int id)
{
return m_vcLayer[ id ];
}
//---------------------------------------------------------------------------------------
// appear layer set
void SCloudLayerSet::add(int id, SCloudLayerInfo* pLayer)
{
vcLayerInfo.push_back( pLayer );
}
void SCloudLayerSet::clear()
{
for(int i = 0; i < (int)vcLayerInfo.size(); ++i)
{
SCloudLayerInfo* p = vcLayerInfo[ i ];
SAFE_DELETE( p );
}
vcLayerInfo.clear();
}
void SCloudLayerSet::size(int sz)
{
clear();
}
SCloudLayerInfo* SCloudLayerSet::find(int id)
{
return vcLayerInfo[ id ];
}
// appear layer
CCloudLayerSetDB* GetCloudLayerSetDB()
{
return g_pCloudLayerSetDB;
}
CCloudLayerSetDB::CCloudLayerSetDB()
{
}
CCloudLayerSetDB::~CCloudLayerSetDB()
{
clear();
}
int CCloudLayerSetDB::get_size()
{
return (int)m_vcLayerSet.size();
}
void CCloudLayerSetDB::add(int id, SCloudLayerSet* pLayer)
{
m_vcLayerSet.push_back( pLayer );
}
void CCloudLayerSetDB::clear()
{
for(int i = 0; i < (int)m_vcLayerSet.size(); ++i)
{
SCloudLayerSet* p = m_vcLayerSet[ i ];
SAFE_DELETE( p );
}
m_vcLayerSet.clear();
}
void CCloudLayerSetDB::size(int sz)
{
clear();
// m_vcLayerSet.resize(sz);
}
SCloudLayerSet* CCloudLayerSetDB::find(int id)
{
return m_vcLayerSet[ id ];
}
//---------------------------------------------------------------------------------------
// SCloudVertexBufferPack
//---------------------------------------------------------------------------------------
void SCloudVertexBufferPack::add(K3DVERTEX_CLOUD* pVtx)
{
vcVB.push_back(pVtx);
}
void SCloudVertexBufferPack::add(int id, K3DVERTEX_CLOUD* pVtx)
{
vcVB.push_back(pVtx);
}
void SCloudVertexBufferPack::clear()
{
for(int i = 0; i < (int)vcVB.size(); ++i)
{
K3DVERTEX_CLOUD* p = vcVB[ i ];
SAFE_DELETE( p );
}
vcVB.clear();
}
K3DVERTEX_CLOUD* SCloudVertexBufferPack::find(int id)
{
if(id < 0 || id >= (int)vcVB.size())
return NULL;
return vcVB[ id ];
}
//---------------------------------------------------------------------------------------
// cloud unit
//---------------------------------------------------------------------------------------
CCloudUnit::CCloudUnit()
: SGameEnvCloud(), m_pDevice( 0 )
{
SetFadeState( FADE_NONE );
m_fMoveFrame = 0.0f;
m_fMovePosX = m_fMovePosY = m_fMovePosZ = 0.0f;
}
CCloudUnit::~CCloudUnit()
{
SAFE_DELETE(m_pPrimitive);
}
int CCloudUnit::make(SCloudCreateParam& pr)
{
m_fMoveFrame = 0.0f;
m_fMovePosX = m_vPos.x;
m_fMovePosY = m_vPos.y;
m_nDir = pr.nDir;
if ( m_nDir == 0 )
m_vDir = K3DVector(-1.0f, 0.0f, 0.0f);
else if( m_nDir == 1 )
m_vDir = K3DVector(1.0f, 0.0f, 0.0f);
else if( m_nDir == 2 )
m_vDir = K3DVector(0.0f, 1.0f, 0.0f);
else if( m_nDir == 3 )
m_vDir = K3DVector(0.0f, -1.0f, 0.0f);
int nCurrentTick = (int)GetSafeTickCount();
m_nType = pr.nType;
m_nLayerGap = pr.nLayerGapType;
m_nPath = pr.nPath;
SCloudTypeInfo* pTypeInfo = GetCloudTypeInfoDB().find( m_nType ); // 구름 타입정보를 구한다
if( pTypeInfo == NULL )
return 0;
m_nTypeSize = pTypeInfo->type_size; // 크기 타입
m_nTypeThickness = pTypeInfo->type_thickness; // 두께 타입
m_nTypeThicknessGap = pTypeInfo->type_thickness_gap; // 두께 간격 타입
m_nTypeTxrGroup[C_BRIGHT] = pTypeInfo->type_txr_normal; // 보통 덱스처 그룸 타입
m_nTypeTxrGroup[C_GRAY] = pTypeInfo->type_txr_middle; // 중간 밝기 텍스처 그룹 타입
m_nTypeTxrGroup[C_DARK] = pTypeInfo->type_txr_dark; // 어두운 텍스처 그룹 타입
m_fMoveSpeed = pTypeInfo->fMoveSpeed; // 이동 속도
m_nThickness = GetCloudThicknessDB().find( m_nTypeThickness ); // 구름 두께 구함
if( m_nThickness <= 0 )
return -1;
float fThicknessGap = GetCloudThicknessGapDB().find( m_nTypeThicknessGap ); // 구름 두께 간격 ( 구름 평면간의 간격 )
if( fThicknessGap < 0.0f )
return -2;
SCloudKind* pKind = GetCloudKindDB().find( m_nType ); // 구름모양의 종류 디비
if( pKind == NULL )
return -3;
SCloudSize* pSizeType = GetCloudSizeDB().find( m_nTypeSize ); // cloud size
if( pSizeType == NULL )
return -4;
float fSizeGap = pSizeType->e - pSizeType->s;
int nSGap = 3;
if( fSizeGap < 0.0f )
nSGap = 1;
float fCloudSize100 = (float)( (GetSafeTickCount() % nSGap) + pSizeType->s );
float fRealSizeW2 = fCloudSize100 / 2.0f;
// height
float fHeight = pr.fStandardHeight + ((float)m_nThickness * fThicknessGap);
GenerateCloudTexture( CCloudTxrGroupDB::NORMAL ); // 밝은 텍스처
GenerateCloudTexture( CCloudTxrGroupDB::MIDDLE ); // 중간 밝기 텍스처
GenerateCloudTexture( CCloudTxrGroupDB::DARK ); // 어두운 텍스처
int nHalfCount = m_nThickness / 2;
int j=0;
float fG = 1.0f / (float)nHalfCount;
for(int k=m_nThickness; k>0; k--)
{
float fRate = GetCloudKindDB().calculateRate(m_nType, k, m_nThickness); // 지정된 두께 비율에 따라 현재 단계의 비율을 구한다
float fCurrentCloudSize = fRate + fCloudSize100; // 구름 타입의 9단계 비율과 구름 두께의 비율이 조합된 현재 단계의 구름 크기
float fRealSizeW = (float)pSizeType->s + ( fSizeGap * fRate); // cloud size height
float fRealSizeW2 = fRealSizeW / 2.0f;
float fRealSizeH = (float)pSizeType->s + ( fSizeGap * fRate); // cloud size height
float fRealSizeH2 = fRealSizeH / 2.0f;
KColor cloudColor(pr.color[1], pr.color[2], pr.color[3], pr.color[0]);
int id = k * ONE_CLOUD_PLANE_VTX_COUNT; // 구름 한 평면당 버텍스 4
int nColorType = 0;
if ( k == 0 ) // 바닥은 어두운 텍스처
nColorType = C_DARK;
else if( k < nHalfCount ) // 중간까지는 중간 밝기 텍스처
nColorType = C_GRAY;
else if( k >= nHalfCount ) // 중간 이상은 가장 밝은 텍스처
{
nColorType = C_BRIGHT;
float rx = tan( fG * (float)(j) ) / 1.57079f;
cloudColor.a = BYTE( 255.0f * rx );
j++;
}
K3DVERTEX_CLOUD* pVtx = new K3DVERTEX_CLOUD[ ONE_CLOUD_PLANE_VTX_COUNT ];
pVtx[ 0 ].position = K3DVector( pr.fx - fRealSizeW2, pr.fy - fRealSizeH2, fHeight );
pVtx[ 0 ].color = cloudColor;
pVtx[ 0 ].normal = K3DVector( 0.0f, 0.0f, 1.0f );
pVtx[ 0 ].texcoord0.Set(0.0f, 0.0f);
pVtx[ 1 ].position = K3DVector( pr.fx + fRealSizeW2, pr.fy - fRealSizeH2, fHeight );
pVtx[ 1 ].color = cloudColor;
pVtx[ 1 ].normal = K3DVector( 0.0f, 0.0f, 1.0f );
pVtx[ 1 ].texcoord0.Set(1.0f, 0.0f);
pVtx[ 2 ].position = K3DVector( pr.fx - fRealSizeW2, pr.fy + fRealSizeH2, fHeight );
pVtx[ 2 ].color = cloudColor;
pVtx[ 2 ].normal = K3DVector( 0.0f, 0.0f, 1.0f );
pVtx[ 2 ].texcoord0.Set(0.0f, 1.0f);
pVtx[ 3 ].position = K3DVector( pr.fx + fRealSizeW2, pr.fy + fRealSizeH2, fHeight );
pVtx[ 3 ].color = cloudColor;
pVtx[ 3 ].normal = K3DVector( 0.0f, 0.0f, 1.0f );
pVtx[ 3 ].texcoord0.Set(1.0f, 1.0f);
m_VBPack[ nColorType ].add( &pVtx[ 0 ] );
m_VBPack[ nColorType ].add( &pVtx[ 1 ] );
m_VBPack[ nColorType ].add( &pVtx[ 2 ] );
m_VBPack[ nColorType ].add( &pVtx[ 3 ] );
fHeight -= fThicknessGap; // cloud height
}
GenerateCloudVertexBuffer();
return 1;
}
void CCloudUnit::GenerateCloudTexture(int nColorType)
{
if(nColorType < C_BRIGHT || nColorType >= C_MAX)
return ;
std::string* pStrTxrName = GetCloudTxrGroupDB().find_str( nColorType, m_nTypeTxrGroup[ nColorType ] );
if( pStrTxrName->size() <= 3 )
return ;
NX3LoadPack loadpack;
loadpack.Init();
K3DTexture* pTexture = KTextureManager::GetManager()->GetTexture( pStrTxrName->c_str(), &loadpack, true, KTextureManager::GetManager()->GetMipMapBiasLevel() );
if( pTexture == NULL )
return ;
m_pPrimitive->SetTexture( nColorType, pTexture ); // 텍스처 설정
}
void CCloudUnit::GenerateCloudVertexBuffer()
{
m_pPrimitive->ClearVertexBuffer();
for(int y=C_BRIGHT; y<C_MAX; y++)
{
int count = m_VBPack[ y ].get_size();
if( count <= 0 )
continue;
DWORD dwFormat = 0;
K3DVertexBuffer* pVB = m_pDevice->CreateVertexBufferUsePoolDefault(
sizeof(K3DVERTEX_CLOUD), dwFormat,
ONE_CLOUD_PLANE_VTX_COUNT * count,
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY ); // 버텍스 버퍼 만듦
if( pVB == NULL )
assert(pVB && "Failed CreateVertexBufferUsePoolDefault");
// 버텍스 버퍼에 락걸고 내용을 채운다
int nVtxSize, nPrimCnt = 0;
K3DVERTEX_CLOUD* pVtx = NULL;
#if defined( _DEBUG ) // D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨
pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD );
#else
pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_DISCARD );
#endif
assert(vtx && "pVB->Lock( (void**)&vtx, nVtxSize );");
if( pVtx == NULL )
return;
int nPlaneCount = count / ONE_CLOUD_PLANE_VTX_COUNT;
for(int x=0; x<count; x++)
{
pVtx[ x ] = *m_VBPack[ y ].find( x );
}
nPrimCnt += count; // 4 : 평면당 버텍스 4개씩
pVB->Unlock();
m_pPrimitive->SetVertexCnt( y, nPrimCnt );
if( pVB )
m_pPrimitive->SetVertexBuffer( y, pVB ); // 렌더링 프리미티브에 버퍼 연결
// 인덱스 버퍼
int nInBCount = nPlaneCount * ONE_CLOUD_PLANE_INDEX_COUNT;
K3DIndexBuffer* pIB = m_pDevice->CreateIndexBuffer( nInBCount );
if( pIB == NULL )
assert(pIB && "Failed CreateIndexBuffer");
WORD *idxb;
int idxSize;
pIB->Lock((void **)&idxb, idxSize);
assert(idxb && "pIB->Lock((void **)&idxb, idxSize);");
int kid = 0;
for(int k = 0; k < nPlaneCount; k++, kid += ONE_CLOUD_PLANE_INDEX_COUNT)
{
idxb[ kid + 0 ] = k * ONE_CLOUD_PLANE_VTX_COUNT + 0;
idxb[ kid + 1 ] = k * ONE_CLOUD_PLANE_VTX_COUNT + 1;
idxb[ kid + 2 ] = k * ONE_CLOUD_PLANE_VTX_COUNT + 2;
idxb[ kid + 3 ] = k * ONE_CLOUD_PLANE_VTX_COUNT + 3;
idxb[ kid + 4 ] = k * ONE_CLOUD_PLANE_VTX_COUNT + 2;
idxb[ kid + 5 ] = k * ONE_CLOUD_PLANE_VTX_COUNT + 1;
}
pIB->Unlock();
if( pIB )
m_pPrimitive->SetIndexBuffer( y, pIB ); // 렌더링 프리미티브에 버퍼 연결
}
}
void CCloudUnit::UpdatePos( float fx, float fy, float fz )
{
int k=0;
}
void CCloudUnit::Init( K3DRenderDevice *pDevice, K3DIndexBuffer * pIndexBuf )
{
m_pDevice = pDevice;
m_pMtl = new K3DMaterial;
m_pMtl->SetAmbient( K3DColor( 1.f, 0.f, 0.f, 0.f ) );
m_pMtl->SetDiffuse( K3DColor( 1.f, 0.f, 0.f, 0.f ) );
m_pMtl->SetSpecular( K3DColor( 0.f, 0.f, 0.f, 0.f ) );
m_pMtl->SetSpecularPower( 1.0f );
m_pParentMat = NULL; // SkyBox 위치
K3DMatrixIdentity( m_LocalMat ); // 구름 위치
K3DMatrixIdentity( m_WorldMat );
m_pPrimitive->SetTransparent( true );
m_pPrimitive->SetTransform( &m_LocalMat, &m_WorldMat );
m_pPrimitive->SetMaterial( m_pMtl );
}
int CCloudUnit::ProcessSecond( DWORD dwTime )
{
DWORD dwFrameTick = dwTime - m_dwTickOld;
if( dwFrameTick < 0 )
return 0;
// 속도 = 움직인 거리 / 단위시간
// 거리 = 시간 * 속도
// 시간 = 거리 / 속도
float fGap = (float)dwFrameTick * (float)m_fMoveSpeed;
if ( m_nDir == 0 )
{
m_fMoveFrame += ( m_vDir.x * fGap );
m_fMovePosX = m_vPos.x + m_fMoveFrame;
if( m_fMovePosX < -ZONE_CLOUD_WIDTH_D2 )
{
m_fMoveFrame = ZONE_CLOUD_WIDTH_D2;
m_fMovePosX = ZONE_CLOUD_WIDTH_D2;
}
}
else if( m_nDir == 1 )
{
m_fMoveFrame += ( m_vDir.x * fGap );
m_fMovePosX = m_vPos.x + m_fMoveFrame;
if( m_fMovePosX > ZONE_CLOUD_WIDTH_D2 )
{
m_fMoveFrame = -ZONE_CLOUD_WIDTH_D2;
m_fMovePosX = -ZONE_CLOUD_WIDTH_D2;
}
}
else if( m_nDir == 2 )
{
m_fMoveFrame += ( m_vDir.y * fGap );
m_fMovePosY = m_vPos.y + m_fMoveFrame;
if( m_fMovePosY > ZONE_CLOUD_HEIGHT_D2 )
{
m_fMoveFrame = -ZONE_CLOUD_HEIGHT_D2;
m_fMovePosY = -ZONE_CLOUD_HEIGHT_D2;
}
}
else if( m_nDir == 3 )
{
m_fMoveFrame += ( m_vDir.y * fGap );
m_fMovePosY = m_vPos.y + m_fMoveFrame;
if( m_fMovePosY < -ZONE_CLOUD_HEIGHT_D2 )
{
m_fMoveFrame = ZONE_CLOUD_HEIGHT_D2;
m_fMovePosY = ZONE_CLOUD_HEIGHT_D2;
}
}
SCalculateHeightParam sParam;
sParam.nLayerGapType = m_nLayerGap;
sParam.nPathType = m_nPath;
sParam.nDir = m_nDir;
sParam.x = m_fMovePosX + ZONE_CLOUD_WIDTH_D2;
sParam.y = m_fMovePosY + ZONE_CLOUD_HEIGHT_D2;
sParam.zoneX = ZONE_CLOUD_WIDTH;
sParam.zoneY = ZONE_CLOUD_HEIGHT;
m_fMovePosZ = GetCloudPathDB().calculateHeight( sParam );
m_fMovePosZ -= g_fMyPlayerHeight;
m_dwTickOld = dwTime;
return 0;
}
void CCloudUnit::SetFadeState( int nState )
{
m_sFadeState = nState;
if ( m_sFadeState == FADE_IN )
m_fAlpha = 0.0f;
else if( m_sFadeState == FADE_OUT )
m_fAlpha = 1.0f;
}
// 서서히 알파값 높아져 투명하게 변화시킴
int CCloudUnit::IncreaseAlpha( DWORD dwFrameTick )
{
m_fAlpha += (float)dwFrameTick / FADE_ALPHA_TIME;
float fCurAlpha = m_fAlpha;
float fCurAlpha2 = fCurAlpha;
if( fCurAlpha > 1.0f )
fCurAlpha = 1.0f;
UpdateAlpha( fCurAlpha );
return 1;
}
// 서서히 알파값 낮아져 불투명하게 변화시킴
int CCloudUnit::DecreaseAlpha( DWORD dwFrameTick )
{
m_fAlpha -= (float)dwFrameTick / FADE_ALPHA_TIME;
float fCurAlpha = m_fAlpha;
float fCurAlpha2 = fCurAlpha;
if( fCurAlpha < 0.0f )
fCurAlpha = 0.0f;
UpdateAlpha( fCurAlpha );
return 1;
}
void CCloudUnit::UpdateAlpha( float fAlpha )
{
for(int y=C_BRIGHT; y<C_MAX; y++)
{
int count = m_VBPack[ y ].get_size();
if( count <= 0 )
continue;
K3DVertexBuffer* pVB = m_pPrimitive->GetVertexBuffer( y );
if( pVB == NULL )
continue ;
// 버텍스 버퍼에 락걸고 내용을 채운다
int nVtxSize, nPrimCnt = 0;
K3DVERTEX_CLOUD* pVtx = NULL;
#if defined( _DEBUG ) // D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨
pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD );
#else
pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_DISCARD );
#endif
assert(vtx && "pVB->Lock( (void**)&vtx, nVtxSize );");
if( pVtx == NULL )
return;
for(int x=0; x<count; x++)
{
pVtx[ x ] = *m_VBPack[ y ].find( x );
pVtx[ x ].color.a = fAlpha;
}
pVB->Unlock();
}
}
void CCloudUnit::UpdateAlphaBrightLayer()
{
int y=C_BRIGHT;
{
int count = m_VBPack[ y ].get_size();
if( count <= 0 )
return ;
K3DVertexBuffer* pVB = m_pPrimitive->GetVertexBuffer( y );
if( pVB == NULL )
return ;
// 버텍스 버퍼에 락걸고 내용을 채운다
int nVtxSize, nPrimCnt = 0;
K3DVERTEX_CLOUD* pVtx = NULL;
#if defined( _DEBUG ) // D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨
pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD );
#else
pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_DISCARD );
#endif
assert(vtx && "pVB->Lock( (void**)&vtx, nVtxSize );");
if( pVtx == NULL )
return;
int nPlaneCount = count / ONE_CLOUD_PLANE_VTX_COUNT;
float fG = 1.0f / (float)nPlaneCount;
for(int x=0; x<count; x++)
{
pVtx[ x ] = *m_VBPack[ y ].find( x );
int j = x / 4;
float rx = tan( fG * (float)(j) ) / 1.57079f;
pVtx[ x ].color.a = BYTE( 255.0f * rx );
}
pVB->Unlock();
}
}
void CCloudUnit::Render( KViewportObject *viewport )
{
if( m_pPrimitive )
{
viewport->Register( m_pPrimitive, KRenderObject::RENDEREFX_CLOUD );
}
}
void CCloudUnit::SetHeight( int i, float fz )
{
}
void CCloudUnit::SetPosition( float fx, float fy, float fz )
{
m_vPos.x = fx;
m_vPos.y = fy;
m_vPos.z = fz;
}
K3DVector& CCloudUnit::GetPosition()
{
return m_vPos;
}
void CCloudUnit::UpdatePosition(float fx, float fy, float fz)
{
SGameWorld* pGameWorld = dynamicCast<SGameWorld*>(g_pCurrentGameSystem->GetGame());
float gfx = 0.0f;
float gfy = 0.0f;
float gfz = 0.0f;
SGameAvatarEx* pMyCharacter = g_pCurrentGameSystem->GetLocalPlayer();
if( pMyCharacter )
{
float out;
WORD wTile;
K3DVector vPos = pMyCharacter->GetCurPos();
pGameWorld->GetHeight( vPos.x, vPos.y, out, wTile );
gfz = pMyCharacter->GetCurPos().z;
gfz = out;
}
K3DMatrix* pMat = m_pPrimitive->GetTransform();
pMat->_41 = m_fMovePosX + g_fX + gfx;
pMat->_42 = m_fMovePosY + g_fY + gfy;
pMat->_43 = m_fMovePosZ + fz + g_fZ + gfz;
}
void CCloudUnit::SetTransform( K3DMatrix* pParentMatrix )
{
SetParentMat( pParentMatrix );
m_pPrimitive->SetTransform( pParentMatrix, pParentMatrix );
}
void CCloudUnit::initVB()
{
}
void CCloudUnit::initCloudObjects()
{
}
void CCloudUnit::ChangeCloudColor(int nR, int nG, int nB)
{
int count = m_VBPack[ C_BRIGHT ].get_size();
if( count <= 0 )
return ;
K3DVertexBuffer* pVB = m_pPrimitive->GetVertexBuffer( C_BRIGHT );
if( pVB == NULL )
return ;
// 버텍스 버퍼에 락걸고 내용을 채운다
int nVtxSize, nPrimCnt = 0;
K3DVERTEX_CLOUD* pVtx = NULL;
#if defined( _DEBUG ) // D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨
pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD );
#else
pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_DISCARD );
#endif
assert(vtx && "pVB->Lock( (void**)&vtx, nVtxSize );");
if( pVtx == NULL )
return;
int _r = nR; // - pVtx->color.r;
int _g = nG; // - pVtx->color.g;
int _b = nB; // - pVtx->color.b;
int j=0;
int nPlaneCount = count / ONE_CLOUD_PLANE_VTX_COUNT;
float fG = 1.0f / (float)nPlaneCount;
for(int k=nPlaneCount; k>0; k--, j++)
{
float rx = tan( fG * (float)j ) / 1.57079f;
int id = (k - 1) * ONE_CLOUD_PLANE_VTX_COUNT;
for(int z=0; z<ONE_CLOUD_PLANE_VTX_COUNT; z++)
{
K3DVERTEX_CLOUD* pV = m_VBPack[ C_BRIGHT ].find( id + z );
pV->color.r = _r;
pV->color.g = _g;
pV->color.b = _b;
}
}
pVB->Unlock();
}
//---------------------------------------------------------------------------------------
// cloud uni manager
CCloudLayer::CCloudLayer()
{
}
CCloudLayer::~CCloudLayer()
{
clear();
}
void CCloudLayer::add(int id, CCloudUnit* pCloud)
{
m_vcCloud.push_back( pCloud );
}
void CCloudLayer::clear()
{
int nCount = m_vcCloud.size();
for(int x=0; x<nCount; x++)
{
CCloudUnit* pCloud = m_vcCloud[x];
SAFE_DELETE( pCloud );
}
m_vcCloud.clear();
}
void CCloudLayer::size(int sz)
{
m_vcCloud.resize(sz);
}
CCloudUnit* CCloudLayer::find(int id)
{
return m_vcCloud[ id ];
}
int CCloudLayer::makeClouds(SCloudParam& sParam)
{
if( sParam.pCloudShowInfo == NULL )
return -1;
int nCurTick = GetSafeTickCount();
m_sParam.nTypeDistribution = sParam.nTypeDistribution;
m_sParam.nLayerGapType = sParam.nLayerGapType;
m_sParam.nTypeMoveDir = sParam.nTypeMoveDir;
m_sParam.nTypePathType = sParam.nTypePathType;
m_sParam.nTypeCloudHeightRandomGap = sParam.nTypeCloudHeightRandomGap;
float fLayerHeight = (float)GetCloudLayerGapDB().find( m_sParam.nLayerGapType );
// 분포도 값
int tDistribution = GetCloudDistributionDB().find( m_sParam.nTypeDistribution );
int tHeightRadomGap = GetCloudHeightRadomGapDB().find( m_sParam.nTypeCloudHeightRandomGap );
int sz = (int)sParam.pCloudShowInfo->vcShowInfo.size();
std::vector< int > vecCount;
std::vector< POINT > vecXY;
int nTotalCount = 0;
for(int x=0; x<sz; x++)
{
SCloudShowInfo* pShowInfo = sParam.pCloudShowInfo->find( x );
if( pShowInfo == NULL )
return -4;
// 구름의 개수
int nCloudCount = (tDistribution * pShowInfo->type_show_rate) / 100;
for(int z=0; z<nCloudCount; z++)
{
POINT pt;
pt.x = rand() % (int)ZONE_CLOUD_WIDTH;
pt.y = rand() % (int)ZONE_CLOUD_HEIGHT;
vecXY.push_back( pt );
}
vecCount.push_back(nCloudCount);
nTotalCount += nCloudCount;
}
int id = 0;
for(int x=0; x<sz; x++)
{
SCloudShowInfo* pShowInfo = sParam.pCloudShowInfo->find( x );
if( pShowInfo == NULL )
return -4;
for(int z=0; z<vecCount[ x ]; z++)
{
CCloudUnit* pCloud = new CCloudUnit;
pCloud->Init( m_pDevice );
pCloud->SetParent( this );
// cloud position
float fx = (float)vecXY[ id ].x;
float fy = (float)vecXY[ id ].y;
SCalculateHeightParam sHeightParam;
sHeightParam.nLayerGapType = m_sParam.nLayerGapType;
sHeightParam.nPathType = m_sParam.nTypePathType;
sHeightParam.nDir = m_sParam.nTypeMoveDir;
sHeightParam.x = fx;
sHeightParam.y = fy;
sHeightParam.zoneX = ZONE_CLOUD_WIDTH;
sHeightParam.zoneY = ZONE_CLOUD_HEIGHT;
float fHeight = GetCloudPathDB().calculateHeight( sHeightParam );
fx -= ZONE_CLOUD_WIDTH_D2;
fy -= ZONE_CLOUD_HEIGHT_D2;
pCloud->SetPosition(fx, fy, fHeight);
pCloud->SetID( id );
SCloudCreateParam pr;
pr.nType = pShowInfo->type_cloud;
pr.nLayerGapType = m_sParam.nLayerGapType;
pr.nPath = m_sParam.nTypePathType;
pr.fStandardHeight = 0.0f;
pr.nDir = m_sParam.nTypeMoveDir;
pr.fx = 0.0f;
pr.fy = 0.0f;
pr.color[0] = sParam.pCloudShowInfo->color[0];
pr.color[1] = sParam.pCloudShowInfo->color[1];
pr.color[2] = sParam.pCloudShowInfo->color[2];
pr.color[3] = sParam.pCloudShowInfo->color[3];
if( 0 == pCloud->make( pr ) )
return -4;
add( id, pCloud );
id += 1;
}
}
return 1;
}
int CCloudLayer::Process( DWORD dwTime )
{
int sz = (int)m_vcCloud.size();
for(int x=0; x<sz; x++)
{
int nState = m_vcCloud[x]->ProcessSecond( dwTime );
if( nState == FADE_IN_COMPLETE || nState == FADE_OUT_COMPLETE )
return nState;
}
return 1;
}
void CCloudLayer::Render( KViewportObject *viewport )
{
int sz = (int)m_vcCloud.size();
for(int x=0; x<sz; x++)
{
m_vcCloud[x]->Render( viewport );
}
}
void CCloudLayer::SetPosition( float fx, float fy, float fz, int idCloud )
{
int sz = (int)m_vcCloud.size();
if( idCloud == -1 )
{
for(int x=0; x<sz; x++)
{
m_vcCloud[ x ]->SetPosition( fx, fy, fz );
}
return ;
}
if( idCloud < 0 || idCloud >= sz )
return ;
m_vcCloud[ idCloud ]->SetPosition( fx, fy, fz );
}
void CCloudLayer::UpdatePosition(float fx, float fy, float fz)
{
int sz = (int)m_vcCloud.size();
for(int x=0; x<sz; x++)
{
m_vcCloud[ x ]->UpdatePosition(fx, fy, fz);
}
}
void CCloudLayer::FadeInOutCloud(int nFadeState)
{
int sz = (int)m_vcCloud.size();
for(int x=0; x<sz; x++)
{
m_vcCloud[ x ]->SetFadeState( nFadeState );
}
}
void CCloudLayer::CompleteFadeIn()
{
m_pParent->CompleteFadeIn();
}
void CCloudLayer::CompleteFadeOut()
{
m_pParent->CompleteFadeOut();
}
void CCloudLayer::SetAlpha( float fAlpha )
{
int sz = (int)m_vcCloud.size();
for(int x=0; x<sz; x++)
{
m_vcCloud[ x ]->SetAlpha( fAlpha );
}
}
void CCloudLayer::UpdateAlpha( float fAlpha )
{
int sz = (int)m_vcCloud.size();
for(int x=0; x<sz; x++)
{
m_vcCloud[ x ]->UpdateAlpha( fAlpha );
}
}
void CCloudLayer::UpdateAlphaBrightLayer()
{
int sz = (int)m_vcCloud.size();
for(int x=0; x<sz; x++)
{
m_vcCloud[ x ]->UpdateAlphaBrightLayer();
}
}
int CCloudLayer::DecreaseAlpha( DWORD dwFrameTick )
{
int sz = (int)m_vcCloud.size();
for(int x=0; x<sz; x++)
{
m_vcCloud[ x ]->DecreaseAlpha( dwFrameTick );
}
return 1;
}
int CCloudLayer::IncreaseAlpha( DWORD dwFrameTick )
{
int sz = (int)m_vcCloud.size();
for(int x=0; x<sz; x++)
{
m_vcCloud[ x ]->IncreaseAlpha( dwFrameTick );
}
return 1;
}
void CCloudLayer::ChangeCloudColor(int nR, int nG, int nB)
{
int sz = (int)m_vcCloud.size();
for(int x=0; x<sz; x++)
{
m_vcCloud[ x ]->ChangeCloudColor(nR, nG, nB);
}
}
//---------------------------------------------------------------------------------------
// cloud uni manager
CCloudLayerSet::CCloudLayerSet()
{
m_nRenderCloudID = -1;
}
CCloudLayerSet::~CCloudLayerSet()
{
clear();
}
bool CCloudLayerSet::SetRenderCloudID( int id )
{
m_nRenderCloudID = id;
return true;
}
int CCloudLayerSet::get_size()
{
return (int)m_vcLayer.size();
}
void CCloudLayerSet::SetDevice(K3DRenderDevice* pDvc)
{
m_pDevice = pDvc;
}
void CCloudLayerSet::add(int id, CCloudLayer* pLayer)
{
m_vcLayer.push_back( pLayer );
}
void CCloudLayerSet::clear()
{
int nCount = m_vcLayer.size();
for(int x=0; x<nCount; x++)
{
CCloudLayer* pLayer = m_vcLayer[x];
SAFE_DELETE( pLayer );
}
m_vcLayer.clear();
}
void CCloudLayerSet::size(int sz)
{
int k=0;
m_vcLayer.resize(sz);
}
CCloudLayer* CCloudLayerSet::find(int id)
{
int k=0;
return m_vcLayer[ id ];
}
int CCloudLayerSet::makeLayer(int nLayerID, int nType, int nDir, int nPathType, int nLayerGapType)
{
if( nLayerID < 0 )
return -1;
if( nType < 0 || nDir < 0 || nPathType < 0 || nLayerGapType < 0 )
return -2;
// 구름 경로 디비 (높이)
SCloudPath* pPath = GetCloudPathDB().find( nPathType );
if( pPath == NULL )
return -3;
SCloudLayer* pCloudLayerDB = GetCloudLayerDB()->find( nType );
if( pCloudLayerDB == NULL )
return -3;
int sz = pCloudLayerDB->vcShowInfo.size();
for(int x=0; x<sz; x++)
{
CCloudLayer* pLayer = new CCloudLayer;
pLayer->SetDevice( m_pDevice );
pLayer->SetParent( this );
SCloudParam sParam;
sParam.nTypeDistribution = pCloudLayerDB->type_distribution;
sParam.nTypeCloudHeightRandomGap = pCloudLayerDB->type_height_random_gap;
sParam.nTypePathType = nPathType;
sParam.nTypeMoveDir = nDir;
sParam.nLayerGapType = nLayerGapType;
sParam.pCloudShowInfo = pCloudLayerDB;
if( 0 == pLayer->makeClouds( sParam ) )
return -4;
add( x, pLayer );
}
return 1;
}
int CCloudLayerSet::Process( DWORD dwTime )
{
if( m_nRenderCloudID < 0 || m_nRenderCloudID >= m_vcLayer.size() )
return 0;
SGameWorld* pGameWorld = dynamicCast<SGameWorld*>(g_pCurrentGameSystem->GetGame());
SGameAvatarEx* pMyCharacter = g_pCurrentGameSystem->GetLocalPlayer();
if( pMyCharacter )
{
WORD wTile;
K3DVector vPos = pMyCharacter->GetCurPos();
pGameWorld->GetHeight( vPos.x, vPos.y, g_fMyPlayerHeight, wTile );
}
int sz = (int)m_vcLayer.size();
for(int x=0; x<sz; x++)
{
int nState = m_vcLayer[x]->Process( dwTime );
if( nState == FADE_IN_COMPLETE || nState == FADE_OUT_COMPLETE )
return nState;
}
return 1;
}
void CCloudLayerSet::Render( KViewportObject *viewport )
{
if( m_nRenderCloudID < 0 || m_nRenderCloudID >= m_vcLayer.size() )
return ;
int sz = (int)m_vcLayer.size();
for(int x=0; x<sz; x++)
{
m_vcLayer[x]->Render( viewport );
}
}
void CCloudLayerSet::SetPosition( float fx, float fy, float fz )
{
if( m_nRenderCloudID < 0 || m_nRenderCloudID >= m_vcLayer.size() )
return ;
m_vcLayer[ m_nRenderCloudID ]->SetPosition( fx, fy, fz );
}
void CCloudLayerSet::UpdatePosition(float fx, float fy, float fz)
{
int nCount = m_vcLayer.size();
for(int x=0; x<nCount; x++)
{
CCloudLayer* pLayer = m_vcLayer[x];
pLayer->UpdatePosition(fx, fy, fz);
}
}
void CCloudLayerSet::FadeInOutCloud(int nFadeState)
{
int nCount = m_vcLayer.size();
for(int x=0; x<nCount; x++)
{
CCloudLayer* pLayer = m_vcLayer[x];
pLayer->FadeInOutCloud( nFadeState );
}
}
void CCloudLayerSet::CompleteFadeIn()
{
m_pParent->CompleteFadeIn();
}
void CCloudLayerSet::CompleteFadeOut()
{
m_pParent->CompleteFadeOut();
}
void CCloudLayerSet::SetAlpha( float fAlpha )
{
int sz = (int)m_vcLayer.size();
for(int x=0; x<sz; x++)
{
m_vcLayer[ x ]->SetAlpha( fAlpha );
}
}
void CCloudLayerSet::UpdateAlpha( float fAlpha )
{
int sz = (int)m_vcLayer.size();
for(int x=0; x<sz; x++)
{
m_vcLayer[ x ]->UpdateAlpha( fAlpha );
}
}
void CCloudLayerSet::UpdateAlphaBrightLayer()
{
int sz = (int)m_vcLayer.size();
for(int x=0; x<sz; x++)
{
m_vcLayer[ x ]->UpdateAlphaBrightLayer();
}
}
int CCloudLayerSet::DecreaseAlpha( DWORD dwFrameTick )
{
int sz = (int)m_vcLayer.size();
for(int x=0; x<sz; x++)
{
m_vcLayer[ x ]->DecreaseAlpha( dwFrameTick );
}
return 1;
}
int CCloudLayerSet::IncreaseAlpha( DWORD dwFrameTick )
{
int sz = (int)m_vcLayer.size();
for(int x=0; x<sz; x++)
{
m_vcLayer[ x ]->IncreaseAlpha( dwFrameTick );
}
return 1;
}
void CCloudLayerSet::ChangeCloudColor(int nR, int nG, int nB)
{
int sz = (int)m_vcLayer.size();
for(int x=0; x<sz; x++)
{
m_vcLayer[ x ]->ChangeCloudColor(nR, nG, nB);
}
}
//---------------------------------------------------------------------------------------
void CreateCloudDB()
{
g_pCloudKindDB = new CCloudKindDB;
g_pCloudThicknesDB = new CCloudThicknessDB;
g_pCloudThicknessGapDB = new CCloudThicknessGapDB;
g_pCloudSizeDB = new CCloudSizeDB;
g_pCloudTxrGroupDB = new CCloudTxrGroupDB;
g_pCloudDistributionDB = new CCloudDistributionDB;
g_pCloudHeightRadomGapDB = new CCloudHeightRadomGapDB;
g_pCloudCloudLayerGapDB = new CCloudLayerGapDB;
g_pCloudCloudMoveDirDB = new CCloudMoveDirDB;
g_pCloudPathDB = new CCloudPathDB;
g_pCloudTypeInfoDB = new CCloudTypeInfoDB;
g_pCloudLayerDB = new CCloudLayerDB;
g_pCloudLayerSetDB = new CCloudLayerSetDB;
}
void DestroyCloudDB()
{
SAFE_DELETE(g_pCloudKindDB);
SAFE_DELETE(g_pCloudThicknesDB);
SAFE_DELETE(g_pCloudThicknessGapDB);
SAFE_DELETE(g_pCloudSizeDB);
SAFE_DELETE(g_pCloudTxrGroupDB);
SAFE_DELETE(g_pCloudDistributionDB);
SAFE_DELETE(g_pCloudHeightRadomGapDB);
SAFE_DELETE(g_pCloudCloudLayerGapDB);
SAFE_DELETE(g_pCloudCloudMoveDirDB);
SAFE_DELETE(g_pCloudPathDB);
SAFE_DELETE(g_pCloudTypeInfoDB);
SAFE_DELETE(g_pCloudLayerDB);
SAFE_DELETE(g_pCloudLayerSetDB);
}
//---------------------------------------------------------------------------------------
// cloud uni manager
CCloudMaker::CCloudMaker()
{
m_dwTickOld = 0;
m_bShow = false;
m_pCloud = new CCloudLayerSet;
m_pCloud->SetParent( this );
}
CCloudMaker::~CCloudMaker()
{
clearCloud();
SAFE_DELETE( m_pCloud );
}
void CCloudMaker::SetWillCloudID( int _id )
{
m_nWillCloudID = _id;
}
int CCloudMaker::GetRenderCloudID() const
{
if( m_pCloud )
return m_pCloud->GetRenderCloudID();
return -1;
}
void CCloudMaker::ClearRenderCloudID()
{
if( m_pCloud )
m_pCloud->SetRenderCloudID( -1 );
}
void CCloudMaker::SetDevice(K3DRenderDevice* pDvc)
{
m_pCloud->SetDevice(pDvc);
}
int CCloudMaker::makeCloud(int id)
{
if( id < 0 )
return 0;
if( m_pCloud->GetRenderCloudID() == id )
return 1;
if( id > GetCloudLayerSetDB()->get_size() )
return -1;
// current cloud id ( rendering )
if( false == m_pCloud->SetRenderCloudID( id ) )
return -2;
clearCloud();
SCloudLayerSet* pLayerSet = GetCloudLayerSetDB()->find( id ); // 아이디로 구름세트 구조체 얻는다
if( pLayerSet == NULL )
return -3;
int sz = (int)pLayerSet->vcLayerInfo.size();
for(int x=0; x<sz; x++)
{
SCloudLayerInfo* pLayerInfo = pLayerSet->find(x);
if( pLayerInfo == NULL )
return -4;
if( 0 == m_pCloud->makeLayer( x, pLayerInfo->type_layer, pLayerInfo->type_move_dir, pLayerInfo->type_path, pLayerInfo->type_layer_gap ) )
return -5;
}
m_bShow = true;
return 1;
}
void CCloudMaker::clearCloud()
{
m_pCloud->clear();
m_bShow = false;
}
void CCloudMaker::Process( DWORD dwTime )
{
DWORD dwFrameTick = dwTime - m_dwTickOld;
if(m_bShow)
{
m_pCloud->Process( dwTime );
if( g_nFadeState != FADE_NONE )
{
// int nState = m_pCloud->Process( dwTime );
// if( nState == FADE_IN_COMPLETE )
if( g_nFadeState == FADE_IN_COMPLETE )
{
CompleteFadeIn();
m_pCloud->Process( dwTime );
// FadeInOutCloud( FADE_OUT ); // 구름 서서히 불투명하게 나타남
}
// else if( nState == FADE_OUT_COMPLETE )
else if( g_nFadeState == FADE_OUT_COMPLETE )
{
CompleteFadeOut();
m_pCloud->UpdateAlphaBrightLayer();
m_pCloud->Process( dwTime );
// FadeInOutCloud( FADE_NONE );
}
else if( g_nFadeState == FADE_IN )
{
m_fAlpha -= (float)dwFrameTick / FADE_ALPHA_TIME;
if( m_fAlpha < 0.0f )
{
m_fAlpha = 0.0f;
g_nFadeState = FADE_IN_COMPLETE;
}
m_pCloud->UpdateAlpha( m_fAlpha * 255.0f );
}
else if( g_nFadeState == FADE_OUT )
{
m_fAlpha += (float)dwFrameTick / FADE_ALPHA_TIME;
if( m_fAlpha > 1.0f )
{
m_fAlpha = 1.0f;
g_nFadeState = FADE_OUT_COMPLETE;
}
m_pCloud->UpdateAlpha( m_fAlpha * 255.0f );
}
}
}
m_dwTickOld = dwTime;
}
void CCloudMaker::Render( KViewportObject *viewport )
{
if(m_bShow)
m_pCloud->Render( viewport );
}
void CCloudMaker::SetPosition( float fx, float fy, float fz )
{
m_pCloud->SetPosition( fx, fy, fz );
}
void CCloudMaker::UpdatePosition(float fx, float fy, float fz)
{
m_pCloud->UpdatePosition(fx, fy, fz);
}
void CCloudMaker::FadeInOutCloud(int nFadeState)
{
if( true == CompareCloudID() )
return ;
g_nFadeState = nFadeState;
if ( g_nFadeState == FADE_IN )
m_fAlpha = 1.0f;
else if( g_nFadeState == FADE_OUT )
m_fAlpha = 0.0f;
m_bShow = true;
}
void CCloudMaker::CompleteFadeIn()
{
if( m_nWillCloudID > -1 && m_nWillCloudID != GetRenderCloudID() )
{
m_bShow = false;
ClearRenderCloudID();
clearCloud();
makeCloud( m_nWillCloudID ); // 다른 종류의 구름 세트로 바꿈
m_pCloud->SetRenderCloudID( m_nWillCloudID );
g_nFadeState = FADE_OUT;
}
}
void CCloudMaker::CompleteFadeOut()
{
m_bShow = true;
g_nFadeState = FADE_NONE;
}
bool CCloudMaker::CompareCloudID()
{
if(m_nWillCloudID == GetRenderCloudID())
return true;
return false;
}
void CCloudMaker::ChangeCloudColor(int nR, int nG, int nB)
{
m_pCloud->ChangeCloudColor(nR, nG, nB);
}
#endif