diff options
| author | kaelima <kaelima@live.se> | 2011-10-19 17:40:44 +0100 |
|---|---|---|
| committer | kaelima <kaelima@live.se> | 2011-10-19 17:40:44 +0100 |
| commit | be0b2fcf97404af624e538be96ea05892d3f41be (patch) | |
| tree | 8849332a9a8930226fea13b4e5188f4b521a70c3 /src/server/game/Grids | |
| parent | d7e019072677dd098c491986ebe8c48259d20155 (diff) | |
Core/Grid:
- Simplified CellArea calculation (Original author: SilverIce)
- Removed unused code in Cell class (Original author: SilverIce)
- Improve some Visit functions.
Diffstat (limited to 'src/server/game/Grids')
| -rwxr-xr-x | src/server/game/Grids/Cells/Cell.h | 94 | ||||
| -rw-r--r-- | src/server/game/Grids/Cells/CellImpl.h | 168 | ||||
| -rw-r--r-- | src/server/game/Grids/GridDefines.h | 7 |
3 files changed, 48 insertions, 221 deletions
diff --git a/src/server/game/Grids/Cells/Cell.h b/src/server/game/Grids/Cells/Cell.h index 12648881719..13bb0afc494 100755 --- a/src/server/game/Grids/Cells/Cell.h +++ b/src/server/game/Grids/Cells/Cell.h @@ -29,88 +29,34 @@ class Map; class WorldObject; -enum District -{ - UPPER_DISTRICT = 1, - LOWER_DISTRICT = 1 << 1, - LEFT_DISTRICT = 1 << 2, - RIGHT_DISTRICT = 1 << 3, - CENTER_DISTRICT = 1 << 4, - UPPER_LEFT_DISTRICT = (UPPER_DISTRICT | LEFT_DISTRICT), - UPPER_RIGHT_DISTRICT = (UPPER_DISTRICT | RIGHT_DISTRICT), - LOWER_LEFT_DISTRICT = (LOWER_DISTRICT | LEFT_DISTRICT), - LOWER_RIGHT_DISTRICT = (LOWER_DISTRICT | RIGHT_DISTRICT), - ALL_DISTRICT = (UPPER_DISTRICT | LOWER_DISTRICT | LEFT_DISTRICT | RIGHT_DISTRICT | CENTER_DISTRICT) -}; - struct CellArea { - CellArea() : right_offset(0), left_offset(0), upper_offset(0), lower_offset(0) {} - CellArea(int right, int left, int upper, int lower) : right_offset(right), left_offset(left), upper_offset(upper), lower_offset(lower) {} - bool operator!() const { return !right_offset && !left_offset && !upper_offset && !lower_offset; } + CellArea() {} + CellArea(CellCoord low, CellCoord high) : low_bound(low), high_bound(high) {} + + bool operator!() const { return low_bound == high_bound; } void ResizeBorders(CellCoord& begin_cell, CellCoord& end_cell) const { - begin_cell.dec_x(left_offset); - begin_cell.dec_y(lower_offset); - end_cell.inc_x(right_offset); - end_cell.inc_y(upper_offset); + begin_cell = low_bound; + end_cell = high_bound; } - int right_offset; - int left_offset; - int upper_offset; - int lower_offset; + CellCoord low_bound; + CellCoord high_bound; }; struct Cell { Cell() { data.All = 0; } - Cell(const Cell &cell) { data.All = cell.data.All; } + Cell(Cell const& cell) { data.All = cell.data.All; } explicit Cell(CellCoord const& p); explicit Cell(float x, float y); - void operator|=(Cell &cell) - { - data.Part.reserved = 0; - cell.data.Part.reserved = 0; - uint32 x, y, old_x, old_y; - Compute(x, y); - cell.Compute(old_x, old_y); - - if (std::abs(int(x-old_x)) > 1 || std::abs(int(y-old_y)) > 1) - { - data.Part.reserved = ALL_DISTRICT; - cell.data.Part.reserved = ALL_DISTRICT; - return; - } - - if (x < old_x) - { - data.Part.reserved |= LEFT_DISTRICT; - cell.data.Part.reserved |= RIGHT_DISTRICT; - } - else if (old_x < x) - { - data.Part.reserved |= RIGHT_DISTRICT; - cell.data.Part.reserved |= LEFT_DISTRICT; - } - if (y < old_y) - { - data.Part.reserved |= UPPER_DISTRICT; - cell.data.Part.reserved |= LOWER_DISTRICT; - } - else if (old_y < y) - { - data.Part.reserved |= LOWER_DISTRICT; - cell.data.Part.reserved |= UPPER_DISTRICT; - } - } - void Compute(uint32 &x, uint32 &y) const { - x = data.Part.grid_x*MAX_NUMBER_OF_CELLS + data.Part.cell_x; - y = data.Part.grid_y*MAX_NUMBER_OF_CELLS + data.Part.cell_y; + x = data.Part.grid_x * MAX_NUMBER_OF_CELLS + data.Part.cell_x; + y = data.Part.grid_y * MAX_NUMBER_OF_CELLS + data.Part.cell_y; } bool DiffCell(const Cell &cell) const @@ -135,18 +81,18 @@ struct Cell CellCoord GetCellCoord() const { return CellCoord( - data.Part.grid_x*MAX_NUMBER_OF_CELLS+data.Part.cell_x, - data.Part.grid_y*MAX_NUMBER_OF_CELLS+data.Part.cell_y); + data.Part.grid_x * MAX_NUMBER_OF_CELLS+data.Part.cell_x, + data.Part.grid_y * MAX_NUMBER_OF_CELLS+data.Part.cell_y); } - Cell& operator=(const Cell &cell) + Cell& operator=(Cell const& cell) { this->data.All = cell.data.All; return *this; } - bool operator == (const Cell &cell) const { return (data.All == cell.data.All); } - bool operator != (const Cell &cell) const { return !operator == (cell); } + bool operator == (Cell const& cell) const { return (data.All == cell.data.All); } + bool operator != (Cell const& cell) const { return !operator == (cell); } union { struct @@ -161,15 +107,13 @@ struct Cell uint32 All; } data; - template<class T, class CONTAINER> void Visit(const CellCoord&, TypeContainerVisitor<T, CONTAINER> &visitor, Map &) const; - template<class T, class CONTAINER> void Visit(const CellCoord&, TypeContainerVisitor<T, CONTAINER> &visitor, Map &, const WorldObject&, float) const; - template<class T, class CONTAINER> void Visit(const CellCoord&, TypeContainerVisitor<T, CONTAINER> &visitor, Map &, float, float, float) const; + template<class T, class CONTAINER> void Visit(CellCoord const&, TypeContainerVisitor<T, CONTAINER>& visitor, Map &, WorldObject const&, float) const; + template<class T, class CONTAINER> void Visit(CellCoord const&, TypeContainerVisitor<T, CONTAINER>& visitor, Map &, float, float, float) const; - static CellArea CalculateCellArea(const WorldObject &obj, float radius); static CellArea CalculateCellArea(float x, float y, float radius); private: - template<class T, class CONTAINER> void VisitCircle(TypeContainerVisitor<T, CONTAINER> &, Map &, const CellCoord&, const CellCoord&) const; + template<class T, class CONTAINER> void VisitCircle(TypeContainerVisitor<T, CONTAINER> &, Map &, CellCoord const&, CellCoord const&) const; }; #endif diff --git a/src/server/game/Grids/Cells/CellImpl.h b/src/server/game/Grids/Cells/CellImpl.h index 5a5be4d7358..af697b9f21d 100644 --- a/src/server/game/Grids/Cells/CellImpl.h +++ b/src/server/game/Grids/Cells/CellImpl.h @@ -46,140 +46,22 @@ inline Cell::Cell(float x, float y) data.Part.reserved = 0; } -template<class T, class CONTAINER> -inline void -Cell::Visit(const CellCoord& standing_cell, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m) const -{ - if (!standing_cell.IsCoordValid()) - return; - - uint16 district = (District)this->data.Part.reserved; - if (district == CENTER_DISTRICT) - { - m.Visit(*this, visitor); - return; - } - - // set up the cell range based on the district - CellCoord begin_cell = standing_cell; - CellCoord end_cell = standing_cell; - - switch (district) - { - case ALL_DISTRICT: - { - begin_cell.dec_x(1); begin_cell.dec_y(1); // upper left - end_cell.inc_x(1); end_cell.inc_y(1); // lower right - break; - } - case UPPER_LEFT_DISTRICT: - { - begin_cell.dec_x(1); begin_cell.dec_y(1); // upper left - break; - } - case UPPER_RIGHT_DISTRICT: - { - begin_cell.dec_y(1); // up - end_cell.inc_x(1); // right - break; - } - case LOWER_LEFT_DISTRICT: - { - begin_cell.dec_x(1); // left - end_cell.inc_y(1); // down - break; - } - case LOWER_RIGHT_DISTRICT: - { - end_cell.inc_x(1); end_cell.inc_y(1); // lower right - break; - } - case LEFT_DISTRICT: - { - begin_cell.dec_y(1); // up - end_cell.inc_x(1); end_cell.inc_y(1); // lower right - break; - } - case RIGHT_DISTRICT: - { - begin_cell.dec_x(1); begin_cell.dec_y(1); // upper left - end_cell.inc_y(1); // down - break; - } - case UPPER_DISTRICT: - { - begin_cell.dec_x(1); begin_cell.dec_y(1); // upper left - end_cell.inc_x(1); // right - break; - } - case LOWER_DISTRICT: - { - begin_cell.dec_x(1); // left - end_cell.inc_x(1); end_cell.inc_y(1); // lower right - break; - } - default: - { - ASSERT(false); - break; - } - } - - // 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++) - { - CellCoord cellCoord(x, y); - Cell r_zone(cellCoord); - r_zone.data.Part.nocreate = this->data.Part.nocreate; - m.Visit(r_zone, visitor); - } - } -} - -inline int CellHelper(const float radius) -{ - if (radius < 1.0f) - return 0; - - return (int)ceilf(radius/SIZE_OF_GRID_CELL); -} - -inline CellArea Cell::CalculateCellArea(const WorldObject &obj, float radius) -{ - return Cell::CalculateCellArea(obj.GetPositionX(), obj.GetPositionY(), radius); -} - inline CellArea Cell::CalculateCellArea(float x, float y, float radius) { if (radius <= 0.0f) - return CellArea(); - - //lets calculate object coord offsets from cell borders. - //TODO: add more correct/generic method for this task - 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); - - const float x_off = (x_offset - x_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL; - const float y_off = (y_offset - y_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL; + { + CellCoord center = Trinity::ComputeCellCoord(x, y).normalize(); + return CellArea(center, center); + } - const float tmp_diff = radius - CENTER_GRID_CELL_OFFSET; - //lets calculate upper/lower/right/left corners for cell search - int right = CellHelper(tmp_diff + x_off); - int left = CellHelper(tmp_diff - x_off); - int upper = CellHelper(tmp_diff + y_off); - int lower = CellHelper(tmp_diff - y_off); + CellCoord centerX = Trinity::ComputeCellCoord(x - radius, y - radius).normalize(); + CellCoord centerY = Trinity::ComputeCellCoord(x + radius, y + radius).normalize(); - return CellArea(right, left, upper, lower); + return CellArea(centerX, centerY); } template<class T, class CONTAINER> -inline void -Cell::Visit(const CellCoord& standing_cell, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, float radius, float x_off, float y_off) const +inline void Cell::Visit(CellCoord const& standing_cell, TypeContainerVisitor<T, CONTAINER>& visitor, Map& map, float radius, float x_off, float y_off) const { if (!standing_cell.IsCoordValid()) return; @@ -189,7 +71,7 @@ Cell::Visit(const CellCoord& standing_cell, TypeContainerVisitor<T, CONTAINER> & //maybe it is better to just return when radius <= 0.0f? if (radius <= 0.0f) { - m.Visit(*this, visitor); + map.Visit(*this, visitor); return; } //lets limit the upper value for search radius @@ -201,32 +83,28 @@ Cell::Visit(const CellCoord& standing_cell, TypeContainerVisitor<T, CONTAINER> & //if radius fits inside standing cell if (!area) { - m.Visit(*this, visitor); + map.Visit(*this, visitor); return; } - CellCoord begin_cell = standing_cell; - CellCoord end_cell = standing_cell; - - area.ResizeBorders(begin_cell, end_cell); //visit all cells, found in CalculateCellArea() //if radius is known to reach cell area more than 4x4 then we should call optimized VisitCircle //currently this technique works with MAX_NUMBER_OF_CELLS 16 and higher, with lower values //there are nothing to optimize because SIZE_OF_GRID_CELL is too big... - if (((end_cell.x_coord - begin_cell.x_coord) > 4) && ((end_cell.y_coord - begin_cell.y_coord) > 4)) + if (((area.high_bound.x_coord - area.low_bound.x_coord) > 4) && ((area.high_bound.y_coord - area.low_bound.y_coord) > 4)) { - VisitCircle(visitor, m, begin_cell, end_cell); + VisitCircle(visitor, map, area.low_bound, area.high_bound); return; } //ALWAYS visit standing cell first!!! Since we deal with small radiuses //it is very essential to call visitor for standing cell firstly... - m.Visit(*this, visitor); + map.Visit(*this, visitor); // loop the cell range - for (uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x) + for (uint32 x = area.low_bound.x_coord; x <= area.high_bound.x_coord; ++x) { - for (uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y) + for (uint32 y = area.low_bound.y_coord; y <= area.high_bound.y_coord; ++y) { CellCoord cellCoord(x, y); //lets skip standing cell since we already visited it @@ -234,24 +112,22 @@ Cell::Visit(const CellCoord& standing_cell, TypeContainerVisitor<T, CONTAINER> & { Cell r_zone(cellCoord); r_zone.data.Part.nocreate = this->data.Part.nocreate; - m.Visit(r_zone, visitor); + map.Visit(r_zone, visitor); } } } } template<class T, class CONTAINER> -inline void -Cell::Visit(const CellCoord& l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &obj, float radius) const +inline void Cell::Visit(CellCoord const& standing_cell, TypeContainerVisitor<T, CONTAINER>& visitor, Map& map, WorldObject const& 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 - Visit(l, visitor, m, radius + obj.GetObjectSize(), obj.GetPositionX(), obj.GetPositionY()); + Visit(standing_cell, visitor, map, radius + obj.GetObjectSize(), obj.GetPositionX(), obj.GetPositionY()); } template<class T, class CONTAINER> -inline void -Cell::VisitCircle(TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const CellCoord& begin_cell, const CellCoord& end_cell) const +inline void Cell::VisitCircle(TypeContainerVisitor<T, CONTAINER>& visitor, Map& map, CellCoord const& begin_cell, CellCoord const& end_cell) const { //here is an algorithm for 'filling' circum-squared octagon uint32 x_shift = (uint32)ceilf((end_cell.x_coord - begin_cell.x_coord) * 0.3f - 0.5f); @@ -267,7 +143,7 @@ Cell::VisitCircle(TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const Cel CellCoord cellCoord(x, y); Cell r_zone(cellCoord); r_zone.data.Part.nocreate = this->data.Part.nocreate; - m.Visit(r_zone, visitor); + map.Visit(r_zone, visitor); } } @@ -291,13 +167,13 @@ Cell::VisitCircle(TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const Cel CellCoord cellCoord_left(x_start - step, y); Cell r_zone_left(cellCoord_left); r_zone_left.data.Part.nocreate = this->data.Part.nocreate; - m.Visit(r_zone_left, visitor); + map.Visit(r_zone_left, visitor); //right trapezoid cell visit CellCoord cellCoord_right(x_end + step, y); Cell r_zone_right(cellCoord_right); r_zone_right.data.Part.nocreate = this->data.Part.nocreate; - m.Visit(r_zone_right, visitor); + map.Visit(r_zone_right, visitor); } } } diff --git a/src/server/game/Grids/GridDefines.h b/src/server/game/Grids/GridDefines.h index c8abc314ff0..44e2588ef81 100644 --- a/src/server/game/Grids/GridDefines.h +++ b/src/server/game/Grids/GridDefines.h @@ -128,6 +128,13 @@ struct CoordPair return x_coord < LIMIT && y_coord < LIMIT; } + CoordPair& normalize() + { + x_coord = std::min(x_coord, LIMIT - 1); + y_coord = std::min(y_coord, LIMIT - 1); + return *this; + } + uint32 x_coord; uint32 y_coord; }; |
