added further fixes, and upgrades
This commit is contained in:
237
TSE_Core/src/BehaviourScripts/OrdererSpriteSet.cpp
Normal file
237
TSE_Core/src/BehaviourScripts/OrdererSpriteSet.cpp
Normal file
@@ -0,0 +1,237 @@
|
||||
#include "OrdererSpriteSet.hpp"
|
||||
#include <algorithm>
|
||||
#include <tuple>
|
||||
|
||||
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;
|
||||
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)
|
||||
{
|
||||
return std::tie(a.y, a.x) > std::tie(b.y, 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)
|
||||
{
|
||||
return std::tie(a.y, a.x) < std::tie(b.y, 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user