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

281 lines
8.2 KiB
C++

#pragma once
#include "KViewport.h"
#include "KPrimitive.h"
#include <mmo/ArType.h>
class SGameSkillFx : public K3DPrimitive
{
protected:
class SGameObject* m_pGameObject;
void* m_pPrimitive;
int m_nVertexSize;
K3DTextureSPtr m_spTexture;
bool m_bEnd;
K3DMatrix m_matRoot;
K3DMatrix m_matBillborad;
public:
void SetVertex( void* pVertex );
void SetVertexSize( int nVertexSize );
void SetTexture( K3DTexture *pTexture );
void SetBillboardMatrix( K3DMatrix matBillboard );
public:
bool IsEnd() { return m_bEnd; }
public:
void Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum = true ) = 0;
public:
SGameSkillFx();
virtual ~SGameSkillFx();
};
class SGameLightningPrimitive : public SGameSkillFx
{
public:
void Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum = true )
{
UpdatePrimitive( viewport );
dev->SetTransformIdentity( K3DRenderDevice::TS_WORLD );
dev->SetTexture( 0, m_spTexture );
dev->SetCullMode( K3DRenderDevice::KCM_NONE );
dev->DrawTriangleStrip( K3DFVF_UNLITVERTEX, m_pPrimitive, m_nVertexSize*2, sizeof( K3DUNLITVERTEX ) );
dev->SetCullMode( K3DRenderDevice::KCM_CCW );
}
void UpdatePrimitive( KViewportObject *viewport )
{
K3DVector vCamera = viewport->GetBackUpViewCamera()->GetCamPos();
K3DUNLITVERTEX* pVertex = (K3DUNLITVERTEX*)m_pPrimitive;
for( int i = 0; i < m_nVertexSize; ++i )
{
int nV1 = i*2;
int nV2 = i*2+1;
K3DVector vPosition = pVertex[nV1].pos - vCamera;
m_matBillborad._41 = vPosition.x;
m_matBillborad._42 = vPosition.y;
m_matBillborad._43 = vPosition.z;
float fRandZ = (float)( rand() % 13 - 6 );
float fPos = (float)( rand() % 9 - 4 );
float fSize = 1.0f;
pVertex[nV1].pos = K3DVector( fPos + fSize, 0.0f, fRandZ );
fRandZ = (float)( rand() % 13 - 6 );
pVertex[nV2].pos = K3DVector( fPos - fSize, 0.0f, fRandZ );
// pVertex[nV1].pos += vPosition;
// pVertex[nV2].pos += vPosition;
K3DVectorTransform( pVertex[nV1].pos, pVertex[nV1].pos, m_matBillborad );
K3DVectorTransform( pVertex[nV2].pos, pVertex[nV2].pos, m_matBillborad );
pVertex[nV1].texel.u = 0.0f;
pVertex[nV2].texel.u = 1.0f;
pVertex[nV1].texel.v = pVertex[nV2].texel.v = (float)i/(float)(m_nVertexSize-1);
pVertex[nV1].diffuse = pVertex[nV2].diffuse = KColor( 255, 255, 255, (unsigned char)(255.0f * (float)i/(float)(m_nVertexSize-1)) );//(255 * ( i / m_nVertexSize - 1) ) );
pVertex[nV1].normal = K3DVector( 0.0f, 0.0f, 1.0f );
pVertex[nV2].normal = K3DVector( 0.0f, 0.0f, 1.0f );
}
}
};
class SGameHealingWavePrimitive : public SGameSkillFx
{
private:
float m_fWave;
float m_fStartWave;
public:
void Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum = true )
{
K3DMatrix matWorld;
K3DMatrixIdentity( matWorld );
dev->SetTransform( K3DRenderDevice::TS_WORLD, &matWorld );
UpdatePrimitive( viewport );
dev->SetTexture( 0, m_spTexture );
dev->SetCullMode( K3DRenderDevice::KCM_NONE );
dev->DrawTriangleStrip( K3DFVF_UNLITVERTEX, m_pPrimitive, m_nVertexSize*2, sizeof( K3DUNLITVERTEX ) );
dev->SetCullMode( K3DRenderDevice::KCM_CCW );
}
void UpdatePrimitive( KViewportObject *viewport )
{
K3DVector vCamera = viewport->GetBackUpViewCamera()->GetCamPos();
K3DUNLITVERTEX* pVertex = (K3DUNLITVERTEX*)m_pPrimitive;
m_fStartWave += 0.5f;
m_fWave = m_fStartWave;
K3DMatrix matView;
K3DMatrixIdentity( m_matBillborad );
matView = *viewport->GetViewMatrix();
//X축
/* m_matBillborad._22 = matView._22;
m_matBillborad._23 = matView._23;
m_matBillborad._32 = matView._32;
m_matBillborad._33 = matView._33;*/
//Y축
/* m_matBillborad._11 = matView._11;
m_matBillborad._13 = matView._13;
m_matBillborad._31 = matView._31;
m_matBillborad._33 = matView._33;*/
//Z축
/* m_matBillborad._11 = matView._11;
m_matBillborad._12 = matView._12;
m_matBillborad._21 = matView._21;
m_matBillborad._22 = matView._22;*/
// K3DMatrixInverse( m_matBillborad, m_matBillborad );
K3DVector vCamPos = viewport->GetCameraPos();
K3DVector vCamTar = viewport->GetCameraTargetPos();
K3DVector vDir = vCamTar - vCamPos;
// K3DVectorNormalize( vDir, vDir );
if( vDir.x > 0.0f )
{
K3DMatrixRotationY( m_matBillborad, -atanf( vDir.z/vDir.x ) + K3D_PI/2.0f );
}
else
{
K3DMatrixRotationY( m_matBillborad, -atanf( vDir.z/vDir.x ) - K3D_PI/2.0f );
}
int nV1 = 0, nV2 = 0;
for( int i = 0; i < m_nVertexSize; ++i )
{
nV1 = i*2;
nV2 = i*2+1;
K3DVector vPosition = pVertex[nV1].pos - vCamera;
m_matBillborad._41 = vPosition.x;
m_matBillborad._42 = vPosition.y;
m_matBillborad._43 = vPosition.z;
m_fWave += 0.1f;
float cos = 0.0f;//cosf( m_fWave ) * 2.0f;
static float fSize = 16.0f;
pVertex[nV1].pos = K3DVector( cos-fSize, 0.0f, 0.0f );
pVertex[nV2].pos = K3DVector( cos+fSize, 0.0f, 0.0f );
K3DVectorTransform( pVertex[nV1].pos, pVertex[nV1].pos, m_matBillborad );
K3DVectorTransform( pVertex[nV2].pos, pVertex[nV2].pos, m_matBillborad );
pVertex[nV1].texel.u = 0.0f;
pVertex[nV2].texel.u = 1.0f;
pVertex[nV1].texel.v = pVertex[nV2].texel.v = (float)i/(float)(m_nVertexSize-1);
pVertex[nV1].diffuse = pVertex[nV2].diffuse = KColor( 255, 255, 255, 255/* * (float)i/(float)(m_nVertexSize-1)*/ ); //unsigned char( 255.0f * m_fVisibility * (float)i/(float)(m_nDrawCount-1) ) );
pVertex[nV1].normal = K3DVector( 0.0f, 0.0f, 1.0f );
pVertex[nV2].normal = K3DVector( 0.0f, 0.0f, 1.0f );
}
}
public:
SGameHealingWavePrimitive() : m_fWave( 0.0f )
, m_fStartWave( 0.0f )
{}
};
/// 라이트닝
class SGameLightningFx : public SGameLightningPrimitive
{
private:
SGameSkillFx* m_pLightningPrimitive;
K3DUNLITVERTEX* m_pVertex;
float m_fMeter;
int m_nFrameCnt;
int m_nLength;
float m_fSpeed;
struct LinkInfo
{
AR_HANDLE hStart;
AR_HANDLE hEnd;
bool bStartHealingWave;
bool bEndHealingWave;
K3DVector vHeadPosition;
DWORD dwOldTime;
int nVertexSize;
LinkInfo( AR_HANDLE start, AR_HANDLE end, bool bStart = false ) : hStart( start )
, hEnd( end )
, bStartHealingWave( bStart )
, bEndHealingWave( false )
, vHeadPosition( 0.0f, 0.0f, 0.0f )
, dwOldTime( 0 )
, nVertexSize( 0 )
{}
};
std::vector< LinkInfo > m_vLinkInfo;
public:
void Init( class SGameObject* pCaster, AR_HANDLE hCaster, std::vector< struct SkillResult > & vTargetList );
void Process( DWORD dwTime );
void Render( KViewportObject *viewport );
public:
void StartLightning( SGameObject* pStart, SGameObject* pEnd, DWORD dwTime, LinkInfo & link );
bool EndLightning( SGameObject* pStart, SGameObject* pEnd, DWORD dwTime, LinkInfo & link );
public:
SGameLightningFx();
virtual ~SGameLightningFx();
};
/// 힐링 웨이브
class SGameHealingWaveFx : public SGameHealingWavePrimitive
{
private:
SGameSkillFx* m_pHealingWavePrimitive;
K3DUNLITVERTEX* m_pVertex;
float m_fMeter;
int m_nFrameCnt;
int m_nLength;
float m_fSpeed;
struct LinkInfo
{
AR_HANDLE hStart;
AR_HANDLE hEnd;
bool bStartHealingWave;
bool bEndHealingWave;
K3DVector vHeadPosition;
DWORD dwOldTime;
int nVertexSize;
LinkInfo( AR_HANDLE start, AR_HANDLE end, bool bStart = false ) : hStart( start )
, hEnd( end )
, bStartHealingWave( bStart )
, bEndHealingWave( false )
, vHeadPosition( 0.0f, 0.0f, 0.0f )
, dwOldTime( 0 )
, nVertexSize( 0 )
{}
};
std::vector< LinkInfo > m_vLinkInfo;
public:
void Init( class SGameObject* pCaster, AR_HANDLE hCaster, std::vector< struct SkillResult > & vTargetList );
void Process( DWORD dwTime );
void Render( KViewportObject *viewport );
public:
void StartHealingWave( SGameObject* pStart, SGameObject* pEnd, DWORD dwTime, LinkInfo & link );
bool EndHealingWave( SGameObject* pStart, SGameObject* pEnd, DWORD dwTime, LinkInfo & link );
public:
SGameHealingWaveFx();
virtual ~SGameHealingWaveFx();
};