spritesheet hashing, navigation fix, etc.

This commit is contained in:
2026-02-06 11:52:33 -05:00
parent 64d6a1d95a
commit 85073a2ab9
14 changed files with 428 additions and 39 deletions
+1 -1
View File
@@ -39,7 +39,7 @@ namespace anm2ed::anm2
Spritesheet* spritesheet_get(int);
bool spritesheet_add(const std::filesystem::path&, const std::filesystem::path&, int&);
bool spritesheet_pack(int);
bool spritesheet_pack(int, int);
bool regions_trim(int, const std::set<int>&);
std::vector<std::string> spritesheet_labels_get();
std::vector<int> spritesheet_ids_get();
+7 -7
View File
@@ -29,9 +29,9 @@ namespace anm2ed::anm2
return true;
}
bool Anm2::spritesheet_pack(int id)
bool Anm2::spritesheet_pack(int id, int padding)
{
constexpr int PACKING_PADDING = 1;
const int packingPadding = std::max(0, padding);
struct RectI
{
@@ -256,8 +256,8 @@ namespace anm2ed::anm2
auto minPoint = glm::ivec2(glm::min(region.crop, region.crop + region.size));
auto maxPoint = glm::ivec2(glm::max(region.crop, region.crop + region.size));
auto size = glm::max(maxPoint - minPoint, glm::ivec2(1));
int packWidth = size.x + PACKING_PADDING * 2;
int packHeight = size.y + PACKING_PADDING * 2;
int packWidth = size.x + packingPadding * 2;
int packHeight = size.y + packingPadding * 2;
items.push_back({regionID, minPoint.x, minPoint.y, size.x, size.y, packWidth, packHeight});
}
@@ -290,8 +290,8 @@ namespace anm2ed::anm2
{
int sourceX = item.srcX + x;
int sourceY = item.srcY + y;
int destinationX = destinationRect.x + PACKING_PADDING + x;
int destinationY = destinationRect.y + PACKING_PADDING + y;
int destinationX = destinationRect.x + packingPadding + x;
int destinationY = destinationRect.y + packingPadding + y;
if (sourceX < 0 || sourceY < 0 || sourceX >= textureSize.x || sourceY >= textureSize.y) continue;
if (destinationX < 0 || destinationY < 0 || destinationX >= packedWidth || destinationY >= packedHeight)
@@ -312,7 +312,7 @@ namespace anm2ed::anm2
if (packedRects.contains(regionID))
{
auto& rect = packedRects.at(regionID);
region.crop = {rect.x + PACKING_PADDING, rect.y + PACKING_PADDING};
region.crop = {rect.x + packingPadding, rect.y + packingPadding};
}
return true;
+50 -4
View File
@@ -1,7 +1,9 @@
#include "spritesheet.h"
#include <algorithm>
#include <functional>
#include <ranges>
#include <string_view>
#include <vector>
#include "map_.h"
@@ -52,6 +54,7 @@ namespace anm2ed::anm2
path = path::lower_case_backslash_handle(path);
texture = Texture(path);
regionOrder.clear();
for (auto child = element->FirstChildElement("Region"); child; child = child->NextSiblingElement("Region"))
{
Region region{};
@@ -73,12 +76,16 @@ namespace anm2ed::anm2
child->QueryFloatAttribute("YPivot", &region.pivot.y);
}
regions.emplace(id, std::move(region));
regionOrder.push_back(id);
}
regionOrder.clear();
regionOrder.reserve(regions.size());
for (auto id : regions | std::views::keys)
regionOrder.push_back(id);
if (regionOrder.size() != regions.size())
{
regionOrder.clear();
regionOrder.reserve(regions.size());
for (auto id : regions | std::views::keys)
regionOrder.push_back(id);
}
}
Spritesheet::Spritesheet(const std::filesystem::path& directory, const std::filesystem::path& path)
@@ -231,4 +238,43 @@ namespace anm2ed::anm2
}
bool Spritesheet::is_valid() { return texture.is_valid(); }
uint64_t Spritesheet::hash() const
{
auto hash_combine = [](std::size_t& seed, std::size_t value)
{
seed ^= value + 0x9e3779b97f4a7c15ULL + (seed << 6) + (seed >> 2);
};
std::size_t seed{};
hash_combine(seed, std::hash<int>{}(texture.size.x));
hash_combine(seed, std::hash<int>{}(texture.size.y));
hash_combine(seed, std::hash<int>{}(texture.channels));
hash_combine(seed, std::hash<int>{}(texture.filter));
if (!texture.pixels.empty())
{
std::string_view bytes(reinterpret_cast<const char*>(texture.pixels.data()), texture.pixels.size());
hash_combine(seed, std::hash<std::string_view>{}(bytes));
}
else
{
hash_combine(seed, 0);
}
for (const auto& [id, region] : regions)
{
hash_combine(seed, std::hash<int>{}(id));
hash_combine(seed, std::hash<std::string>{}(region.name));
hash_combine(seed, std::hash<float>{}(region.crop.x));
hash_combine(seed, std::hash<float>{}(region.crop.y));
hash_combine(seed, std::hash<float>{}(region.size.x));
hash_combine(seed, std::hash<float>{}(region.size.y));
hash_combine(seed, std::hash<float>{}(region.pivot.x));
hash_combine(seed, std::hash<float>{}(region.pivot.y));
hash_combine(seed, std::hash<int>{}(static_cast<int>(region.origin)));
}
return static_cast<uint64_t>(seed);
}
}
+2
View File
@@ -5,6 +5,7 @@
#include <set>
#include <vector>
#include <string>
#include <cstdint>
#include <tinyxml2/tinyxml2.h>
#include "texture.h"
@@ -48,5 +49,6 @@ namespace anm2ed::anm2
void serialize(tinyxml2::XMLDocument&, tinyxml2::XMLElement*, int, Flags = 0);
void reload(const std::filesystem::path&, const std::filesystem::path& = {});
bool is_valid();
uint64_t hash() const;
};
}