Graphics: Rework tilemap class (and fix its AABB)
This commit is contained in:
@@ -11,9 +11,9 @@
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
||||
#include <Nazara/Utils/Bitset.hpp>
|
||||
#include <Nazara/Utility/VertexStruct.hpp>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
@@ -71,12 +71,14 @@ namespace Nz
|
||||
private:
|
||||
Vector3ui GetTextureSize(std::size_t matIndex) const;
|
||||
inline void InvalidateVertices();
|
||||
void UpdateAABB();
|
||||
void UpdateVertices() const;
|
||||
|
||||
struct Layer
|
||||
{
|
||||
std::set<std::size_t> tiles;
|
||||
std::shared_ptr<MaterialInstance> material;
|
||||
Bitset<UInt64> enabledTiles;
|
||||
std::size_t enabledTileCount = 0; //< cached bitset popcount
|
||||
};
|
||||
|
||||
mutable std::vector<VertexStruct_XYZ_Color_UV> m_vertices;
|
||||
|
||||
@@ -20,9 +20,14 @@ namespace Nz
|
||||
|
||||
std::size_t tileIndex = tilePos.y * m_mapSize.x + tilePos.x;
|
||||
Tile& tile = m_tiles[tileIndex];
|
||||
tile.enabled = false;
|
||||
if (tile.enabled)
|
||||
{
|
||||
tile.enabled = false;
|
||||
|
||||
m_layers[tile.layerIndex].tiles.erase(tileIndex);
|
||||
Layer& layer = m_layers[tile.layerIndex];
|
||||
layer.enabledTiles.Reset(tileIndex);
|
||||
layer.enabledTileCount = layer.enabledTiles.Count();
|
||||
}
|
||||
|
||||
InvalidateVertices();
|
||||
}
|
||||
@@ -36,7 +41,10 @@ namespace Nz
|
||||
tile.enabled = false;
|
||||
|
||||
for (Layer& layer : m_layers)
|
||||
layer.tiles.clear();
|
||||
{
|
||||
layer.enabledTiles.Reset();
|
||||
layer.enabledTileCount = 0;
|
||||
}
|
||||
|
||||
InvalidateVertices();
|
||||
}
|
||||
@@ -57,23 +65,27 @@ namespace Nz
|
||||
{
|
||||
NazaraAssert(tilesPos || tileCount == 0, "Invalid tile position array with a non-zero tileCount");
|
||||
|
||||
UInt32 invalidatedLayers = 0;
|
||||
|
||||
for (std::size_t i = 0; i < tileCount; ++i)
|
||||
{
|
||||
NazaraAssert(tilesPos->x < m_mapSize.x&& tilesPos->y < m_mapSize.y, "Tile position is out of bounds");
|
||||
|
||||
std::size_t tileIndex = tilesPos->y * m_mapSize.x + tilesPos->x;
|
||||
Tile& tile = m_tiles[tileIndex];
|
||||
tile.enabled = false;
|
||||
|
||||
m_layers[tile.layerIndex].tiles.erase(tileIndex);
|
||||
if (tile.enabled)
|
||||
{
|
||||
tile.enabled = false;
|
||||
|
||||
invalidatedLayers |= 1U << tile.layerIndex;
|
||||
Layer& layer = m_layers[tile.layerIndex];
|
||||
layer.enabledTiles.Reset(tileIndex);
|
||||
}
|
||||
|
||||
tilesPos++;
|
||||
}
|
||||
|
||||
for (Layer& layer : m_layers)
|
||||
layer.enabledTileCount = layer.enabledTiles.Count();
|
||||
|
||||
if (tileCount > 0)
|
||||
InvalidateVertices();
|
||||
}
|
||||
@@ -111,19 +123,25 @@ namespace Nz
|
||||
NazaraAssert(tilePos.x < m_mapSize.x&& tilePos.y < m_mapSize.y, "Tile position is out of bounds");
|
||||
NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds");
|
||||
|
||||
UInt32 invalidatedLayers = 1U << materialIndex;
|
||||
|
||||
std::size_t tileIndex = tilePos.y * m_mapSize.x + tilePos.x;
|
||||
Tile& tile = m_tiles[tilePos.y * m_mapSize.x + tilePos.x];
|
||||
|
||||
if (!tile.enabled)
|
||||
m_layers[materialIndex].tiles.insert(tileIndex);
|
||||
{
|
||||
Layer& layer = m_layers[materialIndex];
|
||||
layer.enabledTiles.UnboundedSet(tileIndex);
|
||||
layer.enabledTileCount = layer.enabledTiles.Count();
|
||||
}
|
||||
else if (materialIndex != tile.layerIndex)
|
||||
{
|
||||
m_layers[tile.layerIndex].tiles.erase(tileIndex);
|
||||
m_layers[materialIndex].tiles.insert(tileIndex);
|
||||
Layer& oldLayer = m_layers[tile.layerIndex];
|
||||
Layer& newLayer = m_layers[tile.layerIndex];
|
||||
|
||||
invalidatedLayers |= 1U << tile.layerIndex;
|
||||
oldLayer.enabledTiles.Reset(tileIndex);
|
||||
oldLayer.enabledTileCount = oldLayer.enabledTiles.Count();
|
||||
|
||||
newLayer.enabledTiles.UnboundedSet(tileIndex);
|
||||
newLayer.enabledTileCount = newLayer.enabledTiles.Count();
|
||||
}
|
||||
|
||||
tile.enabled = true;
|
||||
@@ -180,7 +198,7 @@ namespace Nz
|
||||
NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds");
|
||||
|
||||
for (Layer& layer : m_layers)
|
||||
layer.tiles.clear();
|
||||
layer.enabledTiles.Reset();
|
||||
|
||||
std::size_t tileIndex = 0;
|
||||
for (Tile& tile : m_tiles)
|
||||
@@ -190,9 +208,11 @@ namespace Nz
|
||||
tile.textureCoords = coords;
|
||||
tile.layerIndex = materialIndex;
|
||||
|
||||
m_layers[materialIndex].tiles.insert(tileIndex++);
|
||||
m_layers[materialIndex].enabledTiles.UnboundedSet(tileIndex++);
|
||||
}
|
||||
|
||||
m_layers[materialIndex].enabledTileCount = m_layers[materialIndex].enabledTiles.Count();
|
||||
|
||||
InvalidateVertices();
|
||||
}
|
||||
|
||||
@@ -240,8 +260,6 @@ namespace Nz
|
||||
NazaraAssert(tilesPos || tileCount == 0, "Invalid tile position array with a non-zero tileCount");
|
||||
NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds");
|
||||
|
||||
UInt32 invalidatedLayers = 1U << materialIndex;
|
||||
|
||||
for (std::size_t i = 0; i < tileCount; ++i)
|
||||
{
|
||||
NazaraAssert(tilesPos->x < m_mapSize.x&& tilesPos->y < m_mapSize.y, "Tile position is out of bounds");
|
||||
@@ -250,13 +268,21 @@ namespace Nz
|
||||
Tile& tile = m_tiles[tileIndex];
|
||||
|
||||
if (!tile.enabled)
|
||||
m_layers[materialIndex].tiles.insert(tileIndex);
|
||||
{
|
||||
Layer& layer = m_layers[materialIndex];
|
||||
layer.enabledTiles.UnboundedSet(tileIndex);
|
||||
layer.enabledTileCount = layer.enabledTiles.Count();
|
||||
}
|
||||
else if (materialIndex != tile.layerIndex)
|
||||
{
|
||||
m_layers[tile.layerIndex].tiles.erase(tileIndex);
|
||||
m_layers[materialIndex].tiles.insert(tileIndex);
|
||||
Layer& oldLayer = m_layers[tile.layerIndex];
|
||||
Layer& newLayer = m_layers[tile.layerIndex];
|
||||
|
||||
invalidatedLayers |= 1U << tile.layerIndex;
|
||||
oldLayer.enabledTiles.Reset(tileIndex);
|
||||
oldLayer.enabledTileCount = oldLayer.enabledTiles.Count();
|
||||
|
||||
newLayer.enabledTiles.UnboundedSet(tileIndex);
|
||||
newLayer.enabledTileCount = newLayer.enabledTiles.Count();
|
||||
}
|
||||
|
||||
tile.enabled = true;
|
||||
@@ -266,6 +292,9 @@ namespace Nz
|
||||
tilesPos++;
|
||||
}
|
||||
|
||||
for (Layer& layer : m_layers)
|
||||
layer.enabledTileCount = layer.enabledTiles.Count();
|
||||
|
||||
if (tileCount > 0)
|
||||
InvalidateVertices();
|
||||
}
|
||||
@@ -373,6 +402,7 @@ namespace Nz
|
||||
m_origin = origin;
|
||||
|
||||
InvalidateVertices();
|
||||
UpdateAABB();
|
||||
}
|
||||
|
||||
inline void Tilemap::InvalidateVertices()
|
||||
@@ -380,6 +410,12 @@ namespace Nz
|
||||
m_shouldRebuildVertices = true;
|
||||
OnElementInvalidated(this);
|
||||
}
|
||||
|
||||
inline void Tilemap::UpdateAABB()
|
||||
{
|
||||
Vector2f size = GetSize();
|
||||
InstancedRenderable::UpdateAABB(Rectf(-m_origin * size, size));
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
||||
Reference in New Issue
Block a user