/* ========================================================================== * ÀÛ ¼º ÀÚ : À̼ø±Ô * ÀÛ ¼º ÀÏ : 2006.12.04 * ³» ¿ë : ³×ºñ¸Þ½Ã ³ëµå * ÁÖÀÇ»çÇ× : *===========================================================================*/ #pragma once #include "Box.h" class cRay; class cNaviMeshBranchNode; class cNaviMeshLeafNode; class cNaviMeshBuffer; #ifdef MAP_EDITOR class cNaviMeshNodeBuildingInfo; class cNaviMeshNodeBuilding; #endif /// ³×ºñ¸Þ½Ã ³ëµå class cNaviMeshNode { public: cNaviMeshNode( cNaviMeshBranchNode* parent, unsigned int xi, unsigned int yi, unsigned int cellCount ); virtual ~cNaviMeshNode(); /// ·Îµù virtual bool Load( cFileLoader& loader ) = 0; /// ÀúÀå virtual bool Save( cFileSaver& saver ) = 0; /// ³×ºñ¸Þ½ÃÀÇ ³ôÀ̸ʰú µ¿±âÈ­ virtual void SyncHeight() = 0; /// Äøµ virtual void Cull( tArray* visibleArray, NiFrustumPlanes& frustum ) = 0; /// °¡½Ã ¹è¿­¿¡ Ãß°¡ virtual void AddToVisibleArray( tArray* visibleArray ) = 0; /// Ãæµ¹ °Ë»ç virtual bool CollideRay( NiPoint3* contact, float* distance, const cRay& ray, float maxDistance ) = 0; /// °æ°è »óÀÚ const cBox& GetBoundBox() const; public: /// ºÎ¸ð cNaviMeshBranchNode* mParent; /// °æ°è cBox mBoundBox; NiPoint3 mCenter; float mRadius; }; inline const cBox& cNaviMeshNode::GetBoundBox() const { return mBoundBox; } /// ³×ºñ¸Þ½Ã °¡Áö ³ëµå class cNaviMeshBranchNode : public cNaviMeshNode { friend class cNaviMeshLeafNode; public: cNaviMeshBranchNode( cNaviMeshBranchNode* parent, unsigned int xi, unsigned int yi, unsigned int cellCount ); ~cNaviMeshBranchNode(); /// ·Îµù bool Load( cFileLoader& loader ); /// ÀúÀå bool Save( cFileSaver& saver ); /// ÁöÇüÀÇ ³ôÀ̸ʰú µ¿±âÈ­ void SyncHeight(); /// Äøµ void Cull( tArray* visibleArray, NiFrustumPlanes& frustum ); /// °¡½Ã ¹è¿­¿¡ Ãß°¡ void AddToVisibleArray( tArray* visibleArray ); /// Ãæµ¹ °Ë»ç bool CollideRay( NiPoint3* contact, float* distance, const cRay& ray, float maxDistance = NI_INFINITY ); protected: /// °æ°è »óÀÚ¸¦ °»½Å void UpdateBoundUpward(); public: /// ÀÚ½Ä ¹è¿­ cNaviMeshNode* mChild[4]; }; /// ³×ºñ¸Þ½Ã ¸®ÇÁ ³ëµå class cNaviMeshLeafNode : public cNaviMeshNode { friend class cNaviMesh; friend class cNaviMeshBranchNode; friend class cNaviMeshNodeCompareForRendering; #ifdef MAP_EDITOR friend class cNaviMeshNodeBuilding; friend class cNaviFieldNodePainting; #endif public: cNaviMeshLeafNode( cNaviMeshBranchNode* parent, unsigned int xi, unsigned int yi, unsigned int gridSize ); ~cNaviMeshLeafNode(); /// ·Îµù bool Load( cFileLoader& loader ); /// ÀúÀå bool Save( cFileSaver& saver ); /// ÁöÇüÀÇ ³ôÀ̸ʰú µ¿±âÈ­ void SyncHeight(); /// Äøµ void Cull( tArray* visibleArray, NiFrustumPlanes& frustum ); /// °¡½Ã ¹è¿­¿¡ Ãß°¡ void AddToVisibleArray( tArray* visibleArray ); /// Ãæµ¹ °Ë»ç bool CollideRay( NiPoint3* contact, float* distance, const cRay& ray, float maxDistance = NI_INFINITY ); #ifdef MAP_EDITOR /// ¿Ã¸² bool Raise( const NiPoint3& pos, float innerRadius, float outerRadius, float maxValue ); /// ³·Ãã bool Lower( const NiPoint3& pos, float innerRadius, float outerRadius, float maxValue ); /// ÆòÆòÇÏ°Ô ¸¸µê bool Flatten( const NiPoint3& pos, float innerRadius, float outerRadius, float maxValue ); /// ºÎµå·´°Ô ¸¸µê /// ratio´Â [0.1, 1] ¹üÀ§ÀÇ °ªÀ» °¡Á®¾ß ÇÑ´Ù. 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 ); private: /// °æ°è »óÀÚ¸¦ °»½Å void UpdateBoundUpward(); /// ±âÇÏ Á¤º¸¸¦ °»½Å void UpdatePosCoords(); #ifdef MAP_EDITOR /// º¯°æÀü Á¤º¸¸¦ ¹é¾÷ /// Undo, Redo¿¡ ÇÊ¿äÇÑ Á¤º¸¸¦ ¼öÁýÇÑ´Ù. bool BackupBuilding( cNaviMeshNodeBuildingInfo* info, const NiPoint3& pos, float outerRadius ); /// ³×ºñ¸Þ½ÃÀÇ ³ôÀ̸ʰú µ¿±âÈ­ ¹× °»½Å /// µ¿±âÈ­´Â °è»ê»óÀÇ ¿ÀÂ÷·Î ÀÎÇÑ Å©·¢À» ¹æÁöÇÑ´Ù. void UpdateBuilding( cNaviMeshNodeBuildingInfo* info, const NiPoint3& pos, float outerRadius ); /// Undo, Redo void Undo( const cNaviMeshNodeBuilding& doing ); void Redo( const cNaviMeshNodeBuilding& doing ); #endif /// Á¤Á¡ ¹üÀ§¸¦ °è»ê bool CalcRange( unsigned int* xbegin, unsigned int* ybegin, unsigned int* xend, unsigned int* yend, const NiPoint3& pos, float outerRadius ); private: /// ÁÂÇ¥ (³×ºñ¸Þ½Ã ±×¸®µå »óÀÇ À§Ä¡) unsigned int mXIndex; unsigned int mYIndex; /// ¹öÆÛ cNaviMeshBuffer* mBuffer; /// ³ôÀÌ ¹è¿­ float* mHeights; private: /// ¹öÀü static unsigned int mVersion; /// ¸®ÇÁ ³ëµåÀÇ ±×¸®µå Å©±â static unsigned int mCellCount; static unsigned int mLineCount; }; /// ³×ºñ¸Þ½Ã ³ëµå ºñ±³ ÇÔ¼öÀÚ class cNaviMeshNodeCompareForRendering { public: bool operator () ( const cNaviMeshLeafNode* left, const cNaviMeshLeafNode* right ) const { cNaviMeshBuffer* lbuff = left->mBuffer; cNaviMeshBuffer* rbuff = right->mBuffer; return lbuff < rbuff; }; };