253 lines
6.9 KiB
C++
253 lines
6.9 KiB
C++
#include "OrdererSpriteSet.hpp"
|
|
#include <algorithm>
|
|
#include <tuple>
|
|
#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::Vector3> *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::Vector2i> *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::Vector2> *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::Vector2> *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;
|
|
}
|