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;
|
||||
}
|
||||
74
TSE_Core/src/BehaviourScripts/OrdererSpriteSet.hpp
Normal file
74
TSE_Core/src/BehaviourScripts/OrdererSpriteSet.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#define ORDERERSPRITESET typeid(OrdererSpriteSet).name()
|
||||
|
||||
#include "elements/BehaviourScript.hpp"
|
||||
#include "elements/Transformable.hpp"
|
||||
#include "Types.hpp"
|
||||
#include "enums/SortingOrder.hpp"
|
||||
#include "Vector2.hpp"
|
||||
#include "Vector2i.hpp"
|
||||
#include <unordered_map>
|
||||
#include "elements/Sprite.hpp"
|
||||
#include "elements/TileSet.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
struct OrdererSpriteSetChunk
|
||||
{
|
||||
private:
|
||||
std::vector<Vector3> orderedPositions;
|
||||
std::vector<Vector2i> orderedSpriteIDs;
|
||||
std::vector<Vector2> orderedScales;
|
||||
SortingOrder order;
|
||||
int chunksize;
|
||||
std::unordered_map<Vector3, Vector2i> sprites;
|
||||
std::unordered_map<Vector3, Vector2> spriteScales;
|
||||
public:
|
||||
bool dirtyPositions = true;
|
||||
bool dirtySpriteIds = true;
|
||||
bool dirtyScales = true;
|
||||
Vector2 pos;
|
||||
|
||||
OrdererSpriteSetChunk(int _chunksize = 16, const Vector2& _pos = {0,0}, SortingOrder _order = TopRight);
|
||||
void SetSprite(const Vector2& p, const Vector2& Spriteindex, const Vector2& Normalindex, TileSet* set, float height, Vector2& scale);
|
||||
void RemoveSprite(Vector2 p, float height);
|
||||
void SetOrdering(SortingOrder _order);
|
||||
const std::vector<Vector3>* GetOrderedPositions();
|
||||
const std::vector<Vector2i>* GetOrderedSpriteIds();
|
||||
const std::vector<Vector2>* GetOrderedScales();
|
||||
int GetChunksize();
|
||||
int GetSpriteCount();
|
||||
};
|
||||
|
||||
|
||||
class OrdererSpriteSet : public TSE::BehaviourScript
|
||||
{
|
||||
private:
|
||||
bool dirty = true;
|
||||
std::vector<Vector2> orderedChunks;
|
||||
Rect bounds = Rect(0,0,0,0);
|
||||
|
||||
public:
|
||||
int chunkSize = 16;
|
||||
SortingOrder order = TopRight;
|
||||
TileSet* set;
|
||||
std::unordered_map<Vector2, OrdererSpriteSetChunk> chunks;
|
||||
|
||||
void RemoveSprite(Vector2 p, float height);
|
||||
void SetSprite(Vector2 p, Vector2 Spriteindex, float height, Vector2 scale, Vector2 Normalindex = {-1,-1});
|
||||
OrdererSpriteSetChunk* GetChunk(const Vector2& pos);
|
||||
const std::vector<Vector2>* GetChunkPositionsInOrder();
|
||||
int GetChunkCount();
|
||||
TileSet* GetTileSet();
|
||||
void DirtyAll();
|
||||
|
||||
inline const char* GetName() override
|
||||
{
|
||||
return "Orderer Sprite Set";
|
||||
}
|
||||
|
||||
private:
|
||||
Vector2 LocalToChunkPos(const Vector2& v);
|
||||
};
|
||||
} // namespace TSE
|
||||
@@ -25,6 +25,8 @@ void TSE::TileMapChunk::RemoveTile(Vector2 p)
|
||||
void TSE::TileMapChunk::SetOrdering(SortingOrder _order)
|
||||
{
|
||||
order = _order;
|
||||
dirtyPositions = true;
|
||||
dirtySpriteIds = true;
|
||||
}
|
||||
|
||||
const std::vector<TSE::Vector2>* TSE::TileMapChunk::GetOrderedPositions()
|
||||
@@ -43,7 +45,7 @@ const std::vector<TSE::Vector2>* TSE::TileMapChunk::GetOrderedPositions()
|
||||
Vector2 p(x,y);
|
||||
auto v = sprites.find(p);
|
||||
if(v != sprites.end())
|
||||
orderedPositions.push_back(v->first - offset);
|
||||
orderedPositions.push_back(v->first * Vector2(nextLine.x, nextLine.y * 0.5f) + Vector2(-nextLine.x * y, nextLine.y * 0.5f * x));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -56,7 +58,7 @@ const std::vector<TSE::Vector2>* TSE::TileMapChunk::GetOrderedPositions()
|
||||
Vector2 p(x,y);
|
||||
auto v = sprites.find(p);
|
||||
if(v != sprites.end())
|
||||
orderedPositions.push_back(v->first - offset);
|
||||
orderedPositions.push_back(v->first * Vector2(nextLine.x, nextLine.y * 0.5f) + Vector2(-nextLine.x * y, nextLine.y * 0.5f * x));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -69,7 +71,7 @@ const std::vector<TSE::Vector2>* TSE::TileMapChunk::GetOrderedPositions()
|
||||
Vector2 p(x,y);
|
||||
auto v = sprites.find(p);
|
||||
if(v != sprites.end())
|
||||
orderedPositions.push_back(v->first - offset);
|
||||
orderedPositions.push_back(v->first * Vector2(nextLine.x, nextLine.y * 0.5f) + Vector2(-nextLine.x * y, nextLine.y * 0.5f * x));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -82,7 +84,7 @@ const std::vector<TSE::Vector2>* TSE::TileMapChunk::GetOrderedPositions()
|
||||
Vector2 p(x,y);
|
||||
auto v = sprites.find(p);
|
||||
if(v != sprites.end())
|
||||
orderedPositions.push_back(v->first - offset);
|
||||
orderedPositions.push_back(v->first * Vector2(nextLine.x, nextLine.y * 0.5f) + Vector2(-nextLine.x * y, nextLine.y * 0.5f * x));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -271,6 +273,7 @@ void TSE::TileMap::SetNextLineOffset(const Vector2 &offset)
|
||||
{
|
||||
chunk.nextLine = offset;
|
||||
}
|
||||
DirtyAll();
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::TileMap::GetNextLineOffset()
|
||||
@@ -278,6 +281,16 @@ TSE::Vector2 TSE::TileMap::GetNextLineOffset()
|
||||
return nextLine;
|
||||
}
|
||||
|
||||
void TSE::TileMap::DirtyAll()
|
||||
{
|
||||
dirty = true;
|
||||
for(auto& chunk : chunks)
|
||||
{
|
||||
chunk.second.dirtyPositions = true;
|
||||
chunk.second.dirtySpriteIds = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TSE::TileMap::CheckBounds(Vector2 pos)
|
||||
{
|
||||
if(pos.x > bounds.p2.x)
|
||||
@@ -305,10 +318,10 @@ TSE::Vector2 TSE::TileMap::ChunkToLocalPos(const Vector2 &v, const TileMapChunk
|
||||
|
||||
TSE::Vector2 TSE::TileMap::RealPosToTileMapPos(const Vector2 &v)
|
||||
{
|
||||
return v + nextLine * v.y;
|
||||
return v * Vector2(nextLine.x, nextLine.y * 0.5f) + Vector2(-nextLine.x * v.y, nextLine.y * 0.5f * v.x);
|
||||
}
|
||||
|
||||
TSE::Vector2 TSE::TileMap::TileMapToRealPos(const Vector2 &v)
|
||||
{
|
||||
return v - nextLine * v.y;
|
||||
return v * Vector2(nextLine.x, nextLine.y * 0.5f) + Vector2(-nextLine.x * v.y, nextLine.y * 0.5f * v.x);
|
||||
}
|
||||
|
||||
@@ -8,28 +8,21 @@
|
||||
#include "Vector2i.hpp"
|
||||
#include "elements/Sprite.hpp"
|
||||
#include "elements/TileSet.hpp"
|
||||
#include "enums/SortingOrder.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
enum SortingOrder
|
||||
{
|
||||
TopRight,
|
||||
TopLeft,
|
||||
BottomRight,
|
||||
BottomLeft,
|
||||
};
|
||||
|
||||
struct TileMapChunk
|
||||
{
|
||||
private:
|
||||
bool dirtyPositions = true;
|
||||
bool dirtySpriteIds = true;
|
||||
std::vector<Vector2> orderedPositions;
|
||||
std::vector<Vector2i> orderedSpriteIDs;
|
||||
SortingOrder order;
|
||||
int chunksize;
|
||||
std::unordered_map<Vector2, Vector2i> sprites;
|
||||
public:
|
||||
bool dirtyPositions = true;
|
||||
bool dirtySpriteIds = true;
|
||||
Vector2 nextLine;
|
||||
Vector2 pos;
|
||||
TileMapChunk(int _chunksize = 16, const Vector2& _pos = {0,0}, SortingOrder _order = TopRight);
|
||||
@@ -50,10 +43,10 @@ namespace TSE
|
||||
bool dirty = true;
|
||||
std::vector<Vector2> orderedChunks;
|
||||
Rect bounds = Rect(0,0,0,0);
|
||||
Vector2 nextLine = Vector2(-0.5f, 1.25f);
|
||||
Vector2 nextLine = Vector2(0.5f, 0.5f);
|
||||
public:
|
||||
int chunkSize = 16;
|
||||
SortingOrder order = TopRight;
|
||||
SortingOrder order = BottomRight;
|
||||
Vector2 SpriteScale = Vector2(1,1);
|
||||
TileSet* set;
|
||||
std::unordered_map<Vector2, TileMapChunk> chunks;
|
||||
@@ -69,6 +62,7 @@ namespace TSE
|
||||
Vector2 GetNextLineOffset();
|
||||
Vector2 RealPosToTileMapPos(const Vector2& v);
|
||||
Vector2 TileMapToRealPos(const Vector2& v);
|
||||
void DirtyAll();
|
||||
|
||||
inline const char* GetName() override
|
||||
{
|
||||
|
||||
12
TSE_Core/src/enums/SortingOrder.hpp
Normal file
12
TSE_Core/src/enums/SortingOrder.hpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
enum SortingOrder
|
||||
{
|
||||
TopRight,
|
||||
TopLeft,
|
||||
BottomRight,
|
||||
BottomLeft,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user