update cell search methtod (visiting grids by coords)

the old way will miss the grids when non standart cell size used

--HG--
branch : trunk
This commit is contained in:
silver1ce
2010-01-05 20:34:50 +02:00
parent 082e7bac47
commit 55d9ff7e35
2 changed files with 15 additions and 56 deletions

View File

@@ -169,6 +169,7 @@ struct TRINITY_DLL_DECL Cell
template<class LOCK_TYPE, class T, class CONTAINER> void Visit(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &visitor, Map &, float radius, float x_off, float y_off) const;
static CellArea CalculateCellArea(const WorldObject &obj, float radius);
static CellArea CalculateCellArea(float x, float y, float radius);
private:
template<class LOCK_TYPE, class T, class CONTAINER> void VisitCircle(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &, Map &, const CellPair& , const CellPair& ) const;

View File

@@ -132,54 +132,6 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
}
}
template<class LOCK_TYPE,class T, class CONTAINER>
inline void
Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, float radius, float x_off, float y_off) const
{
const CellPair &standing_cell = l.i_cellPair;
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
return;
int left = 0, right = 0, upper = 0, lower = 0;
// Origin = (CENTER_GRID_CELL_OFFSET, CENTER_GRID_CELL_OFFSET)
if(CENTER_GRID_CELL_OFFSET - x_off < radius)
++right;
if(CENTER_GRID_CELL_OFFSET + x_off < radius)
++left;
if(CENTER_GRID_CELL_OFFSET - y_off < radius)
++upper;
if(CENTER_GRID_CELL_OFFSET + y_off < radius)
++lower;
if(!left && !right && !upper && !lower)
{
m.Visit(l, visitor);
return;
}
CellPair begin_cell = standing_cell;
CellPair end_cell = standing_cell;
begin_cell << left; //note: need change << if left > 1
begin_cell -= lower;
end_cell >> right;
end_cell += upper;
// loop the cell range
for (uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++)
{
for (uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; y++)
{
CellPair cell_pair(x,y);
Cell r_zone(cell_pair);
r_zone.data.Part.nocreate = l->data.Part.nocreate;
CellLock<LOCK_TYPE> lock(r_zone, cell_pair);
m.Visit(lock, visitor);
}
}
}
inline int CellHelper(const float radius)
{
if(radius < 1.0f)
@@ -188,18 +140,15 @@ inline int CellHelper(const float radius)
return (int)ceilf(radius/SIZE_OF_GRID_CELL);
}
inline CellArea Cell::CalculateCellArea(const WorldObject &obj, float radius)
inline CellArea Cell::CalculateCellArea(float x, float y, float radius)
{
if(radius <= 0.0f)
return CellArea();
//we should increase search radius by object's radius, otherwise
//we could have problems with huge creatures, which won't attack nearest players etc
radius += obj.GetObjectSize();
//lets calculate object coord offsets from cell borders.
//TODO: add more correct/generic method for this task
const float x_offset = (obj.GetPositionX() - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
const float y_offset = (obj.GetPositionY() - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
const float x_offset = (x - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
const float y_offset = (y - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
const float x_val = floor(x_offset + CENTER_GRID_CELL_ID + 0.5f);
const float y_val = floor(y_offset + CENTER_GRID_CELL_ID + 0.5f);
@@ -219,7 +168,7 @@ inline CellArea Cell::CalculateCellArea(const WorldObject &obj, float radius)
template<class LOCK_TYPE, class T, class CONTAINER>
inline void
Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &obj, float radius) const
Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, float radius, float x_off, float y_off) const
{
const CellPair &standing_cell = l.i_cellPair;
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
@@ -238,7 +187,7 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
radius = 333.0f;
//lets calculate object coord offsets from cell borders.
CellArea area = Cell::CalculateCellArea(obj, radius);
CellArea area = Cell::CalculateCellArea(x_off, y_off, radius);
//if radius fits inside standing cell
if (!area)
{
@@ -282,6 +231,15 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
}
}
template<class LOCK_TYPE, class T, class CONTAINER>
inline void
Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &obj, float radius) const
{
//we should increase search radius by object's radius, otherwise
//we could have problems with huge creatures, which won't attack nearest players etc
Cell::Visit(l, visitor, m, radius + obj.GetObjectSize(), obj.GetPositionX(), obj.GetPositionY());
}
template<class LOCK_TYPE, class T, class CONTAINER>
inline void
Cell::VisitCircle(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const CellPair& begin_cell, const CellPair& end_cell) const