From d4422c4102e6a78117c685a4cab02143ddd9958e Mon Sep 17 00:00:00 2001 From: SirLynix Date: Sat, 17 Dec 2022 14:48:50 +0100 Subject: [PATCH] Graphics: Add origin to all sprite-based renderables (and made it a factor) --- .../Nazara/Graphics/LinearSlicedSprite.hpp | 8 +++-- .../Nazara/Graphics/LinearSlicedSprite.inl | 22 ++++++++++++-- include/Nazara/Graphics/SlicedSprite.hpp | 4 +++ include/Nazara/Graphics/SlicedSprite.inl | 17 +++++++++++ include/Nazara/Graphics/Sprite.hpp | 6 ++-- include/Nazara/Graphics/Sprite.inl | 8 +++-- include/Nazara/Graphics/Tilemap.hpp | 5 ++-- include/Nazara/Graphics/Tilemap.inl | 11 ++++++- src/Nazara/Graphics/LinearSlicedSprite.cpp | 29 +++++++++++-------- src/Nazara/Graphics/SlicedSprite.cpp | 18 +++++++----- src/Nazara/Graphics/Sprite.cpp | 4 +-- src/Nazara/Graphics/Tilemap.cpp | 4 +-- 12 files changed, 98 insertions(+), 38 deletions(-) diff --git a/include/Nazara/Graphics/LinearSlicedSprite.hpp b/include/Nazara/Graphics/LinearSlicedSprite.hpp index eb2d1d098..70cb5a7d7 100644 --- a/include/Nazara/Graphics/LinearSlicedSprite.hpp +++ b/include/Nazara/Graphics/LinearSlicedSprite.hpp @@ -38,8 +38,10 @@ namespace Nz const std::shared_ptr& GetMaterial(std::size_t i = 0) const override; std::size_t GetMaterialCount() const override; inline Orientation GetOrientation() const; + inline const Vector2f& GetOrigin() const; inline const Section& GetSection(std::size_t sectionIndex) const; std::size_t GetSectionCount() const; + inline float GetSize() const; inline const Rectf& GetTextureCoords() const; Vector3ui GetTextureSize() const; @@ -47,10 +49,11 @@ namespace Nz inline void SetColor(const Color& color); inline void SetMaterial(std::shared_ptr material); + inline void SetOrigin(const Vector2f& origin); inline void SetSection(std::size_t sectionIndex, float size, float textureCoord); inline void SetSectionSize(std::size_t sectionIndex, float size); inline void SetSectionTextureCoord(std::size_t sectionIndex, float textureCoord); - inline void SetSize(const Vector2f& size); + inline void SetSize(float size); inline void SetTextureCoords(const Rectf& textureCoords); inline void SetTextureRect(const Rectf& textureRect); @@ -82,7 +85,8 @@ namespace Nz Color m_color; Orientation m_orientation; Rectf m_textureCoords; - Vector2f m_size; + Vector2f m_origin; + float m_size; }; } diff --git a/include/Nazara/Graphics/LinearSlicedSprite.inl b/include/Nazara/Graphics/LinearSlicedSprite.inl index fa5e78a1c..9bff80315 100644 --- a/include/Nazara/Graphics/LinearSlicedSprite.inl +++ b/include/Nazara/Graphics/LinearSlicedSprite.inl @@ -37,6 +37,11 @@ namespace Nz return m_orientation; } + inline const Vector2f& LinearSlicedSprite::GetOrigin() const + { + return m_origin; + } + inline auto LinearSlicedSprite::GetSection(std::size_t sectionIndex) const -> const Section& { NazaraAssert(sectionIndex < m_sectionCount, "out of range section"); @@ -48,6 +53,11 @@ namespace Nz return m_sectionCount; } + inline float LinearSlicedSprite::GetSize() const + { + return m_size; + } + inline const Rectf& LinearSlicedSprite::GetTextureCoords() const { return m_textureCoords; @@ -84,6 +94,13 @@ namespace Nz } } + inline void LinearSlicedSprite::SetOrigin(const Vector2f& origin) + { + m_origin = origin; + + UpdateVertices(); + } + inline void LinearSlicedSprite::SetSection(std::size_t sectionIndex, float size, float textureCoord) { NazaraAssert(sectionIndex < m_sectionCount, "out of range section"); @@ -115,10 +132,9 @@ namespace Nz UpdateVertices(); } - inline void LinearSlicedSprite::SetSize(const Vector2f& size) + inline void LinearSlicedSprite::SetSize(float size) { - NazaraAssert(size.x >= 0.f, "width must be positive"); - NazaraAssert(size.y >= 0.f, "height must be positive"); + NazaraAssert(size >= 0.f, "size must be positive"); m_size = size; diff --git a/include/Nazara/Graphics/SlicedSprite.hpp b/include/Nazara/Graphics/SlicedSprite.hpp index a95143fe0..a5fac3868 100644 --- a/include/Nazara/Graphics/SlicedSprite.hpp +++ b/include/Nazara/Graphics/SlicedSprite.hpp @@ -33,6 +33,8 @@ namespace Nz inline const Corner& GetBottomRightCorner() const; const std::shared_ptr& GetMaterial(std::size_t i = 0) const override; std::size_t GetMaterialCount() const override; + inline const Vector2f& GetOrigin() const; + inline const Vector2f& GetSize() const; inline const Corner& GetTopLeftCorner() const; inline const Rectf& GetTextureCoords() const; Vector3ui GetTextureSize() const; @@ -42,6 +44,7 @@ namespace Nz inline void SetCornersSize(const Vector2f& topLeftSize, const Vector2f& bottomRightSize); inline void SetCornersTextureCoords(const Vector2f& topLeftTextureCoords, const Vector2f& bottomRightTextureCoords); inline void SetMaterial(std::shared_ptr material); + inline void SetOrigin(const Vector2f& origin); inline void SetSize(const Vector2f& size); inline void SetTextureCoords(const Rectf& textureCoords); inline void SetTextureRect(const Rectf& textureRect); @@ -65,6 +68,7 @@ namespace Nz Corner m_topLeftCorner; Corner m_bottomRightCorner; Rectf m_textureCoords; + Vector2f m_origin; Vector2f m_size; }; } diff --git a/include/Nazara/Graphics/SlicedSprite.inl b/include/Nazara/Graphics/SlicedSprite.inl index bc50aad93..e404b2e92 100644 --- a/include/Nazara/Graphics/SlicedSprite.inl +++ b/include/Nazara/Graphics/SlicedSprite.inl @@ -23,6 +23,16 @@ namespace Nz return m_textureCoords; } + inline const Vector2f& SlicedSprite::GetOrigin() const + { + return m_origin; + } + + inline const Vector2f& SlicedSprite::GetSize() const + { + return m_size; + } + inline auto SlicedSprite::GetTopLeftCorner() const -> const Corner& { return m_topLeftCorner; @@ -72,6 +82,13 @@ namespace Nz } } + inline void SlicedSprite::SetOrigin(const Vector2f& origin) + { + m_origin = origin; + + UpdateVertices(); + } + inline void SlicedSprite::SetSize(const Vector2f& size) { m_size = size; diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index dccfa4c88..c185d7d12 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -31,7 +31,7 @@ namespace Nz inline const Color& GetCornerColor(RectCorner corner) const; const std::shared_ptr& GetMaterial(std::size_t i = 0) const override; std::size_t GetMaterialCount() const override; - inline const Vector3f& GetOrigin() const; + inline const Vector2f& GetOrigin() const; inline const Vector2f& GetSize() const; inline const Rectf& GetTextureCoords() const; Vector3ui GetTextureSize() const; @@ -39,7 +39,7 @@ namespace Nz inline void SetColor(const Color& color); inline void SetCornerColor(RectCorner corner, const Color& color); inline void SetMaterial(std::shared_ptr material); - inline void SetOrigin(const Vector3f& origin); + inline void SetOrigin(const Vector2f& origin); inline void SetSize(const Vector2f& size); inline void SetTextureCoords(const Rectf& textureCoords); inline void SetTextureRect(const Rectf& textureRect); @@ -55,8 +55,8 @@ namespace Nz std::shared_ptr m_material; Color m_color; Rectf m_textureCoords; + Vector2f m_origin; Vector2f m_size; - Vector3f m_origin; }; } diff --git a/include/Nazara/Graphics/Sprite.inl b/include/Nazara/Graphics/Sprite.inl index de24f0a68..269ab3934 100644 --- a/include/Nazara/Graphics/Sprite.inl +++ b/include/Nazara/Graphics/Sprite.inl @@ -18,7 +18,7 @@ namespace Nz return m_cornerColor[UnderlyingCast(corner)]; } - inline const Vector3f& Sprite::GetOrigin() const + inline const Vector2f& Sprite::GetOrigin() const { return m_origin; } @@ -60,7 +60,7 @@ namespace Nz } } - inline void Sprite::SetOrigin(const Vector3f& origin) + inline void Sprite::SetOrigin(const Vector2f& origin) { m_origin = origin; @@ -99,10 +99,12 @@ namespace Nz cornerExtent[UnderlyingCast(RectCorner::LeftTop)] = Vector2f(0.f, 1.f); cornerExtent[UnderlyingCast(RectCorner::RightTop)] = Vector2f(1.f, 1.f); + Vector3f originShift = m_origin * m_size; + for (RectCorner corner : { RectCorner::LeftBottom, RectCorner::RightBottom, RectCorner::LeftTop, RectCorner::RightTop }) { vertices->color = m_color * m_cornerColor[UnderlyingCast(corner)]; - vertices->position = Vector3f(m_size * cornerExtent[UnderlyingCast(corner)], 0.f) - m_origin; + vertices->position = Vector3f(m_size * cornerExtent[UnderlyingCast(corner)], 0.f) - originShift; vertices->uv = m_textureCoords.GetCorner(corner); if (aabb.IsValid()) diff --git a/include/Nazara/Graphics/Tilemap.hpp b/include/Nazara/Graphics/Tilemap.hpp index 3488cc7f0..3a4cf3bb7 100644 --- a/include/Nazara/Graphics/Tilemap.hpp +++ b/include/Nazara/Graphics/Tilemap.hpp @@ -47,6 +47,7 @@ namespace Nz inline const Vector2ui& GetMapSize() const; const std::shared_ptr& GetMaterial(std::size_t i) const override; std::size_t GetMaterialCount() const override; + inline const Vector2f& GetOrigin() const; inline Vector2f GetSize() const; inline const Tile& GetTile(const Vector2ui& tilePos) const; inline const Vector2f& GetTileSize() const; @@ -54,7 +55,7 @@ namespace Nz inline bool IsIsometricModeEnabled() const; void SetMaterial(std::size_t matIndex, std::shared_ptr material); - inline void SetOrigin(const Vector3f& origin); + inline void SetOrigin(const Vector2f& origin); struct Tile { @@ -82,8 +83,8 @@ namespace Nz std::vector m_tiles; std::vector m_layers; Vector2ui m_mapSize; + Vector2f m_origin; Vector2f m_tileSize; - Vector3f m_origin; bool m_isometricModeEnabled; mutable bool m_shouldRebuildVertices; }; diff --git a/include/Nazara/Graphics/Tilemap.inl b/include/Nazara/Graphics/Tilemap.inl index 82845b068..629be65bc 100644 --- a/include/Nazara/Graphics/Tilemap.inl +++ b/include/Nazara/Graphics/Tilemap.inl @@ -310,6 +310,15 @@ namespace Nz return m_mapSize; } + /*! + * \brief Gets the tilemap origin + * \return Tilemap origin + */ + inline const Vector2f& Tilemap::GetOrigin() const + { + return m_origin; + } + /*! * \brief Returns the size of the tilemap in units (which is equivalent to GetMapSize() * GetTileSize()) * \return Maximum size in units occupied by this tilemap @@ -359,7 +368,7 @@ namespace Nz return m_isometricModeEnabled; } - inline void Tilemap::SetOrigin(const Vector3f& origin) + inline void Tilemap::SetOrigin(const Vector2f& origin) { m_origin = origin; diff --git a/src/Nazara/Graphics/LinearSlicedSprite.cpp b/src/Nazara/Graphics/LinearSlicedSprite.cpp index df2c4caa3..8c35d54a6 100644 --- a/src/Nazara/Graphics/LinearSlicedSprite.cpp +++ b/src/Nazara/Graphics/LinearSlicedSprite.cpp @@ -18,7 +18,8 @@ namespace Nz m_color(Color::White), m_orientation(orientation), m_textureCoords(0.f, 0.f, 1.f, 1.f), - m_size(64.f, 64.f) + m_origin(0.f, 0.f), + m_size(64.f) { UpdateVertices(); } @@ -74,16 +75,20 @@ namespace Nz void LinearSlicedSprite::UpdateVertices() { - VertexStruct_XYZ_Color_UV* vertices = m_vertices.data(); + float totalSectionSize = 0.f; + for (const Section& section : m_sections) + totalSectionSize += std::max(section.size, 0.f); - Vector3f origin = Vector3f::Zero(); + Vector2f originShift = m_origin * ((m_orientation == Orientation::Horizontal) ? Vector2f(totalSectionSize, m_size) : Vector2f(m_size, totalSectionSize)); + + Vector3f topLeftCorner = -originShift; Vector2f topLeftUV = m_textureCoords.GetCorner(RectCorner::LeftTop); m_spriteCount = 0; - for (std::size_t i = 0; i < m_sectionCount; ++i) + VertexStruct_XYZ_Color_UV* vertices = m_vertices.data(); + for (const Section& section : m_sections) { - const auto& section = m_sections[i]; if (section.size <= 0.f) continue; @@ -93,37 +98,37 @@ namespace Nz if (m_orientation == Orientation::Horizontal) { dir = Vector2(1.f, 0.f); - size = Vector2f(section.size, m_size.y); + size = Vector2f(section.size, m_size); texCoords = Vector2f(section.textureCoord, m_textureCoords.height); } else { dir = Vector2(0.f, 1.f); - size = Vector2f(m_size.x, section.size); + size = Vector2f(m_size, section.size); texCoords = Vector2f(m_textureCoords.width, section.textureCoord); } vertices->color = m_color; - vertices->position = origin; + vertices->position = topLeftCorner; vertices->uv = topLeftUV; vertices++; vertices->color = m_color; - vertices->position = origin + size.x * Vector3f::Right(); + vertices->position = topLeftCorner + size.x * Vector3f::Right(); vertices->uv = topLeftUV + Vector2f(texCoords.x, 0.f); vertices++; vertices->color = m_color; - vertices->position = origin + size.y * Vector3f::Up(); + vertices->position = topLeftCorner + size.y * Vector3f::Up(); vertices->uv = topLeftUV + Vector2f(0.f, texCoords.y); vertices++; vertices->color = m_color; - vertices->position = origin + size.x * Vector3f::Right() + size.y * Vector3f::Up(); + vertices->position = topLeftCorner + size.x * Vector3f::Right() + size.y * Vector3f::Up(); vertices->uv = topLeftUV + Vector2f(texCoords.x, texCoords.y); vertices++; - origin += dir * section.size; + topLeftCorner += dir * section.size; topLeftUV += dir * section.textureCoord; m_spriteCount++; } diff --git a/src/Nazara/Graphics/SlicedSprite.cpp b/src/Nazara/Graphics/SlicedSprite.cpp index 1323f6fe0..3948afa66 100644 --- a/src/Nazara/Graphics/SlicedSprite.cpp +++ b/src/Nazara/Graphics/SlicedSprite.cpp @@ -15,6 +15,7 @@ namespace Nz m_material(std::move(material)), m_color(Color::White), m_textureCoords(0.f, 0.f, 1.f, 1.f), + m_origin(0.f, 0.f), m_size(64.f, 64.f) { UpdateVertices(); @@ -98,7 +99,8 @@ namespace Nz m_bottomRightCorner.textureCoords.y * m_textureCoords.height }; - Vector3f origin = Vector3f::Zero(); + Vector3f originShift = m_origin * m_size; + Vector3f topLeftCorner = -originShift; Vector2f topLeftUV = m_textureCoords.GetCorner(RectCorner::LeftTop); m_spriteCount = 0; @@ -113,36 +115,36 @@ namespace Nz if (width > 0.f) { vertices->color = m_color; - vertices->position = origin; + vertices->position = topLeftCorner; vertices->uv = topLeftUV; vertices++; vertices->color = m_color; - vertices->position = origin + width * Vector3f::Right(); + vertices->position = topLeftCorner + width * Vector3f::Right(); vertices->uv = topLeftUV + Vector2f(texCoordsX[x], 0.f); vertices++; vertices->color = m_color; - vertices->position = origin + height * Vector3f::Up(); + vertices->position = topLeftCorner + height * Vector3f::Up(); vertices->uv = topLeftUV + Vector2f(0.f, texCoordsY[y]); vertices++; vertices->color = m_color; - vertices->position = origin + width * Vector3f::Right() + height * Vector3f::Up(); + vertices->position = topLeftCorner + width * Vector3f::Right() + height * Vector3f::Up(); vertices->uv = topLeftUV + Vector2f(texCoordsX[x], texCoordsY[y]); vertices++; - origin.x += width; + topLeftCorner.x += width; m_spriteCount++; } topLeftUV.x += texCoordsX[x]; } - origin.y += height; + topLeftCorner.y += height; } - origin.x = 0; + topLeftCorner.x = -originShift.x; topLeftUV.x = m_textureCoords.x; topLeftUV.y += texCoordsY[y]; diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index e9f1428a1..1b47a2c68 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -16,8 +16,8 @@ namespace Nz m_material(std::move(material)), m_color(Color::White), m_textureCoords(0.f, 0.f, 1.f, 1.f), - m_size(64.f, 64.f), - m_origin(0.f, 0.f, 0.f) + m_origin(0.f, 0.f), + m_size(64.f, 64.f) { m_cornerColor.fill(Color::White); diff --git a/src/Nazara/Graphics/Tilemap.cpp b/src/Nazara/Graphics/Tilemap.cpp index 4bc9d6b1e..a82adaba7 100644 --- a/src/Nazara/Graphics/Tilemap.cpp +++ b/src/Nazara/Graphics/Tilemap.cpp @@ -27,6 +27,7 @@ namespace Nz m_layers(materialCount), m_mapSize(mapSize), m_tileSize(tileSize), + m_origin(0.f, 0.f), m_isometricModeEnabled(false), m_shouldRebuildVertices(false) { @@ -120,9 +121,8 @@ namespace Nz m_vertices.resize(spriteCount * 4); VertexStruct_XYZ_Color_UV* vertexPtr = reinterpret_cast(m_vertices.data()); - Vector3f originShift = m_origin * GetSize(); - float topCorner = m_tileSize.y * (m_mapSize.y - 1); + Vector3f originShift = m_origin * GetSize(); for (const Layer& layer : m_layers) {