- °³¿ä
- ±âÁ¸ ±×¸®µåÀÇ ¹®Á¦Á¡
- °´Ã¼ÀÇ Å©±â¿¡ ÀÇÇÑ ¹®Á¦
- °´Ã¼°¡ ¼¿¿¡ ºñÇØ ³Ê¹« Å« °æ¿ì
- °´Ã¼°¡ ¼¿¿¡ ºñÇØ ³Ê¹« ÀÛÀº °æ¿ì
- °´Ã¼ÀÇ Å©±â°¡ °¡º¯ÀûÀÎ °æ¿ì
- ¸Þ¸ð¸® ¹®Á¦
- °èÃþÇü ±×¸®µå °³¿ä
- °èÃþÇü ±×¸®µå ±¸Çö
- HierarchicalGrid.h
- HierarchicalGrid.cpp
- ÀÀ¿ë ºÐ¾ß ¹× ÇѰèÁ¡
1 °³¿ä
ÀϹÝÀûÀÎ "ŸÀÏ" ¹æ½ÄÀÇ ´ÜÁ¡À» °³¼±ÇÑ °èÃþÇü µ¥ÀÌÅÍ ±¸Á¶. OcTree³ª QuadTree¿Í »ó´çÈ÷ ºñ½ÁÇÏÁö¸¸, Æ®¸® ·çÆ®°¡ Á¸ÀçÇÏÁö ¾Ê´Â´Ù´Â Á¡ÀÌ Æ²¸®´Ù. ·çÆ® ¾øÀÌ ·¹º§°ªÀ» ÅëÇØ ¹Ù·Î ÇØ´ç °èÃþ¿¡ Á¢±ÙÇÒ ¼ö Àֱ⠶§¹®¿¡ Æ®¸®¿¡ ºñÇØ¼ ºü¸£´Ù°í ÇÒ ¼ö ÀÖ´Ù.
2 ±âÁ¸ ±×¸®µåÀÇ ¹®Á¦Á¡
2.1 °´Ã¼ÀÇ Å©±â¿¡ ÀÇÇÑ ¹®Á¦
2.1.1 °´Ã¼°¡ ¼¿¿¡ ºñÇØ ³Ê¹« Å« °æ¿ì
| ¼¿ÀÌ ³Ê¹« ÀÛÀº °æ¿ì °´Ã¼°¡ ¿òÁ÷ÀÏ ¶§¸¶´Ù ´ë·®ÀÇ ¼¿À» ¾÷µ¥ÀÌÆ®ÇؾßÇÑ´Ù. Ãæµ¹ üũ¸¦ ÇÏ´Â °æ¿ì¿¡µµ ¸¶Âù°¡Áö´Ù. |
2.1.2 °´Ã¼°¡ ¼¿¿¡ ºñÇØ ³Ê¹« ÀÛÀº °æ¿ì
| ¼¿ÀÌ ³Ê¹« Å« °æ¿ì, ÇϳªÀÇ ¼¿¿¡ ¸¹Àº °´Ã¼µéÀÌ µé¾î°¡°Ô µÈ´Ù. ¿òÁ÷ÀÏ ¶§¸¶´Ù ´ë·®ÀÇ °´Ã¼µé°ú Ãæµ¹ Å×½ºÆ®¸¦ ÇØ¾ßÇÑ´Ù. |
| ½ÇÁ¦·Î Ãæµ¹ÇÏ´Â °´Ã¼°¡ ¾ø¾úÀ½¿¡µµ ºÒ±¸Çϰí, 5°³ÀÇ °´Ã¼µé°úÀÇ Ãæµ¹ Å×½ºÆ®¸¦ ÇØ¾ßÇÏ´Â °æ¿ìÀÌ´Ù. |
2.1.3 °´Ã¼ÀÇ Å©±â°¡ °¡º¯ÀûÀÎ °æ¿ì
| ¼¿ ¾÷µ¥ÀÌÆ®¿Í °´Ã¼ °£ Ãæµ¹ Å×½ºÆ® µÑ ´Ù ¹®Á¦°¡ µÇ´Â °æ¿ìÀÌ´Ù. |
2.2 ¸Þ¸ð¸® ¹®Á¦
¼¿°ú ¸Þ¸ð¸® °£ÀÇ ¸ÅÄ¡¿¡ ÀÖ¾î¼, °¡Àå °£´ÜÇÏ°Ô »ý°¢ÇÒ ¼ö ÀÖ´Â °ÍÀº ±×³É Â÷¿ø¿¡ µû¶ó ¹è¿À» Àâ°í, °¢°¢ÀÇ ¼¿À» Çϳª¾¿ 1:1 ´ëÀÀ½ÃŰ´Â ¹æ¹ýÀÌ´Ù. ÇÏÁö¸¸ ÀÌ ¹æ¹ýÀº ¾î´À Á¤µµ "Àû´çÇÑ" Å©±âÀÇ ¼¿À» »ç¿ëÇÏ°Ô µÇ¸é °ÅÀÇ ÇÊ¿¬ÀûÀ¸·Î ¸Þ¸ð¸® ¹®Á¦¸¦ ÀÏÀ¸Å²´Ù. ¾î¶»°Ô ÇÒ´çÇÒ ¼ö ÀÖ°Ú´Ù°¡ ¾Æ´Ï¶ó ¸î ±â°¡¹ÙÀÌÆ® ¼öÁØÀÌ ³ª¿Â´Ù.
3 °èÃþÇü ±×¸®µå °³¿ä
°èÃþÇü ±×¸®µå´Â À§¿Í °°ÀÌ °°Àº ¿µ¿ªÀ» Ä¿¹öÇÏ´Â ¿©·¯ °èÃþÀÇ ±×¸®µå·Î ÀÌ·ç¾îÁø´Ù.
ºü¸¥ »ðÀÔ ¹× »èÁ¦¸¦ À§ÇØ, ÀÓÀÇÀÇ °´Ã¼´Â Å©±â¿¡ µû¶ó ÀÚ½ÅÀ» ¿ÏÀüÈ÷ ¼ö¿ëÇÒ ¼ö ÀÖ´Â °èÃþÀÇ ¼¿¿¡¸¸ »ðÀԵȴÙ. À§¿¡¼µµ ¾ð±ÞÇßµíÀÌ ¼¿ Å©±â°¡ ³Ê¹« ÀÛÀ¸¸é, °´Ã¼°¡ ¿òÁ÷ÀÏ ¶§ ³Ê¹« ¸¹Àº ¾÷µ¥ÀÌÆ®°¡ ÇÊ¿äÇÏ°Ô µÈ´Ù. À̸¦ ¹æÁöÇϱâ À§ÇØ °¡Àå ³·Àº ·¹º§ÀÇ ¼¿ Å©±â´Â ¿ùµå ¾È¿¡ Á¸ÀçÇÏ´Â °¡Àå ÀÛÀº °´Ã¼ÀÇ Å©±âº¸´Ù´Â Ä¿¾ß ÇÑ´Ù. ·¹º§ÀÌ ¿Ã¶ó°¥ ¶§¸¶´Ù ¼¿ÀÇ Å©±â°¡ 2¹è¾¿ Ä¿Áö´Â °ÍÀÌ ÀϹÝÀûÀ̳ª, ¹Ýµå½Ã ±×·¡¾ßÇÒ ÇÊ¿ä´Â ¾ø´Ù. ¾î·µç ÃÖ°í ·¹º§ÀÇ ¼¿Àº ¿ùµå ¾È¿¡ Á¸ÀçÇÏ´Â °¡Àå Å« Å©±âÀÇ °´Ã¼º¸´Ù Ä¿¾ß ÇÑ´Ù.
ÀÌ·± ½ÄÀ¸·Î ±¸Á¶¸¦ ÀâÀ¸¸é, ÀÓÀÇÀÇ °´Ã¼´Â ÇÑ ¼ø°£¿¡ ÃÖ´ë 4°³ÀÇ ¼¿¿¡ °ÉÃÄÀÖ°Ô µÈ´Ù. Àß »ý°¢ÇØ º¸¸é, ÇϳªÀÇ ¼¿ÀÌ ¼ö¿ëÇÒ ¼ö ÀÖ´Â °´Ã¼ÀÇ Å©±â´Â ¼¿ Å©±âº¸´Ù ÀÛ°Ô ÇÏ´Â °ÍÀÌ ÁÁ´Ù´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. ¼¿ Å©±â¿Í µü ¸Â´Â °´Ã¼¸¦ ¼ö¿ëÇÏ°Ô µÇ¸é, °´Ã¼´Â ´ëºÎºÐÀÇ °æ¿ì 4°³ÀÇ ¼¿¿¡ °ÉÃÄÀÖ°Ô µÇ±â ¶§¹®ÀÌ´Ù. ¼¿ Å©±âÀÇ Àý¹Ý Á¤µµ¸¦, ¼ö¿ëÇÒ ¼ö ÀÖ´Â °´Ã¼ÀÇ ÃÖ´ë Å©±â·Î Àâ´Â °ÍÀÌ Àû´çÇÒ °Í °°´Ù.
ÀÓÀÇÀÇ °´Ã¼°¡ Ãæµ¹À» ÀÏÀ¸Å°´ÂÁö °Ë»çÇϱâ À§Çؼ´Â ¸ðµç ·¹º§À» µ¹¸é¼ ±× °´Ã¼ÀÇ ¿µ¿ª+1°ú °ãÄ¡´Â ¼¿µéÀ» °Ë»çÇØ¾ßÇÑ´Ù. ¿©±â¼ +1 ¿µ¿ªÀ̶õ ÇØ´ç ·¹º§¿¡¼ °´Ã¼ÀÇ ¿µ¿ª°ú °ãÄ¡´Â ¼¿µéÀ» »Ì¾Æ³½ ´ÙÀ½, ±×°ÍÀ» µ¿¼³²ºÏ(2DÀÇ °æ¿ì)À¸·Î 1ľ¿ È®ÀåÇÑ ¿µ¿ªÀ» ¸»ÇÑ´Ù. ¿Ö È®ÀåÀÌ ÇÊ¿äÇϳĸé, È®ÀåµÈ ¿µ¿ª ¾È¿¡µµ °´Ã¼°¡ Á¸ÀçÇÒ ¼ö Àֱ⠶§¹®ÀÌ´Ù. (°´Ã¼´Â ÃÖ´ë 4°³ÀÇ ¼¿¿¡ °ÉÃÄÀÖÀ» ¼ö ÀÖ´Ù´Â Á¡À» »ý°¢ÇØ º¸¶ó.)
°¢°¢ÀÇ ÃþÀ» ¸ðµÎ ¸Þ¸ð¸®¿¡ ÇÒ´çÇÏ°Ô µÇ¸é À§¿¡¼ ¾ð±ÞÇÑ ´Ü¼øÇÑ ±×¸®µåº¸´Ù ÈξÀ ´õ ¸¹Àº ¸Þ¸ð¸®¸¦ ¼Ò¸ðÇÏ°Ô µÇ¹Ç·Î, °´Ã¼°¡ Á¸ÀçÇÏ´Â ¼¿µé¸¸ »ý¼ºÇϰí, ÇØ½¬¸¦ ÅëÇØ À̸¦ ¾×¼¼½ºÇÑ´Ù.
4 °èÃþÇü ±×¸®µå ±¸Çö
¾Æ·¡ÀÇ ¼Ò½º¿¡¼´Â ´ëÃæ ´ÙÀ½°ú °°Àº ¸ð¾çÀÇ Å¬·¡½ºµéÀ» ÀÌ¿ëÇÑ´Ù.
// ´ëÃæ ÀÌ¿Í °°Àº ¸ð¾çÀÇ Å¬·¡½º¸¦ »ç¿ëÇÑ´Ù.
class cPoint3D
{
float x, y, z;
};
class cObject
{
cPoint3D m_Position;
float m_Radius;
size_t m_GridLevel;
DWORD m_GridHash;
cObject* m_Prev;
cObject* m_Next;
}; ¾î¼Æ®³ª ÇØ½¬ ÇÔ¼ö °°Àº °Ç ¾Ë¾Æ¼ ¹Ù²ãÁà¾ßÇÑ´Ù.
4.1 HierarchicalGrid.h
#ifndef __HIERARCHICALGRID_H__
#define __HIERARCHICALGRID_H__
#include "Object.h"
////////////////////////////////////////////////////////////////////////////////
/// \class cHierarchicalGrid
/// \brief ¿ùµå »ó¿¡ Á¸ÀçÇÏ´Â °´Ã¼µé °£ÀÇ Ãæµ¹ üũ¸¦ À§ÇÑ ±×¸®µå Ŭ·¡½º.
////////////////////////////////////////////////////////////////////////////////
class cHierarchicalGrid
{
public:
typedef list<cObject*> OBJECT_LIST;
private:
class cLevel;
const size_t m_MaxLevel; ///< ÃÖ´ë ·¹º§
cLevel** m_Levels; ///< ·¹º§º°·Î Á¸ÀçÇÏ´Â °´Ã¼µé
public:
/// \brief »ý¼ºÀÚ
/// \param maxLevel ÃÖ´ë ·¹º§
/// \param minCellSize ÃÖÇÏÀ§ ¼¿ÀÇ Å©±â
/// \param cellToCellRatio ·¹º§ÀÌ Çϳª ¿Ã¶ó°¥ ¶§¸¶´Ù ¼¿ÀÌ ¾ó¸¶³ª Ä¿Áö´Â°¡?
/// \param objectToCellRatio ¼¿¿¡ µé¾î°¥ ¼ö ÀÖ´Â ¿ÀºêÁ§Æ® Å©±â vs ¼¿ Å©±âÀÇ ºñÀ²
cHierarchicalGrid(size_t maxLevel=32, float minCellSize=1.0f,
float cellToCellRatio=2.0f, float objectToCellRatio=0.25f);
/// \brief ¼Ò¸êÀÚ
virtual ~cHierarchicalGrid();
public:
/// \brief °´Ã¼¸¦ Ãß°¡ÇÑ´Ù.
/// \param object Ãß°¡ÇÒ °´Ã¼
/// \return bool ¹«»çÈ÷ Ãß°¡ÇÑ °æ¿ì true, Ãæµ¹ÀÌ ÀÏ¾î³ °æ¿ì false
bool AddObject(cObject* object);
/// \brief °´Ã¼¸¦ Á¦°ÅÇÑ´Ù.
/// \param object Á¦°ÅÇÒ °´Ã¼
/// \return bool ¹«»çÈ÷ Á¦°ÅÇÑ °æ¿ì true, ÇØ´ç °´Ã¼°¡ Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì false
bool RemoveObject(cObject* object);
/// \brief ÇØ´ç °´Ã¼¿Í Ãæµ¹ÇÏ´Â °´Ã¼°¡ ÀÖ´ÂÁöÀÇ ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù.
/// \param object Ãæµ¹ üũ¸¦ ¼öÇàÇÒ °´Ã¼
/// \param epsilon Ãæµ¹ üũ½Ã »ç¿ëÇÒ ¿ÀÂ÷Çã¿ë°ª
/// \return bool Ãæµ¹ÇÏ´Â °´Ã¼°¡ Çϳª¶óµµ Á¸ÀçÇÏ´Â °æ¿ì true, ¾ø´Ù¸é false
bool CheckObject(cObject* object, float epsilon=0.0f) const;
/// \brief ÇØ´ç ÁöÁ¡¿¡ Ãæµ¹ÇÏ´Â °´Ã¼°¡ ÀÖ´ÂÁöÀÇ ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù.
/// \param position Ãæµ¹ üũ¸¦ ¼öÇàÇÒ ÁöÁ¡
/// \param radius üũÇÒ ¿µ¿ªÀÇ ¹ÝÁö¸§
/// \param epsilon Ãæµ¹ üũ½Ã »ç¿ëÇÒ ¿ÀÂ÷Çã¿ë°ª
/// \return bool Ãæµ¹ÇÏ´Â °´Ã¼°¡ Çϳª¶óµµ Á¸ÀçÇÏ´Â °æ¿ì true, ¾ø´Ù¸é false
bool CheckObject(const cPoint3D& position, float radius, float epsilon=0.0f) const;
/// \brief ÇØ´ç ¿µ¿ª ¾È¿¡ ÀÖ´Â ¸ðµç °´Ã¼µéÀ» ¹ÝȯÇÑ´Ù.
/// \param position Áß½ÉÁ¡
/// \param radius ¹Ý°æ
/// \param epsilon Ãæµ¹ üũ½Ã »ç¿ëÇÒ ¿ÀÂ÷Çã¿ë°ª
/// \param objects °´Ã¼µéÀÌ µé¾î°¥ Ä÷º¼Ç
void QueryObjects(const cPoint3D& position, float radius, float epsilon,
cHierarchicalGrid::OBJECT_LIST& objects);
private:
/// º¹»ç »ý¼º ±ÝÁö
cHierarchicalGrid(const cHierarchicalGrid&)
: m_MaxLevel(0), m_Levels(NULL) {}
/// ´ëÀÔ ±ÝÁö
cHierarchicalGrid& operator = (const cHierarchicalGrid&) { return *this; }
};
#endif
4.2 HierarchicalGrid.cpp
#include "HierarchicalGrid.h"
//#include "Hash.h"
namespace
{
/// \brief ¼¿ »ó¿¡¼ÀÇ À§Ä¡ ÇØ½¬°ªÀ» ¹ÝȯÇÑ´Ù.
/// \param pos ¿ÀºêÁ§Æ®ÀÇ ½ÇÁ¦ À§Ä¡
/// \param cellSize ¼¿ÀÇ Å©±â
/// \return DWORD ÇØ½¬°ª
DWORD GetCellPositionHash(const cPoint3D& pos, float cellSize)
{
int cell[3] = {
(int)(pos.x / cellSize),
(int)(pos.y / cellSize),
(int)(pos.z / cellSize)
};
// Àû´çÇÑ ÇØ½¬ ÇÔ¼ö¸¦ ÀÌ¿ëÇϵµ·Ï ÇÑ´Ù.
return cHash::GetPjwHash((const char*)&cell, sizeof(int)*3);
}
/// \brief ¼¿ »ó¿¡¼ÀÇ ÇØ½¬°ªÀ» ¹ÝȯÇÑ´Ù.
/// \param x ¼¿ ÁÂÇ¥
/// \param y ¼¿ ÁÂÇ¥
/// \param z ¼¿ ÁÂÇ¥
/// \return DWORD ÇØ½¬°ª
DWORD GetCellPositionHash(int x, int y, int z)
{
int cell[3] = { x, y, z };
// Àû´çÇÑ ÇØ½¬ ÇÔ¼ö¸¦ ÀÌ¿ëÇϵµ·Ï ÇÑ´Ù.
return cHash::GetPjwHash((const char*)&cell, sizeof(int)*3);
}
/// \brief µÎ ¿ÀºêÁ§Æ®°¡ Ãæµ¹ÇÏ´ÂÁöÀÇ ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù.
/// \param lhs ¿ÀºêÁ§Æ®
/// \param rhs ¿ÀºêÁ§Æ®
/// \param epsilon ¿ÀÂ÷ ¼öÁ¤°ª
/// \return bool Ãæµ¹ÇÏ´Â °æ¿ì true, ¾Æ´Ï¶ó¸é false
bool IsCollide(const cObject* lhs, const cObject* rhs, float epsilon)
{
const cPoint3D& from = lhs->GetPosition();
const cPoint3D& to = rhs->GetPosition();
float x = from.x - to.x;
float y = from.y - to.y;
float z = from.z - to.z;
float dist = sqrt( x * x + y * y + z * z );
return dist <= sqrt(lhs->GetRadius() + rhs->GetRadius() + epsilon);
}
/// \brief ÇØ´ç ¿µ¿ª¿Í ¿ÀºêÁ§Æ®°¡ Ãæµ¹ÇÏ´ÂÁöÀÇ ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù.
/// \param from ¿µ¿ª Áß½ÉÁ¡
/// \param radius ¿µ¿ª ¹ÝÁö¸§
/// \param target ¿ÀºêÁ§Æ®
/// \param epsilon ¿ÀÂ÷ ¼öÁ¤°ª
/// \return bool Ãæµ¹ÇÏ´Â °æ¿ì true, ¾Æ´Ï¶ó¸é false
bool IsCollide(const cPoint3D& from, float radius, const cObject* target, float epsilon)
{
const cPoint3D& to = target->GetPosition();
float x = from.x - to.x;
float y = from.y - to.y;
float z = from.z - to.z;
float dist = sqrt( x * x + y * y + z * z );
return dist <= sqrt(radius + target->GetRadius() + epsilon);
}
}
////////////////////////////////////////////////////////////////////////////////
/// \class cHierarchicalGrid::cLevel
/// \brief ÇϳªÀÇ ·¹º§¿¡ ´ëÇÑ °´Ã¼
////////////////////////////////////////////////////////////////////////////////
class cHierarchicalGrid::cLevel
{
private:
struct CELLREGION
{
int minX; int minY; int minZ;
int maxX; int maxY; int maxZ;
};
typedef stdext::hash_map<DWORD, cObject*> OBJECTS;
const size_t m_Level; ///< ·¹º§
const float m_CellSize; ///< °¢°¢ÀÇ ¼¿ Å©±â
const float m_MaxObjectSize; ///< ¼¿¿¡ µé¾î°¥ ¼ö ÀÖ´Â ¿ÀºêÁ§Æ®ÀÇ ÃÖ´ë Å©±â
OBJECTS m_Objects; ///< ÇöÀç ·¹º§¿¡ Á¸ÀçÇÏ´Â ¿ÀºêÁ§Æ®µé
public:
/// \brief »ý¼ºÀÚ
/// \param level ·¹º§
/// \param cellSize ¼¿ Å©±â
/// \param maxObjectSize ¼¿¿¡ µé¾î°¥ ¼ö ÀÖ´Â ¿ÀºêÁ§Æ®ÀÇ ÃÖ´ë Å©±â
cLevel(size_t level, float cellSize, float maxObjectSize)
: m_Level(level), m_CellSize(cellSize), m_MaxObjectSize(maxObjectSize)
{
}
/// \brief ¼Ò¸êÀÚ
~cLevel()
{
// ¿ÀºêÁ§Æ®´Â ´Ù¸¥ Ä÷º¼Ç¿¡ Æ÷ÇԵǾî ÀÖÀ» °ÍÀ̹ǷΠ»èÁ¦ÇÏÁö ¾Ê´Â´Ù.
}
public:
/// \brief °´Ã¼¸¦ Ãß°¡ÇÑ´Ù.
/// \param object Ãß°¡ÇÒ °´Ã¼
void AddObject(cObject* object)
{
// »èÁ¦¸¦ À§ÇÏ¿© ·¹º§°ú ÇØ½¬°ª µîÀ» ±â¾ïÇØµÐ´Ù.
object->SetGridLevel(m_Level);
object->SetGridHash(GetCellPositionHash(object->GetPosition(), m_CellSize));
// ·¹º§¿¡´Ù Ãß°¡ÇÑ´Ù.
OBJECTS::iterator itr(m_Objects.find(object->GetGridHash()));
if (itr == m_Objects.end())
{
m_Objects.insert(OBJECTS::value_type(object->GetGridHash(), object));
}
else
{
cObject* prev = itr->second;
object->SetPrev(prev);
object->SetNext(prev->GetNext());
prev->SetNext(object);
}
}
/// \brief °´Ã¼¸¦ Á¦°ÅÇÑ´Ù.
/// \param object Á¦°ÅÇÒ °´Ã¼
/// \return bool ¹«»çÈ÷ Á¦°ÅÇÑ °æ¿ì true, ÇØ´ç °´Ã¼°¡ Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì false
bool RemoveObject(cObject* object)
{
Assert(object->GetGridLevel() == m_Level);
// ·¹º§¿¡¼ ã¾Æº»´Ù.
OBJECTS::iterator itr(m_Objects.find(object->GetGridHash()));
if (itr == m_Objects.end())
{
Assert(false && "cannot find specified object");
return false;
}
// ¸®½ºÆ® Çì´õ¶ó¸é...
if ((itr->second) == object)
{
cObject* next = object->GetNext();
if (next == NULL)
{
m_Objects.erase(itr);
}
else
{
itr->second = next;
}
}
// ¸®½ºÆ® Çì´õ°¡ ¾Æ´Ï¶ó¸é...
else
{
cObject* prev = object->GetPrev();
if (prev != NULL)
prev->SetNext(object->GetNext());
cObject* next = object->GetNext();
if (next != NULL)
prev->SetPrev(object->GetPrev());
}
// Æ÷ÀÎÅÍ ÃʱâÈÇØÁØ´Ù.
object->SetPrev(NULL);
object->SetNext(NULL);
return true;
}
/// \brief ÇØ´ç °´Ã¼¿Í Ãæµ¹ÇÏ´Â °´Ã¼°¡ ÀÖ´ÂÁöÀÇ ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù.
/// \param object Ãæµ¹ üũ¸¦ ¼öÇàÇÒ °´Ã¼
/// \param epsilon Ãæµ¹ üũ½Ã »ç¿ëÇÒ ¿ÀÂ÷Çã¿ë°ª
/// \return bool Ãæµ¹ÇÏ´Â °´Ã¼°¡ Çϳª¶óµµ Á¸ÀçÇÏ´Â °æ¿ì true, ¾ø´Ù¸é false
bool CheckObject(cObject* object, float epsilon) const
{
const cPoint3D& from = object->GetPosition();
// Ã¼Å©ÇØ¾ßÇÒ ¼¿ÀÇ ¹üÀ§¸¦ °è»êÇÑ´Ù.
CELLREGION r;
GetCellRegion(from, object->GetRadius(), epsilon, r);
// ¸ðµç ¼¿À» °Ë»çÇÑ´Ù.
for (int x = r.minX; x <= r.maxX; x++)
{
for (int y = r.minY; y <= r.maxY; y++)
{
for (int z = r.minZ; z <= r.maxZ; z++)
{
DWORD hash = GetCellPositionHash(x, y, z);
// ¼¿¿¡ ¾Æ¹« °Íµµ ¾ø´Ù¸é ÆÐ½º.
OBJECTS::const_iterator itr(m_Objects.find(hash));
if (itr == m_Objects.end()) continue;
// ¼¿ ¾ÈÀÇ ¸ðµç ¿ÀºêÁ§Æ®¸¦ °Ë»çÇÑ´Ù.
cObject* current = itr->second;
while (current != NULL)
{
if (current != object && IsCollide(object, current, epsilon))
return true;
current = current->GetNext();
}
}
}
}
return false;
}
/// \brief ÇØ´ç ÁöÁ¡¿¡ Ãæµ¹ÇÏ´Â °´Ã¼°¡ ÀÖ´ÂÁöÀÇ ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù.
/// \param position Ãæµ¹ üũ¸¦ ¼öÇàÇÒ ÁöÁ¡
/// \param radius üũÇÒ ¿µ¿ªÀÇ ¹ÝÁö¸§
/// \param epsilon Ãæµ¹ üũ½Ã »ç¿ëÇÒ ¿ÀÂ÷Çã¿ë°ª
/// \return bool Ãæµ¹ÇÏ´Â °´Ã¼°¡ Çϳª¶óµµ Á¸ÀçÇÏ´Â °æ¿ì true, ¾ø´Ù¸é false
bool CheckObject(const cPoint3D& position, float radius, float epsilon) const
{
// Ã¼Å©ÇØ¾ßÇÒ ¼¿ÀÇ ¹üÀ§¸¦ °è»êÇÑ´Ù.
CELLREGION r;
GetCellRegion(position, radius, epsilon, r);
// ¸ðµç ¼¿À» °Ë»çÇÑ´Ù.
for (int x = r.minX; x <= r.maxX; x++)
{
for (int y = r.minY; y <= r.maxY; y++)
{
for (int z = r.minZ; z <= r.maxZ; z++)
{
DWORD hash = GetCellPositionHash(x, y, z);
// ¼¿¿¡ ¾Æ¹« °Íµµ ¾ø´Ù¸é ÆÐ½º.
OBJECTS::const_iterator itr(m_Objects.find(hash));
if (itr == m_Objects.end()) continue;
// ¼¿ ¾ÈÀÇ ¸ðµç ¿ÀºêÁ§Æ®¸¦ °Ë»çÇÑ´Ù.
cObject* current = itr->second;
while (current != NULL)
{
if (IsCollide(position, radius, current, epsilon))
return true;
current = current->GetNext();
}
}
}
}
return false;
}
/// \brief ÇØ´ç ¿µ¿ª ¾È¿¡ ÀÖ´Â ¸ðµç °´Ã¼µéÀ» ¹ÝȯÇÑ´Ù.
/// \param position Áß½ÉÁ¡
/// \param radius ¹Ý°æ
/// \param epsilon Ãæµ¹ üũ½Ã »ç¿ëÇÒ ¿ÀÂ÷Çã¿ë°ª
/// \param objects °´Ã¼µéÀÌ µé¾î°¥ Ä÷º¼Ç
void QueryObjects(const cPoint3D& position, float radius, float epsilon,
cHierarchicalGrid::OBJECT_LIST& objects)
{
// Ã¼Å©ÇØ¾ßÇÒ ¼¿ÀÇ ¹üÀ§¸¦ °è»êÇÑ´Ù.
CELLREGION r;
GetCellRegion(position, radius, epsilon, r);
// ¸ðµç ¼¿À» °Ë»çÇÑ´Ù.
for (int x = r.minX; x <= r.maxX; x++)
{
for (int y = r.minY; y <= r.maxY; y++)
{
for (int z = r.minZ; z <= r.maxZ; z++)
{
DWORD hash = GetCellPositionHash(x, y, z);
// ¼¿¿¡ ¾Æ¹« °Íµµ ¾ø´Ù¸é ÆÐ½º.
OBJECTS::const_iterator itr(m_Objects.find(hash));
if (itr == m_Objects.end()) continue;
// ¼¿ ¾ÈÀÇ ¸ðµç ¿ÀºêÁ§Æ®¸¦ °Ë»çÇÑ´Ù.
cObject* current = itr->second;
while (current != NULL)
{
objects.push_back(current);
current = current->GetNext();
}
}
}
}
}
private:
/// \brief ¿ÀºêÁ§Æ®ÀÇ ÁÂÇ¥¿Í Å©±â¸¦ ÀÌ¿ëÇØ Ã¼Å©ÇØ¾ßÇÒ ¼¿ÀÇ ¹üÀ§¸¦ °è»êÇÑ´Ù.
/// \param from Áß½ÉÁ¡
/// \param radius ¹Ý°æ
/// \param epsilon ¿ÀÂ÷°ª
/// \param region Ã¼Å©ÇØ¾ßÇÒ ¿µ¿ª
void GetCellRegion(const cPoint3D& from, float radius, float epsilon, CELLREGION& region) const
{
float delta = radius + m_MaxObjectSize + epsilon;
float ooSize = 1.0f / m_CellSize;
region.minX = (int)floorf((from.x - delta) * ooSize);
region.minY = (int)floorf((from.y - delta) * ooSize);
region.minZ = (int)floorf((from.z - delta) * ooSize);
region.maxX = (int)ceilf((from.x + delta) * ooSize);
region.maxY = (int)ceilf((from.y + delta) * ooSize);
region.maxZ = (int)ceilf((from.z + delta) * ooSize);
}
public:
/// \name Simple getter/setter
/// \{
size_t GetLevel() const { return m_Level; }
float GetCellSize() const { return m_CellSize; }
float GetMaxObjectSize() const { return m_MaxObjectSize; }
bool IsEmpty() const { return m_Objects.empty(); }
/// \}
};
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
/// \param maxLevel ÃÖ´ë ·¹º§
/// \param minCellSize ÃÖÇÏÀ§ ¼¿ÀÇ Å©±â
/// \param cellToCellRatio ·¹º§ÀÌ Çϳª ¿Ã¶ó°¥ ¶§¸¶´Ù ¼¿ÀÌ ¾ó¸¶³ª Ä¿Áö´Â°¡?
/// \param objectToCellRatio ¼¿¿¡ µé¾î°¥ ¼ö ÀÖ´Â ¿ÀºêÁ§Æ® Å©±â vs ¼¿ Å©±âÀÇ ºñÀ²
////////////////////////////////////////////////////////////////////////////////
cHierarchicalGrid::cHierarchicalGrid(
size_t maxLevel, float minCellSize, float cellToCellRatio, float objectToCellRatio)
: m_MaxLevel(maxLevel)
{
Assert(maxLevel > 1);
Assert(minCellSize > 0.0f);
Assert(cellToCellRatio > 1.0f);
Assert(objectToCellRatio <= 1.0f);
m_Levels = new cLevel*[m_MaxLevel];
AssertPtr(m_Levels);
float cellSize = minCellSize;
for (size_t level=0; level<m_MaxLevel; ++level, cellSize *= cellToCellRatio)
{
m_Levels[level] = new cLevel(level, cellSize, cellSize * objectToCellRatio);
AssertPtr(m_Levels[level]);
}
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ¼Ò¸êÀÚ
////////////////////////////////////////////////////////////////////////////////
cHierarchicalGrid::~cHierarchicalGrid()
{
for (size_t i=0; i<m_MaxLevel; ++i)
{
delete m_Levels[i];
}
delete [] m_Levels;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief °´Ã¼¸¦ Ãß°¡ÇÑ´Ù.
/// \param object Ãß°¡ÇÒ °´Ã¼
/// \return bool ¹«»çÈ÷ Ãß°¡ÇÑ °æ¿ì true, Ãæµ¹ÀÌ ÀÏ¾î³ °æ¿ì false
////////////////////////////////////////////////////////////////////////////////
bool cHierarchicalGrid::AddObject(cObject* object)
{
AssertPtr(object);
// ¿ÀºêÁ§Æ®ÀÇ Áö¸§À» ±¸ÇÑ´Ù.
float diameter = object->GetRadius() * 2.0f;
// ¿ÀºêÁ§Æ®¸¦ ¿ÏÀüÈ÷ °¨½Ò ¼ö ÀÖ´Â °¡Àå ³·Àº ·¹º§À» ±¸ÇÑ´Ù.
size_t level = 0;
for (level = 0; level<m_MaxLevel; ++level)
{
if (diameter < m_Levels[level]->GetMaxObjectSize())
break;
}
// ÇØ´ç ¿ÀºêÁ§Æ®¸¦ ¼ö¿ëÇÒ ¼ö ÀÖ´Â ·¹º§ÀÌ ¾ø´Ù¸é ¿¡·¯´Ù.
if (level < m_MaxLevel)
{
Assert(false && "cannot accommodate object");
return false;
}
// ·¹º§¿¡´Ù Ãß°¡ÇÑ´Ù.
m_Levels[level]->AddObject(object);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief °´Ã¼¸¦ Á¦°ÅÇÑ´Ù.
/// \param object Á¦°ÅÇÒ °´Ã¼
/// \return bool ¹«»çÈ÷ Á¦°ÅÇÑ °æ¿ì true, ÇØ´ç °´Ã¼°¡ Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì false
////////////////////////////////////////////////////////////////////////////////
bool cHierarchicalGrid::RemoveObject(cObject* object)
{
AssertPtr(object);
Assert(object->GetGridLevel() < m_MaxLevel);
// ·¹º§¿¡¼ »èÁ¦ÇÑ´Ù.
return m_Levels[object->GetGridLevel()]->RemoveObject(object);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´ç °´Ã¼¿Í Ãæµ¹ÇÏ´Â °´Ã¼°¡ ÀÖ´ÂÁöÀÇ ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù.
/// \param object Ãæµ¹ üũ¸¦ ¼öÇàÇÒ °´Ã¼
/// \param epsilon Ãæµ¹ üũ½Ã »ç¿ëÇÒ ¿ÀÂ÷Çã¿ë°ª
/// \return bool Ãæµ¹ÇÏ´Â °´Ã¼°¡ Çϳª¶óµµ Á¸ÀçÇÏ´Â °æ¿ì true, ¾ø´Ù¸é false
////////////////////////////////////////////////////////////////////////////////
bool cHierarchicalGrid::CheckObject(cObject* object, float epsilon) const
{
AssertPtr(object);
for (size_t level = 0; level < m_MaxLevel; level++)
{
if (m_Levels[level]->IsEmpty())
continue;
if (m_Levels[level]->CheckObject(object, epsilon))
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´ç °´Ã¼¿Í Ãæµ¹ÇÏ´Â °´Ã¼°¡ ÀÖ´ÂÁöÀÇ ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù.
/// \param position Ãæµ¹ üũ¸¦ ¼öÇàÇÒ ÁöÁ¡
/// \param radius üũÇÒ ¿µ¿ªÀÇ ¹ÝÁö¸§
/// \param epsilon Ãæµ¹ üũ½Ã »ç¿ëÇÒ ¿ÀÂ÷Çã¿ë°ª
/// \return bool Ãæµ¹ÇÏ´Â °´Ã¼°¡ Çϳª¶óµµ Á¸ÀçÇÏ´Â °æ¿ì true, ¾ø´Ù¸é false
////////////////////////////////////////////////////////////////////////////////
bool cHierarchicalGrid::CheckObject(const cPoint3D& position, float radius, float epsilon) const
{
for (size_t level = 0; level < m_MaxLevel; level++)
{
if (m_Levels[level]->IsEmpty())
continue;
if (m_Levels[level]->CheckObject(position, radius, epsilon))
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´ç ¿µ¿ª ¾È¿¡ ÀÖ´Â ¸ðµç °´Ã¼µéÀ» ¹ÝȯÇÑ´Ù.
/// \param position Áß½ÉÁ¡
/// \param radius ¹Ý°æ
/// \param epsilon Ãæµ¹ üũ½Ã »ç¿ëÇÒ ¿ÀÂ÷Çã¿ë°ª
/// \param objects °´Ã¼µéÀÌ µé¾î°¥ Ä÷º¼Ç
/// \return size_t Ä÷º¼Ç ¾È¿¡ µé¾î°£ °´Ã¼ÀÇ °¹¼ö
////////////////////////////////////////////////////////////////////////////////
void cHierarchicalGrid::QueryObjects(
const cPoint3D& position, float radius, float epsilon, cHierarchicalGrid::OBJECT_LIST& objects)
{
for (size_t level = 0; level < m_MaxLevel; level++)
m_Levels[level]->QueryObjects(position, radius, epsilon, objects);
}
5 ÀÀ¿ë ºÐ¾ß ¹× ÇѰèÁ¡
ÀÏ´Ü Á¤ÀûÀÎ ÁöÇü Á¤º¸ °°Àº °ÍÀ» ÀúÀåÇϱ⿡´Â ¾Ë¸ÂÁö ¾Ê´Ù. Á¤ÀûÀÎ ÁöÇü Á¤º¸´Â »ó´çÈ÷ ¾çÀÌ ¸¹°í, °í¸£°Ô ÆÛÁ® ÀÖÁöµµ ¾Ê±â ¶§¹®ÀÌ´Ù. MMORPG °ÔÀÓ ¼¹ö¿¡¼ ¿òÁ÷ÀÌ´Â °´Ã¼µéÀ» ÃßÀûÇÏ´Â Á¤µµ¿¡´Â ¾î¿ï¸± °Í °°´Ù. ¾à°£ ÀÀ¿ëÀ» Çϸé AreaOfInterestManagement¿¡µµ ¾î¶»°Ô ÀÌ¿ëÇÒ ¼ö ÀÖÀ» µí Çѵ¥...
SeriousMoin v1 (koMoinMoin 1.0a4 Modified)