/* ========================================================================== * ÀÛ ¼º ÀÚ : À̼ø±Ô * ÀÛ ¼º ÀÏ : 2006.12.04 * ³» ¿ë : ³×ºñ¸Þ½Ã * ÁÖÀÇ»çÇ× : *===========================================================================*/ #pragma once #include "Shader.h" class cRay; class cBox; class cSceneNode; class cNaviMeshBranchNode; class cNaviMeshLeafNode; #ifdef MAP_EDITOR class cNaviMeshBuildingInfo; #endif /// ³×ºñ¸Þ½Ã »ó¼ö const unsigned int NAVIMESH_DEFAULT_RESOLUTION = 512; const unsigned int NAVIMESH_BUFF_CELL_COUNT = 128; const unsigned int NAVIMESH_BUFF_LINE_COUNT = NAVIMESH_BUFF_CELL_COUNT + 1; const unsigned int NAVIMESH_BUFF_VERT_COUNT = NAVIMESH_BUFF_LINE_COUNT * NAVIMESH_BUFF_LINE_COUNT; const unsigned int NAVIMESH_LEAF_CELL_COUNT = 8; const unsigned int NAVIMESH_LEAF_LINE_COUNT = NAVIMESH_LEAF_CELL_COUNT + 1; const unsigned int NAVIMESH_LEAF_LINE_COUNT_X2 = NAVIMESH_LEAF_LINE_COUNT * 2; const unsigned int NAVIMESH_LEAF_VERT_COUNT = NAVIMESH_LEAF_LINE_COUNT * NAVIMESH_LEAF_LINE_COUNT; /// ³×ºñ¸Þ½Ã ·Îµù ¿¡·¯ ÄÚµå const int NAVIMESH_LOAD_ERROR_OPEN = -1; const int NAVIMESH_LOAD_ERROR_FILE_HEADER = -2; const int NAVIMESH_LOAD_ERROR_FILE_TYPE = -3; const int NAVIMESH_LOAD_ERROR_FILE_VERSION = -4; const int NAVIMESH_LOAD_ERROR_GRID_SIZE = -5; const int NAVIMESH_LOAD_ERROR_TEXTURE_NAME = -6; const int NAVIMESH_LOAD_ERROR_TEXTURE = -7; const int NAVIMESH_LOAD_ERROR_NODE = -8; /// ³×ºñ¸Þ½Ã ÆÄÀÏ Çì´õ #pragma pack( push, 1 ) class cNaviMeshFileHeader { public: /// ½Äº° ÄÚµå char mCode[13]; /// ¹öÀü unsigned int mVersion; /// ±×¸®µå Å©±â (¼¿ ¼ö) unsigned int mCellCount; /// Á¤Á¡´ç ¹ÌÅÍ ¼ö float mMetersPerVertex; /// ¹ÌÅÍ´ç ´ÜÀ§ ¼ö ( 100 ) unsigned int mUnitsPerMeter; }; #pragma pack( pop ) /// ³×ºñ¸Þ½Ã ¹öÆÛ class cNaviMeshBuffer { friend class cNaviMesh; friend class cNaviMeshLeafNode; public: cNaviMeshBuffer(); ~cNaviMeshBuffer(); bool Init( cNaviMesh* naviMesh, unsigned int xi, unsigned int yi ); protected: void UpdatePosCoord( cNaviMesh* naviMesh, unsigned int xstart, unsigned ystart, unsigned int count ); private: unsigned int mXIndex; unsigned int mYIndex; /// DX9 LPDIRECT3DVERTEXBUFFER9 mPosCoordBuffer; }; /// ³×ºñ¸Þ½Ã class cNaviMesh { static cNaviMesh* mSingleton; friend class cNaviMeshLeafNode; friend class cNaviMeshBuffer; friend class cNaviMeshBuilding; public: cNaviMesh(); ~cNaviMesh(); /// Áö¿ò void Clear(); /// ÃʱâÈ­ void Init( unsigned int cellCount, float metersPerVertex = 1.0f, unsigned int unitsPerMeter = 100 ); bool IsInited() const; /// ·Îµù int Load( const cString& pathName ); /// ÀúÀå bool Save( const cString& pathName ); /// ó¸® void Process(); /// ·»´õ¸µ void Render(); /// ¹öÆÛ cNaviMeshBuffer* GetBuffer( unsigned int xi, unsigned int yi ); /// ÇÈÅ· bool Pick( NiPoint3* pos, int mouseX, int mouseY ); bool Pick( NiPoint3* pos, const cRay& ray ); bool Pick( NiPoint3* pos, float* dist, const cRay& ray, float maxDistance ); /// ³ôÀ̰ª bool CalcHeight( float* height, float x, float y ) const; bool GetHeight( float* height, unsigned int xi, unsigned int yi ) const; const float* GetHeights() const; /// ÁöÇü¿¡ ¸ÂÃã void SyncAllToTerrain(); #ifdef MAP_EDITOR /// ÆíÁý bool Raise( const NiPoint3& pos, float innerRadius, float outerRadius, float strength ); bool Lower( const NiPoint3& pos, float innerRadius, float outerRadius, float strength ); bool Flatten( const NiPoint3& pos, float innerRadius, float outerRadius, float strength ); bool Smooth( const NiPoint3& pos, float outerRadius, float ratio ); #endif bool SyncToTerrain( const NiPoint3& pos, float innerRadius, float outerRadius ); bool SyncToObject( const NiPoint3& pos, float outerRadius ); bool SyncToPickHeight( const NiPoint3& pos, float innerRadius, float outerRadius, float z ); /// ±×¸®µå Å©±â unsigned int GetCellCount() const; /// Á¤Á¡´ç ¹ÌÅͼö float GetMetersPerVertex() const; /// ¹ÌÅÍ´ç ´ÜÀ§¼ö unsigned int GetUnitsPerMeter() const; /// Á¤Á¡ »çÀÌÀÇ ´ÜÀ§ float GetUnitsPerVertex() const; /// ¸®ÇÁ ³ëµå »çÀÌÀÇ ´ÜÀ§ float GetUnitsPerLeafNode() const; /// ÇØ´ç À§Ä¡ÀÇ ¸®ÇÁ ³ëµå cNaviMeshLeafNode* GetLeafNode( float x, float y ) const; /// º¸ÀÌ´Â ¸®ÇÁ ³ëµå ¼ö unsigned int GetNumVisibleNodes() const; /// °æ°è »óÀÚ const cBox& GetBoundBox() const; /// º¯°æ ¿©ºÎ bool IsModified() const; private: #ifdef MAP_EDITOR /// ¹é¾÷ /// Undo, Redo¿¡ ÇÊ¿äÇÑ Á¤º¸¸¦ ¼öÁýÇÑ´Ù. bool BackupBuilding( cNaviMeshBuildingInfo* info, unsigned int xbegin, unsigned int ybegin, unsigned int xend, unsigned int yend, const NiPoint3& pos, float outerRadius ); /// °»½Å void UpdateBuilding( cNaviMeshBuildingInfo* info, unsigned int xbegin, unsigned int ybegin, unsigned int xend, unsigned int yend, const NiPoint3& pos, float outerRadius ); #endif /// Àû¿ë ¹üÀ§ °è»ê bool CalcRange( unsigned int* xbegin, unsigned int* ybegin, unsigned int* xend, unsigned int* yend, const NiPoint3& pos, float outerRadius ); /// ±×¸®µå Å©±â¸¦ °Ë»ç bool CheckCellCount( unsigned int cellCount ); /// ÇØ´ç À§Ä¡¿¡ ¸®ÇÁ ³ëµå¸¦ ¼³Á¤ void SetLeafNode( unsigned int xi, unsigned int yi, cNaviMeshLeafNode* node ); /// ³ôÀ̰ª void SetHeight( unsigned int xi, unsigned int yi, float height ); float GetHeightFast( unsigned int xi, unsigned int yi ) const; public: /// ´ÜÀÏü¸¦ ¸®ÅÏ static cNaviMesh* GetSingleton(); private: /// ÃʱâÈ­ ¿©ºÎ bool mInited; /// ±×¸®µå Å©±â unsigned int mCellCount; unsigned int mLineCount; /// Á¤Á¡´ç ¹ÌÅÍ ( 1 ) float mMetersPerVertex; /// ¹ÌÅÍ´ç ´ÜÀ§ ( 100 ) unsigned int mUnitsPerMeter; /// Á¤Á¡´ç ´ÜÀ§ float mUnitsPerVertex; /// ¸®ÇÁ ³ëµå´ç ´ÜÀ§ float mUnitsPerLeafNode; /// ·çÆ® ³ëµå cNaviMeshBranchNode* mRootNode; /// ¸®ÇÁ ³ëµå ¹è¿­ typedef tArray cLeafNodeArray; cLeafNodeArray mNodeArray; /// ³ôÀÌ ¹è¿­ float* mHeights; /// °¡½Ã ¹è¿­ cLeafNodeArray mVisibleArray; /// ¼ÎÀÌ´õ cTerrainShader mShader; /// ¹öÆÛ cNaviMeshBuffer** mBuffer; /// DX9 LPDIRECT3DVERTEXDECLARATION9 mVertexDeclaration; LPDIRECT3DINDEXBUFFER9 mIndexBuffer; /// º¯°æ ¿©ºÎ bool mModified; }; inline bool cNaviMesh::IsInited() const { return mInited; } inline cNaviMeshBuffer* cNaviMesh::GetBuffer( unsigned int xi, unsigned int yi ) { return &(mBuffer[yi / NAVIMESH_BUFF_CELL_COUNT][xi / NAVIMESH_BUFF_CELL_COUNT]); } inline unsigned int cNaviMesh::GetCellCount() const { return mCellCount; } inline float cNaviMesh::GetMetersPerVertex() const { return mMetersPerVertex; } inline unsigned int cNaviMesh::GetUnitsPerMeter() const { return mUnitsPerMeter; } inline float cNaviMesh::GetUnitsPerVertex() const { return mUnitsPerVertex; } inline float cNaviMesh::GetUnitsPerLeafNode() const { return mUnitsPerLeafNode; } inline unsigned int cNaviMesh::GetNumVisibleNodes() const { return mVisibleArray.GetSize(); } inline void cNaviMesh::SetHeight( unsigned int xi, unsigned int yi, float height ) { mHeights[yi * mLineCount + xi] = height; } inline float cNaviMesh::GetHeightFast( unsigned int xi, unsigned int yi ) const { return mHeights[yi * mLineCount + xi]; } inline const float* cNaviMesh::GetHeights() const { return mHeights; } inline bool cNaviMesh::IsModified() const { return mModified; } inline cNaviMesh* cNaviMesh::GetSingleton() { return mSingleton; } #define NAVIMESH cNaviMesh::GetSingleton()