From b4acacf3bc4164e2286042218b0002988caa30cc Mon Sep 17 00:00:00 2001 From: fgenesis Date: Sun, 12 May 2024 17:45:01 +0200 Subject: [PATCH] Fix logic oversights that would sometimes mess up map tiles when moved to front or back --- BBGE/Tile.cpp | 30 ++++++++++++++++++------------ BBGE/Tile.h | 16 +++++++++++----- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/BBGE/Tile.cpp b/BBGE/Tile.cpp index d65864c..29daea3 100644 --- a/BBGE/Tile.cpp +++ b/BBGE/Tile.cpp @@ -23,7 +23,7 @@ TileStorage::Sizes TileStorage::stats() const return sz; } -void TileStorage::moveToFront(const size_t *indices, size_t n) +void TileStorage::moveToFront(size_t *indices, size_t n) { if(n) { @@ -32,7 +32,7 @@ void TileStorage::moveToFront(const size_t *indices, size_t n) } } -void TileStorage::moveToBack(const size_t *indices, size_t n) +void TileStorage::moveToBack(size_t *indices, size_t n) { if(n) { @@ -60,7 +60,7 @@ void TileStorage::doInteraction(const Vector& pos, const Vector& vel, float mult } } -void TileStorage::_moveToFront(const size_t *indices, size_t n) +void TileStorage::_moveToFront(size_t *indices, size_t n) { // move tile to front -> move it to the back of the list, to be rendered last aka on top of everything else @@ -68,14 +68,15 @@ void TileStorage::_moveToFront(const size_t *indices, size_t n) { TileData tile = tiles[*indices]; tiles.erase(tiles.begin() + *indices); + *indices = tiles.size(); tiles.push_back(tile); return; } - _moveToPos(size(), indices, n); + _moveToPos(MV_END, indices, n); } -void TileStorage::_moveToBack(const size_t *indices, size_t n) +void TileStorage::_moveToBack(size_t *indices, size_t n) { // move tile to back -> move it to the front of the list, to be rendered first aka underneath everything else @@ -84,28 +85,33 @@ void TileStorage::_moveToBack(const size_t *indices, size_t n) TileData tile = tiles[*indices]; tiles.erase(tiles.begin() + *indices); tiles.insert(tiles.begin(), tile); + *indices = 0; return; } - _moveToPos(0, indices, n); + _moveToPos(MV_BEGIN, indices, n); } -void TileStorage::_moveToPos(size_t where, const size_t * indices, size_t n) +void TileStorage::_moveToPos(MoveTarget where, size_t * indices, size_t n) { std::vector tmp(indices, indices + n); - std::sort(tmp.begin(), tmp.end()); - std::vector tt(n); - // sorted indices -> preserve relative order of tiles + // unsorted indices -> preserve relative order of tiles for(size_t i = 0; i < n; ++i) tt[i] = tiles[tmp[i]]; + std::sort(tmp.begin(), tmp.end()); + // SORTED indices, erasing from the BACK -> we don't get a destructive index shift - for(size_t i = tmp.size(); i --> 0; ) + for(size_t i = n; i --> 0; ) tiles.erase(tiles.begin() + tmp[i]); - tiles.insert(tiles.begin() + where, tt.begin(), tt.end()); + size_t offs = where == MV_BEGIN ? 0 : tiles.size(); + tiles.insert(tiles.begin() + offs, tt.begin(), tt.end()); + + for(size_t i = 0; i < n; ++i) + indices[i] = i + offs; } size_t TileStorage::moveToOther(TileStorage& other, const size_t *indices, size_t n) diff --git a/BBGE/Tile.h b/BBGE/Tile.h index 161c2bf..c783e19 100644 --- a/BBGE/Tile.h +++ b/BBGE/Tile.h @@ -220,8 +220,9 @@ public: TileStorage(); ~TileStorage(); - void moveToFront(const size_t *indices, size_t n); - void moveToBack(const size_t *indices, size_t n); + // Pass in old indices, updates indices where the tiles are afterwards + void moveToFront(size_t *indices, size_t n); + void moveToBack(size_t *indices, size_t n); // returns starting index of new tiles. Since new tiles are always appended at the end, // the new indices corresponding to the moved tiles are [retn .. retn+n) @@ -254,14 +255,19 @@ public: std::vector tiles; // must call refreshAll() after changing this private: + enum MoveTarget + { + MV_BEGIN, + MV_END, + }; std::vector indicesToUpdate; std::vector indicesToCollide; void _refreshTile(const TileData& t); - void _moveToFront(const size_t *indices, size_t n); - void _moveToBack(const size_t *indices, size_t n); - void _moveToPos(size_t where, const size_t *indices, size_t n); + void _moveToFront(size_t *indices, size_t n); + void _moveToBack(size_t *indices, size_t n); + void _moveToPos(MoveTarget where, size_t *indices, size_t n); TileStorage(const TileStorage&); // no-copy };