1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-11-25 09:44:02 +00:00

Reduce Game::fillGrid() complexity from O(n^2) to O(n) when trimming

Eliminates stutter on slow machines or in debug mode when operating doors.
Also the game shouldn't freeze anymore when marking very large tiles
as obstructing.
This commit is contained in:
fgenesis 2024-11-04 04:47:34 +01:00
parent 4702cd238c
commit b59fb507ca
2 changed files with 40 additions and 23 deletions

View file

@ -421,37 +421,47 @@ void Game::fillGrid(const GridFiller& gf)
}
}
if(!obs.size()) // no obs -> nothing else to do here
return;
if (gf.trim)
{
std::vector<TileVector> obsCopy;
obsCopy.swap(obs);
// obs now empty
int minx = INT_MAX, maxx = 0, miny = INT_MAX, maxy = 0;
for(size_t i = 0; i < obs.size(); ++i)
{
const TileVector& tv = obs[i];
minx = std::min(minx, tv.x);
maxx = std::max(maxx, tv.x);
miny = std::min(miny, tv.y);
maxy = std::max(maxy, tv.y);
}
if(minx == maxx || miny == maxy)
return; // would get trimmed completely -> get out early
int sides = 0;
for (size_t i = 0; i < obsCopy.size(); i++)
Array2d<unsigned char> gr(size_t(maxx - minx) + 1, size_t(maxy - miny) + 1, 0);
for(size_t i = 0; i < obs.size(); ++i)
{
sides = 0;
for (size_t j = 0; j < obsCopy.size(); j++)
{
if (i != j)
{
if (
(obsCopy[j].x == obsCopy[i].x-1 && obsCopy[j].y == obsCopy[i].y)
|| (obsCopy[j].x == obsCopy[i].x+1 && obsCopy[j].y == obsCopy[i].y)
|| (obsCopy[j].y == obsCopy[i].y-1 && obsCopy[j].x == obsCopy[i].x)
|| (obsCopy[j].y == obsCopy[i].y+1 && obsCopy[j].x == obsCopy[i].x)
)
{
sides++;
const TileVector& tv = obs[i];
gr(size_t(tv.x - minx), size_t(tv.y - miny)) = 1;
}
if (sides>=4)
const size_t nx = gr.width() - 1;
const size_t ny = gr.height() - 1;
size_t idx = 0;
for(size_t y = 1; y < ny; ++y)
{
obs.push_back(obsCopy[i]);
break;
}
const unsigned char * const row = gr.row(y);
for(size_t x = 1; x < nx; ++x)
{
if(row[x])
{
if(row[x-1] && row[x+1] && gr(x, y-1) && gr(x, y+1))
obs[idx++] = TileVector(int(x) + minx, int(y) + miny);
}
}
}
obs.resize(idx);
}

View file

@ -16,6 +16,7 @@ protected:
public:
Array2d() : _w(0), _h(0) {}
Array2d(size_t w, size_t h) : _w(w), _h(h), _v(w*h) {}
Array2d(size_t w, size_t h, const T& def) : _w(w), _h(h), _v(w*h, def) {}
size_t width() const {return _w;}
size_t height() const {return _h;}
@ -25,6 +26,12 @@ public:
_h = h;
_v.resize(w*h);
}
void init(size_t w, size_t h, const T& def)
{
_w = w;
_h = h;
_v.resize(w*h, def);
}
void clear()
{