#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 m_vAniNames; std::vector 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 m_vPoints; float m_fOfsZ; float m_fTotalPointVectorLength; ///< vPoints로 이루어진 벡터 길이의 총합 std::vector 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 m_vSeqModelNames; std::vector 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 m_vVerts; KQuadPrimitive m_prQuad; KLinePrimitive m_prLine; KPolyLinePrimitive m_prPolyLine; float m_fTotalVertVectorLength; ///< vVerts로 이루어진 벡터 길이의 총합 std::vector m_vEmitters; ///< primitive와 polyline을 그리기 위해 최소한 두 개 (start, end) 는 있어야 한다 //DWORD m_dwStartTime; // 최초로 생성된 시간을 기억한다. DWORD m_dwDrawMode; //std::vector 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 m_vSeqModels; DWORD m_dwType; //BOOL m_bDirectional; K3DMatrix m_Mat; };