#ifndef __CHARACTER_SPHERE_TREE_H__ #define __CHARACTER_SPHERE_TREE_H__ #include "Sphere.h" #include "CharSphereTreeConstants.h" using namespace SphereConst; #include #ifndef SAFE_DELETE #define SAFE_DELETE(p) { if ((p)) { delete (p); (p) = NULL; } } #endif #ifndef SAFE_DELETE_ARRAY #define SAFE_DELETE_ARRAY(p) { if ((p)) { delete [] (p); (p) = NULL; } } #endif //====================================================================================== struct Position; class CCharacter; class CSphere; class CCharSphereNode; class CCharSphereTree; class CCharSphereNodeFifo; class ICharSphereTreeCallBack; //====================================================================================== class ICharSphereTreeCallBack { public: virtual void RangeTestCallBack( const Position& centerPos, float fDistance, CCharSphereNode* pNode ) { } private: }; //====================================================================================== class CCharSphereNode : public CSphere { public: CCharSphereNode(); CCharSphereNode( CCharSphereTree* pTree, const Position& Pos, float fRadius, void* pLink ); void Init( CCharSphereTree* pTree, const Position& Pos, float fRadius, void* pLink ); // =================================================================== // Flag ÇÔ¼ö void SetSphereNodeFlag( eSphereNodeFlag flag ) { m_dwFlag |= flag; } void ClearShpereNodeFlag( eSphereNodeFlag flag ) { m_dwFlag &= ~flag; } bool HasSphereNodeFlag( eSphereNodeFlag flag ) const { if ( m_dwFlag & flag ) return true; return false; } // =================================================================== // ij¸¯ÅÍ °ü·Ã ÇÔ¼ö void SetCID( unsigned long dwCID ) { m_dwCID = dwCID; } unsigned long GetCID() const { return m_dwCID; } void SetCharacter(CCharacter* pCharacter) { m_pCharacter = pCharacter; } CCharacter* GetCharacter() const { return m_pCharacter; } // =================================================================== // ºÎ¸ð & ÀÚ½Ä ÇÔ¼ö void SetParent( CCharSphereNode* pParent ) { m_pParent = pParent; } CCharSphereNode* GetParent() const { return m_pParent; } void AddChild( CCharSphereNode* pChild ); void DeleteChild( CCharSphereNode* pChild ); CCharSphereNode* GetChildren() const { return m_pChildren; } int GetChildCount() const { return m_iChildCount; } // =================================================================== // °°Àº ·¹º§ÀÇ ÇüÁ¦ ÇÔ¼ö void SetPrevSibling( CCharSphereNode* pNode ) { m_pPrevSibling = pNode; } void SetNextSibling( CCharSphereNode* pNode ) { m_pNextSibling = pNode; } CCharSphereNode* GetPrevSibling() const { return m_pPrevSibling; } CCharSphereNode* GetNextSibling() const { return m_pNextSibling; } // =================================================================== // Fifo Æ÷ÀÎÅÍ °ü¸® ÇÔ¼ö void SetRecomputeFifo( CCharSphereNode** ppFifo ) { m_ppRecomuteFifo = ppFifo; } void SetIntegrateFifo( CCharSphereNode** ppFifo ) { m_ppIntegrateFifo = ppFifo; } // =================================================================== // ºÎ¸ð¿Í ÀÚ½Ä ¸ðµÎÀÇ ¿¬°áÀ» ²÷´Â ÇÔ¼ö (½ÇÁ¦·Î´Â ºÎ¸ð¿Í¸¸ ¿¬°áÀ» ²÷´Â´Ù.) void Unlink(); // =================================================================== // Root tree node ÀÇ Link ( Leaf tree ÀÇ Root °¡ ¾Æ´Ñ SuperSphere node °¡ °¡Áø´Ù ) void SetLink( void* pLink ) { m_pLink = pLink; } void* GetLink() const { return m_pLink; } // =================================================================== // ÁÂÇ¥ º¯°æ ÇÔ¼ö void NewPos( const Position& Pos ); void NewPos( float fX, float fY, float fZ ); void NewPosRadius( const Position& Pos, float fRadius ); void NewPosRadius( float fX, float fY, float fZ, float fRadius ); // =================================================================== // °Å¸® ¹× ¹ÙÀεù°Å¸® °è»ê ÇÔ¼ö float Distance2( const CCharSphereNode* pNode ); void ComputeBindingDistance( const CCharSphereNode* pParent ); // =================================================================== // Å©±â Àç°è»ê ÇÔ¼ö ( true ¸®ÅϽÿ¡´Â Á¦°ÅÇØ¾ßÇÔ ) bool Recompute( float fGravy ); // =================================================================== // ¹üÀ§ Å×½ºÆ®¿ë ÇÔ¼ö void RangeTest( const Position& centerPos, float fDistance, ICharSphereTreeCallBack* pCallBack ); void SendToRange( const Position& centerPos, float fDistance, const char* szPacket, unsigned long dwPacketSize, unsigned char cCMD_In ); protected: private: unsigned long m_dwCID; CCharacter* m_pCharacter; CCharSphereNode* m_pParent; CCharSphereNode* m_pChildren; CCharSphereNode* m_pPrevSibling; CCharSphereNode* m_pNextSibling; CCharSphereNode** m_ppRecomuteFifo; // Recompute Fifo ³»ÀÇ À§Ä¡ Æ÷ÀÎÅÍ CCharSphereNode** m_ppIntegrateFifo; // Integrate Fifo ³»ÀÇ À§Ä¡ Æ÷ÀÎÅÍ int m_iChildCount; unsigned long m_dwFlag; float m_fBindingDistance2; void* m_pLink; CCharSphereTree* m_pTree; }; //====================================================================================== class CCharSphereTree { public: CCharSphereTree( int iMaxSphereNode, float fRootSize, float fLeafSize, float fGravy ); virtual ~CCharSphereTree(); typedef std::map< unsigned long, CCharSphereNode* > CharSphereMap; static CCharSphereTree& GetInstance(); // =================================================================== // Tree ÀÇ Node ¸¦ Àç°è»êÇϰí À籸¼ºÇϴ ó¸® ÇÔ¼ö void Process(); // =================================================================== // ij¸¯ÅÍ °ü·Ã ÇÔ¼ö bool AddCharacter( unsigned long dwCID, CCharacter* pCharacter, const Position& Pos ) ; bool DeleteCharacter( unsigned long dwCID ); void MoveTo( unsigned long dwCID, const Position& NewPos ); // =================================================================== // CCharSphereNode ¸¦ »ý¼º(ij¸¯ÅÍ Á¦¿Ü)ÇØ¼­ À籸¼ºÇÏ´Â ÇÔ¼ö ¿Í »èÁ¦ÇÏ´Â ÇÔ¼ö CCharSphereNode* AddSphere( const Position& Pos, float fRadius, void* pLink, unsigned long dwFlag = SNF_LEAF_TREE ); void DeleteSphere( CCharSphereNode* pNode ); // =================================================================== // Àç°è»ê, À籸¼º ¸®½ºÆ®¿¡ Node Ãß°¡ ÇÔ¼ö void AddRecompute( CCharSphereNode* pNode ); void AddIntegrate( CCharSphereNode* pNode ); // =================================================================== // Tree ¸¦ À籸¼ºÇÏ´Â ÇÔ¼ö void Integrate( CCharSphereNode* pNode, CCharSphereNode* pSuperSphere, float fNodeSize ); // =================================================================== // ¹üÀ§ Å×½ºÆ®¿ë ÇÔ¼ö void RangeTest( const Position& centerPos, float fDistance, ICharSphereTreeCallBack* pCallBack ); void SendToRange( const Position& centerPos, float fDistance, const char* szPacket, unsigned long dwPacketSize, unsigned char cCMD_In ); protected: // =================================================================== // ¸ðµç ÀÚ½Ä Node ¸¦ ¸Þ¸ð¸® ÇØÁ¦ÇÏ´Â ÇÔ¼ö void DeleteAllChildSphere( CCharSphereNode* pRootNode ); private: CCharSphereNode* m_pRoot; CCharSphereNode* m_pLeaf; CCharSphereNodeFifo* m_Recompute; CCharSphereNodeFifo* m_Integrate; float m_fMaxRootSize; float m_fMaxLeafSize; float m_fSuperSphereGravy; CharSphereMap m_CharSphereMap; }; //====================================================================================== class CCharSphereNodeFifo { public: CCharSphereNodeFifo( int iSize ) { m_iCount = 0; m_iStackPointer = 0; m_iBottom = 0; m_iSize = iSize; m_ppFifo = new CCharSphereNode *[ m_iSize ]; }; ~CCharSphereNodeFifo() { SAFE_DELETE_ARRAY( m_ppFifo ); }; CCharSphereNode** Push( CCharSphereNode* pNode ) { m_iCount++; CCharSphereNode** ret = &m_ppFifo[ m_iStackPointer ]; m_ppFifo[ m_iStackPointer ] = pNode; ++m_iStackPointer; if ( m_iStackPointer == m_iSize ) m_iStackPointer = 0; return ret; }; CCharSphereNode* Pop() { while ( m_iStackPointer != m_iBottom ) { --m_iCount; CCharSphereNode* ret = m_ppFifo[ m_iBottom ]; ++m_iBottom; if ( m_iBottom == m_iSize ) m_iBottom = 0; if ( ret ) return ret; } return NULL; } bool Flush( CCharSphereNode* pNode ) { if ( m_iStackPointer == m_iBottom ) return false; int i = m_iBottom; while ( i != m_iStackPointer ) { if ( m_ppFifo[i] == pNode ) { m_ppFifo[i] = NULL; return true; } i++; if ( i == m_iSize ) i = 0; } return false; }; int GetCount(void) const { return m_iCount; } private: int m_iCount; int m_iStackPointer; int m_iBottom; int m_iSize; CCharSphereNode** m_ppFifo; }; #endif __CHARACTER_SPHERE_TREE_H__