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

677 lines
15 KiB
C++

#pragma once
#include "KRenderObject.h"
#include "KPrimitivePathEffect.h"
#include "KSeqModel.h"
#include "KSmartPtr.h"
#define PFX_NONX3 "nonx3"
#define PFX_NOTEX "notex"
/** 다른 Seq 시리즈들과의 통일성을 유지하기 위해 모든 시간 단위는 millsecond * 4.8
따라서 velocity 같은 것들도 millsecond * 4.8 동안 진행되는 거리로 정의한다. */
class KResEffectEmitter : public KResource
{
protected:
DWORD m_dwStartTime; ///< 에미터가 활성화되는 시간 (PathEffect의 m_dwStartTime에 상대적인 시간)
int m_nLifeTime; ///< 에미터의 활동 시간 (-값이면 부모 PathEffect가 Active인 동안 계속 Active이다.)
float m_fStartPos; ///< 에미터가 최초로 나타나는 지점 0.0f ~ 1.0f
float m_fVelocity; ///< 에미터가 패스를 따라 움직이는 속도
//bool m_bLifeAffectAlpha; // 시간이 지나면서 알파값도 같이 감소시킬 것인가?
//int m_nSeqModel; // SeqModel ID
BOOL m_bDirectional; ///< 이펙트가 방향성을 갖을 것인가?
std::vector<std::string> m_vAniNames;
std::vector<std::string> m_vAniFileNames;
public:
KResEffectEmitter()
{
m_dwStartTime = 0;
m_nLifeTime = -1;
m_fStartPos = 0.0f;
m_fVelocity = 0.0f;
//m_nSeqModel = -1;
m_bDirectional = FALSE;
std::string str = PFX_NONX3;
m_vAniNames.push_back(str);
m_vAniFileNames.push_back(str);
}
virtual ~KResEffectEmitter()
{
Clear();
}
virtual void Clear()
{
DelAniNames();
}
virtual void DelAniNames()
{
m_vAniNames.erase(m_vAniNames.begin(), m_vAniNames.end());
m_vAniFileNames.erase(m_vAniFileNames.begin(), m_vAniFileNames.end());
std::string str = PFX_NONX3;
m_vAniNames.push_back(str);
m_vAniFileNames.push_back(str);
}
virtual KResource* Clone();
virtual bool Reload()
{
return true;
}
void SetStartTime(DWORD dwTime)
{
m_dwStartTime = dwTime;
}
DWORD GetStartTime()
{
return m_dwStartTime;
}
void SetLifeTime(int nTime)
{
m_nLifeTime = nTime;
}
int GetLifeTime()
{
return m_nLifeTime;
}
void SetStartPos(float fPos)
{
m_fStartPos = fPos;
}
float GetStartPos()
{
return m_fStartPos;
}
void SetVelocity(float fVel)
{
m_fVelocity = fVel;
}
float GetVelocity()
{
return m_fVelocity;
}
//void SetSeqModel(int nId)
//{
// m_nSeqModel = nId;
//}
//int GetSeqModel()
//{
// return m_nSeqModel;
//}
void AddAniName(const char* szName, const char* szFileName)
{
// 현재는 애니메이션 한개만 지원 - 여러개 지원하게 되면 "nonx3" 일때 덮어쓰는 코드 필요
if(GetNumAnis() > 0)
{
DelAniNames();
}
std::string strName = szName;
m_vAniNames.push_back(strName);
std::string strFileName = szFileName;
m_vAniFileNames.push_back(strFileName);
}
const char* GetAniName(int nId)
{
return m_vAniNames[nId].c_str();
}
const char* GetAniFileName(int nId)
{
return m_vAniFileNames[nId].c_str();
}
int GetNumAnis()
{
return (int)m_vAniNames.size();
}
void SetDirectional(BOOL bDirectional)
{
m_bDirectional = bDirectional;
}
BOOL IsDirectional()
{
return m_bDirectional;
}
};
DECL_SPTR(KResEffectEmitter)
class KResPathEffect : public KResource
{
protected:
std::vector<K3DPoint> m_vPoints;
float m_fOfsZ;
float m_fTotalPointVectorLength; ///< vPoints로 이루어진 벡터 길이의 총합
std::vector<KResEffectEmitterSPtr> m_vEmitters; ///< primitive와 polyline을 그리기 위해 최소한 두 개 (start, end) 는 있어야 한다
DWORD m_dwStartTime;
DWORD m_dwLifeTime;
BOOL m_bHasPolyLine; ///< 폴리라인을 갖고 있는가?
float m_fPolyLineWidth; ///< 폴리라인 폭
DWORD m_dwPolyLineColor; ///< 폴리라인 컬러
std::string m_strPolyLineTexName; ///< 폴리라인 텍스쳐 파일 이름
public:
KResPathEffect()
{
m_fOfsZ = 1.0f;
m_fTotalPointVectorLength = 0.0f;
m_dwStartTime = 0;
m_dwLifeTime = 0;
m_bHasPolyLine = FALSE;
m_fPolyLineWidth = 1.0f;
m_dwPolyLineColor = 0xFFFFFFFF;
m_strPolyLineTexName = PFX_NOTEX;
}
virtual ~KResPathEffect()
{
Clear();
}
virtual void DelEmitters();
virtual void DelEmitters(int nId, int numEmitters);
virtual void DelPoints();
virtual void DelPoints(int nId, int numPoint);
virtual void Clear()
{
DelEmitters();
DelPoints();
m_strPolyLineTexName = PFX_NOTEX;
}
virtual KResource* Clone();
virtual bool Reload()
{
return true;
}
void AddPoints(K3DPoint* pPoints, int numPoints);
void InsertPoints(int nId, K3DPoint* pPoints, int numPoints);
float CalcPointVectorLength(int nStart, int nEnd);
K3DPoint* GetPoints()
{
if(m_vPoints.size() > 0)
{
return &m_vPoints[0];
}
else
{
return NULL;
}
}
K3DPoint GetPoint(int nId)
{
return m_vPoints[nId];
}
int GetNumPoints()
{
return (int)m_vPoints.size();
}
K3DPoint& GetPointRef(int nId)
{
return m_vPoints.at(nId);
}
void SetStartTime(DWORD dwTime)
{
m_dwStartTime = dwTime;
}
DWORD GetStartTime()
{
return m_dwStartTime;
}
void SetLifeTime(DWORD dwTime)
{
m_dwLifeTime = dwTime;
}
DWORD GetLifeTime()
{
return m_dwLifeTime;
}
void SetOfsZ(float fOfsZ)
{
m_fOfsZ = fOfsZ;
}
float GetOfsZ()
{
return m_fOfsZ;
}
void SetTotalPointVectorLength(float fLen)
{
m_fTotalPointVectorLength = fLen;
}
float GetTotalPointVectorLength()
{
return m_fTotalPointVectorLength;
}
void AddEmitter(KResEffectEmitter* pEmitter)
{
m_vEmitters.push_back(KResEffectEmitterSPtr(pEmitter) );
}
KResEffectEmitter* GetEmitter(int nIdEmitter)
{
return m_vEmitters[nIdEmitter];
}
int GetNumEmitters()
{
return (int)m_vEmitters.size();
}
int GetPoint(float fPos, K3DPoint& pRes);
//void SetSeqModel(int nIdEmitter, int nIdModel)
//{
// int nSizeEmitter = m_vEmitters.size();
// if(nSizeEmitter <= nIdEmitter) return;
// //int nSizeModel = m_vSeqModelNames.size();
// //if(nSizeModel <= nIdModel) return;
// m_vEmitters[nIdEmitter].SetSeqModel(nIdModel);
//}
void SetHasPolyLine(BOOL bHasPolyLine)
{
m_bHasPolyLine = bHasPolyLine;
}
BOOL HasPolyLine()
{
return m_bHasPolyLine;
}
void SetPolyLineWidth(float fWidth)
{
m_fPolyLineWidth = fWidth;
}
float GetPolyLineWidth()
{
return m_fPolyLineWidth;
}
void SetPolyLineColor(DWORD dwColor)
{
m_dwPolyLineColor = dwColor;
}
DWORD GetPolyLineColor()
{
return m_dwPolyLineColor;
}
void SetPolyLineTexName(const char* szTexName)
{
m_strPolyLineTexName = szTexName;
}
const char* GetPolyLineTexName()
{
return m_strPolyLineTexName.c_str();
}
};
DECL_SPTR(KResPathEffect)
class KResPathEffectChain : public KResource
{
protected:
//std::vector<std::string> m_vSeqModelNames;
std::vector<KResPathEffectSPtr> m_vPathEffects;
BOOL m_bDirectional; ///< PathEffectChain이 방향성을 갖을 것인가?
float m_fMag; ///< PathEffectChain의 크기 (방향 벡터의 크기)
BOOL m_bEndTogether;
public:
KResPathEffectChain()
{
m_bDirectional = FALSE;
m_fMag = 0.0f;
m_bEndTogether = TRUE;
}
virtual ~KResPathEffectChain()
{
Clear();
}
//virtual void Clear();
/// 다~ 지운다
virtual void DelPathEffects()
{
m_vPathEffects.erase(m_vPathEffects.begin(), m_vPathEffects.end());
}
/// 일부만 지운다
virtual void DelPathEffects(int nId, int numPathEffects)
{
m_vPathEffects.erase(m_vPathEffects.begin() + nId, m_vPathEffects.begin() + nId + numPathEffects);
}
virtual void Clear()
{
DelPathEffects();
}
virtual bool Reload()
{
return true;
}
virtual void AddPathEffect(KResPathEffect* pPathEffect)
{
//int oldCap = m_vPoints.capacity();
//int newCap = m_vPoints.size() + numPoints;
//if(oldCap < newCap) m_vPoints.reserve(newCap);
m_vPathEffects.push_back(KResPathEffectSPtr(pPathEffect) );
}
virtual KResPathEffect* GetPathEffect(int nId)
{
return m_vPathEffects[nId];
}
virtual int GetNumPathEffects()
{
return (int)m_vPathEffects.size();
}
//KResPathEffect* GetPathEffect(int nIdPathEffect)
//{
// return m_vPathEffects[nIdPathEffect];
//}
//void AddSeqModel(const char* szName)
//{
// std::string strName = szName;
// m_vSeqModelNames.push_back(strName); // 이거 나중에 해제 안해줘도 되나?
//}
//void SetSeqModel(int nIdPathEffect, int nIdEmitter, int nIdModel)
//{
// size = m_vSeqModelNames.size();
// if(size <= nIdModel) return;
// int size = m_vPathEffects.size();
// if(size <= nIdPathEffect) return;
// m_vPathEffects[nIdPathEffect].SetSeqModel(nIdEmitter, nIdModel);
//}
//const char* GetSeqModelName(int nModel)
//{
// return m_vSeqModelNames[nModel].c_str();
//}
//int GetNumSeqModels()
//{
// return m_vSeqModelNames.size();
//}
void SetDirectional(BOOL bDirectional)
{
m_bDirectional = bDirectional;
}
BOOL IsDirectional()
{
return m_bDirectional;
}
void SetMag(float fMag)
{
m_fMag = fMag;
}
float GetMag()
{
return m_fMag;
}
void SetEndTogether(BOOL bEndTogether)
{
m_bEndTogether = bEndTogether;
}
BOOL DoesEndTogether()
{
return m_bEndTogether;
}
};
DECL_SPTR(KResPathEffectChain)
class KEffectEmitter
{
public:
KEffectEmitter();
~KEffectEmitter();
void Clear();
void SetRes(KResEffectEmitter* pRes);
KResEffectEmitter* GetRes();
void Update(DWORD dwTime);
BOOL IsActive();
//void SetActive(BOOL bActive); // 에디터용
float GetPos();
void SetPos(float fPos);
//float GetAlpha();
//void SetSeqModel(KSeqModel* pSeqModel);
KSeqModel* GetSeqModel();
void CreateSeqModel();
void DelSeqModel();
DWORD GetCurrTime();
void CalcTimes(float fScale);
DWORD GetStartTime();
int GetLifeTime();
private:
KResEffectEmitterSPtr m_spRes;
BOOL m_bActive; ///< 현재 활성화 되있는가?
DWORD m_dwCurrTime;
float m_fCurrPos; ///< 0.0f ~ 1.0f
KSeqModel* m_pSeqModel;
DWORD m_dwStartTime;
int m_nLifeTime;
};
class _KSeqPathEffect : public KSeqObject
{
public:
//struct SPathVertex
//{
// K3DVector vPos;
// float fLength; // 누적된 길이 - 마지막 점의 fLength는 PatheEffect의 m_fTotalVertVectorLength와 같아야 한다. 실제 게임상의 좌표 단위.
//};
enum EPathDrawMode
{
DRAW_POINT = 1 << 0, ///< 에디터용 - 버텍스와 에미터의 위치에 작은 쿼드를 그린다.
DRAW_LINE = 1 << 1, ///< 에디터용
DRAW_ALLPR = 1 << 2, ///< 에디터용
DRAW_EMITTER = 1 << 3,
DRAW_POLYLINE = 1 << 4,
};
_KSeqPathEffect();
virtual ~_KSeqPathEffect();
//void Init(K3DPoint* pPoints, int numPoints);
void Clear();
virtual void DelEmitters();
//virtual void Init();
virtual void SetRes(KResPathEffect* pRes);
virtual KResPathEffect* GetRes();
//virtual KSeqObject* Clone();
virtual void SetTime(DWORD dwTime);
virtual void realizeTime();
//virtual BOOL IsActive();
virtual void Update() = 0;
//virtual void SetPrDrawMode(bool bPrDrawMode);
virtual void SetDrawMode(DWORD dwDrawMode);
//virtual void AttachToTerrain(class CTerrainMapEngine* pTerrain);
//virtual void AttachToTerrain(CTerrainMapEngine* pTerrain, K3DPoint p1, K3DPoint p2);
virtual void UpdatePr();
virtual void Render( KViewportObject *viewport, DWORD flag = RENDEREFX_NONE, const K3DMatrix * pAttachMat = NULL );
//virtual void AddEmitters(KEffectEmitter* pEmitters, int numEmitters);
virtual int GetVert(float fPos, K3DVertex& vRes);
virtual void AddVert(K3DVector vPos);
//int GetCurrLifeTime(DWORD dwTime);
//virtual BOOL AddSeqModel(int nEmitter, const char* szFileName);
//virtual BOOL SetSeqModel(int nEmitter, int nModel);
virtual void RenderEmitter(int nEmitter, KViewportObject* viewport);
virtual void RenderPolyLine(KViewportObject* viewport);
//virtual void DelSeqModels();
static void SetTerrainEngine(class CTerrainMapEngine* pTerrain);
virtual void SetMat(K3DMatrix* pMat);
void CreatePolyLineTex();
void DelPolyLineTex();
void CalcTimes();
DWORD GetStartTime();
DWORD GetLifeTime();
/// m_bEndTogether == TRUE 일때만 사용
void SetLifeTime(DWORD dwLifeTime);
protected:
KResPathEffectSPtr m_spRes;
std::vector<PfxPathVertex> m_vVerts;
KQuadPrimitive m_prQuad;
KLinePrimitive m_prLine;
KPolyLinePrimitive m_prPolyLine;
float m_fTotalVertVectorLength; ///< vVerts로 이루어진 벡터 길이의 총합
std::vector<KEffectEmitter*> m_vEmitters; ///< primitive와 polyline을 그리기 위해 최소한 두 개 (start, end) 는 있어야 한다
//DWORD m_dwStartTime; // 최초로 생성된 시간을 기억한다.
DWORD m_dwDrawMode;
//std::vector<KSeqModel*> m_vSeqModels;
static class CTerrainMapEngine* m_pTerrainEngine;
BOOL m_bActive;
K3DMatrix* m_pMat;
K3DTextureSPtr m_spPolyLineTex;
DWORD m_dwStartTime;
DWORD m_dwLifeTime;
};
class KSeqPathEffect : public _KSeqPathEffect
{
public:
KSeqPathEffect();
virtual ~KSeqPathEffect();
virtual KSeqObject* Clone();
//virtual void realizeTime();
virtual void Update();
virtual void PointsToVerts();
//void SetPrDrawMode(bool bPrDrawMode);
//void AttachToTerrain(class CTerrainMapEngine* pTerrain);
//void AttachToTerrain(CTerrainMapEngine* pTerrain, K3DPoint p1, K3DPoint p2);
//virtual void UpdatePr();
//virtual void Render( KViewportObject *viewport, DWORD flag = RENDEREFX_NONE, const K3DMatrix * pAttachMat = NULL );
//virtual void AddEmitters(KEffectEmitter* pEmitters, int numEmitters);
//virtual int GetVert(float fPos, K3DVertex& vRes);
//virtual void AddVert(K3DVector vPos);
//int GetCurrLifeTime(DWORD dwTime);
//virtual BOOL AddSeqModel(int nEmitter, const char* szFileName);
//virtual void RenderEmitter(int nEmitter, KViewportObject* viewport);
//virtual void DelSeqModels();
};
class KSeqPathEffectGround : public _KSeqPathEffect
{
public:
KSeqPathEffectGround();
virtual ~KSeqPathEffectGround();
//void Init(K3DPoint* pPoints, int numPoints);
//void Clear();
virtual KSeqObject* Clone();
//virtual void realizeTime();
virtual void Update();
//void SetPrDrawMode(bool bPrDrawMode);
virtual void AttachToTerrain();
virtual void AttachToTerrain(K3DPoint p1, K3DPoint p2);
//virtual void UpdatePr();
//virtual void Render( KViewportObject *viewport, DWORD flag = RENDEREFX_NONE, const K3DMatrix * pAttachMat = NULL );
//virtual void AddEmitters(KEffectEmitter* pEmitters, int numEmitters);
//virtual int GetVert(float fPos, K3DVertex& vRes);
//virtual void AddVert(K3DVector vPos);
//int GetCurrLifeTime(DWORD dwTime);
//virtual BOOL AddSeqModel(int nEmitter, const char* szFileName);
//virtual void RenderEmitter(int nEmitter, KViewportObject* viewport);
//virtual void DelSeqModels();
};
class KSeqPathEffectChain : public KSeqObject
{
public:
enum EPathType
{
TYPE_ORDINARY = 0,
TYPE_GROUND,
};
KSeqPathEffectChain();
virtual ~KSeqPathEffectChain();
virtual void Clear();
virtual void SetRes(KResPathEffectChain* pRes);
virtual KResPathEffectChain* GetRes();
virtual KSeqObject* Clone();
virtual void SetTime(DWORD dwTime);
virtual void Update();
virtual void realizeTime();
virtual void Render( KViewportObject *viewport, DWORD flag = RENDEREFX_NONE, const K3DMatrix * pAttachMat = NULL );
static void SetTerrainEngine(class CTerrainMapEngine* pTerrain);
virtual void SetDrawMode(DWORD dwDrawMode);
//virtual void SetDrawMode();
virtual void DelPathEffects();
virtual void SetType(DWORD dwType);
virtual void SetPos(K3DVector vOrigin);
virtual void SetPos(K3DVector vOrigin, K3DVector vTarget);
virtual void CalcTimes();
protected:
KResPathEffectChainSPtr m_spRes;
std::vector<_KSeqPathEffect*> m_vPathEffects;
//DWORD m_dwStartTime;
DWORD m_dwDrawMode;
static class CTerrainMapEngine* m_pTerrainEngine;
// std::vector<KSeqModel*> m_vSeqModels;
DWORD m_dwType;
//BOOL m_bDirectional;
K3DMatrix m_Mat;
};