#include "OrdererSpriteSet.hpp" #include #include #include "Debug.hpp" TSE::OrdererSpriteSetChunk::OrdererSpriteSetChunk(int _chunksize, const Vector2 &_pos, SortingOrder _order) { chunksize = _chunksize; pos = _pos; order = _order; } void TSE::OrdererSpriteSetChunk::SetSprite(const Vector2 &p, const Vector2 &Spriteindex, const Vector2 &Normalindex, TileSet *set, float height, Vector2& scale) { int normalid = -1; if(Normalindex != Vector2(-1,-1)) normalid = set->GetSpriteIdAt(Normalindex.x, Normalindex.y); sprites[Vector3(p.x, p.y, height)] = {set->GetSpriteIdAt(Spriteindex.x, Spriteindex.y), normalid}; spriteScales[Vector3(p.x, p.y, height)] = scale; dirtyPositions = true; dirtySpriteIds = true; dirtyScales = true; } void TSE::OrdererSpriteSetChunk::RemoveSprite(Vector2 p, float height) { sprites.erase(Vector3(p.x, p.y, height)); } void TSE::OrdererSpriteSetChunk::SetOrdering(SortingOrder _order) { order = _order; dirtyPositions = true; dirtySpriteIds = true; } const std::vector *TSE::OrdererSpriteSetChunk::GetOrderedPositions() { if(dirtyPositions) { orderedPositions.clear(); for(auto pos : sprites) { orderedPositions.push_back(pos.first); } switch (order) { case TopLeft: std::sort(orderedPositions.begin(), orderedPositions.end(), [](const Vector3& a, const Vector3& b) { return std::tie(a.y, a.x) > std::tie(b.y, b.x); }); break; case TopRight: std::sort(orderedPositions.begin(), orderedPositions.end(), [](const Vector3& a, const Vector3& b) { if (a.y != b.y) return a.y > b.y; return a.x > b.x; }); break; case BottomLeft: std::sort(orderedPositions.begin(), orderedPositions.end(), [](const Vector3& a, const Vector3& b) { return std::tie(a.y, a.x) < std::tie(b.y, b.x); }); break; case BottomRight: std::sort(orderedPositions.begin(), orderedPositions.end(), [](const Vector3& a, const Vector3& b) { if (a.y != b.y) return a.y < b.y; return a.x > b.x; }); break; } dirtyPositions = false; } return &orderedPositions; } const std::vector *TSE::OrdererSpriteSetChunk::GetOrderedSpriteIds() { if(dirtySpriteIds) { orderedSpriteIDs.clear(); auto tmp = GetOrderedPositions(); for(auto& pos : *tmp) { auto v = sprites.find(pos); if(v != sprites.end()) orderedSpriteIDs.push_back(v->second); else orderedSpriteIDs.push_back({0,0}); } dirtySpriteIds = false; } return &orderedSpriteIDs; } const std::vector *TSE::OrdererSpriteSetChunk::GetOrderedScales() { if(dirtyScales) { orderedScales.clear(); auto tmp = GetOrderedPositions(); for(auto& pos : *tmp) { auto v = spriteScales.find(pos); if(v != spriteScales.end()) orderedScales.push_back(v->second); else orderedScales.push_back({1,1}); } dirtyScales = false; } return &orderedScales; } int TSE::OrdererSpriteSetChunk::GetChunksize() { return chunksize; } int TSE::OrdererSpriteSetChunk::GetSpriteCount() { return sprites.size(); } void TSE::OrdererSpriteSet::RemoveSprite(Vector2 p, float height) { Vector2 chunkInnerPos = LocalToChunkPos(p); Vector2 chunkIndex = p - chunkInnerPos; if(chunks.contains(chunkIndex)) chunks[chunkIndex].RemoveSprite(chunkInnerPos, height); } void TSE::OrdererSpriteSet::SetSprite(Vector2 p, Vector2 Spriteindex, float height, Vector2 scale, Vector2 Normalindex) { Vector2 chunkInnerPos = LocalToChunkPos(p); Vector2 chunkIndex = p - chunkInnerPos; // Vector2 p2 = Vector2((int)p.x % chunkSize, (int)p.y % chunkSize); // Vector2 chunkIndex = p - p2; if(!chunks.contains(chunkIndex)) { dirty = true; chunks[chunkIndex] = OrdererSpriteSetChunk(chunkSize, chunkIndex, order); } chunks[chunkIndex].SetSprite(chunkInnerPos, Spriteindex, Normalindex, set, height, scale); } TSE::OrdererSpriteSetChunk *TSE::OrdererSpriteSet::GetChunk(const Vector2 &pos) { auto chunk = chunks.find(pos); if(chunk == chunks.end()) return nullptr; return &chunks[pos]; } const std::vector *TSE::OrdererSpriteSet::GetChunkPositionsInOrder() { if(dirty) { orderedChunks.clear(); for(auto pos : chunks) { orderedChunks.push_back(pos.first); } switch (order) { case TopLeft: std::sort(orderedChunks.begin(), orderedChunks.end(), [](const Vector2& a, const Vector2& b) { if (a.y != b.y) return a.y > b.y; return a.x < b.x; }); break; case TopRight: std::sort(orderedChunks.begin(), orderedChunks.end(), [](const Vector2& a, const Vector2& b) { if (a.y != b.y) return a.y > b.y; return a.x > b.x; }); break; case BottomLeft: std::sort(orderedChunks.begin(), orderedChunks.end(), [](const Vector2& a, const Vector2& b) { if (a.y != b.y) return a.y < b.y; return a.x < b.x; }); break; case BottomRight: std::sort(orderedChunks.begin(), orderedChunks.end(), [](const Vector2& a, const Vector2& b) { if (a.y != b.y) return a.y < b.y; return a.x > b.x; }); break; } dirty = false; string poses = "["; for(auto pos : orderedChunks) { poses += pos.ToString() + ","; } poses.erase(poses.end() - 1); poses += "]"; TSE_LOG("orderedPositions: " + poses); } return &orderedChunks; } int TSE::OrdererSpriteSet::GetChunkCount() { return chunks.size(); } TSE::TileSet *TSE::OrdererSpriteSet::GetTileSet() { return set; } void TSE::OrdererSpriteSet::DirtyAll() { dirty = true; for(auto& chunk : chunks) { chunk.second.dirtyPositions = true; chunk.second.dirtySpriteIds = true; chunk.second.dirtyScales = true; } } TSE::Vector2 TSE::OrdererSpriteSet::LocalToChunkPos(const Vector2 &v) { Vector2 p = Vector2((int)v.x % chunkSize, (int)v.y % chunkSize); if(p.x < 0) p.x += chunkSize; if(p.y < 0) p.y += chunkSize; return p; }