Mega Region Update.
This commit is contained in:
+107
-28
@@ -1,11 +1,13 @@
|
||||
#include "spritesheet.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <ranges>
|
||||
#include <vector>
|
||||
|
||||
#include "map_.h"
|
||||
#include "path_.h"
|
||||
#include "working_directory.h"
|
||||
#include "xml_.h"
|
||||
#include "map_.h"
|
||||
|
||||
using namespace anm2ed::resource;
|
||||
using namespace anm2ed::util;
|
||||
@@ -14,6 +16,31 @@ using namespace tinyxml2;
|
||||
|
||||
namespace anm2ed::anm2
|
||||
{
|
||||
namespace
|
||||
{
|
||||
const char* origin_to_string(Spritesheet::Region::Origin origin)
|
||||
{
|
||||
switch (origin)
|
||||
{
|
||||
case Spritesheet::Region::TOP_LEFT:
|
||||
return "TopLeft";
|
||||
case Spritesheet::Region::ORIGIN_CENTER:
|
||||
return "Center";
|
||||
case Spritesheet::Region::CUSTOM:
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Spritesheet::Region::Origin origin_from_string(const char* originString)
|
||||
{
|
||||
if (!originString) return Spritesheet::Region::CUSTOM;
|
||||
if (std::string(originString) == "TopLeft") return Spritesheet::Region::TOP_LEFT;
|
||||
if (std::string(originString) == "Center") return Spritesheet::Region::ORIGIN_CENTER;
|
||||
return Spritesheet::Region::CUSTOM;
|
||||
}
|
||||
}
|
||||
|
||||
Spritesheet::Spritesheet(XMLElement* element, int& id)
|
||||
{
|
||||
if (!element) return;
|
||||
@@ -31,14 +58,27 @@ namespace anm2ed::anm2
|
||||
int id{};
|
||||
child->QueryIntAttribute("Id", &id);
|
||||
xml::query_string_attribute(child, "Name", ®ion.name);
|
||||
child->QueryFloatAttribute("CropX", ®ion.crop.x);
|
||||
child->QueryFloatAttribute("CropY", ®ion.crop.y);
|
||||
child->QueryFloatAttribute("PivotX", ®ion.pivot.x);
|
||||
child->QueryFloatAttribute("PivotY", ®ion.pivot.y);
|
||||
child->QueryFloatAttribute("XCrop", ®ion.crop.x);
|
||||
child->QueryFloatAttribute("YCrop", ®ion.crop.y);
|
||||
child->QueryFloatAttribute("Width", ®ion.size.x);
|
||||
child->QueryFloatAttribute("Height", ®ion.size.y);
|
||||
region.origin = origin_from_string(child->Attribute("Origin"));
|
||||
if (region.origin == Spritesheet::Region::TOP_LEFT)
|
||||
region.pivot = {};
|
||||
else if (region.origin == Spritesheet::Region::ORIGIN_CENTER)
|
||||
region.pivot = {(int)(region.size.x / 2.0f), (int)(region.size.y / 2.0f)};
|
||||
else
|
||||
{
|
||||
child->QueryFloatAttribute("XPivot", ®ion.pivot.x);
|
||||
child->QueryFloatAttribute("YPivot", ®ion.pivot.y);
|
||||
}
|
||||
regions.emplace(id, std::move(region));
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -49,32 +89,50 @@ namespace anm2ed::anm2
|
||||
texture = Texture(this->path);
|
||||
}
|
||||
|
||||
XMLElement* Spritesheet::to_element(XMLDocument& document, int id)
|
||||
XMLElement* Spritesheet::to_element(XMLDocument& document, int id, Flags flags)
|
||||
{
|
||||
auto element = document.NewElement("Spritesheet");
|
||||
element->SetAttribute("Id", id);
|
||||
auto pathString = path::to_utf8(path);
|
||||
element->SetAttribute("Path", pathString.c_str());
|
||||
|
||||
for (auto [i, region] : regions)
|
||||
if (!has_flag(flags, NO_REGIONS))
|
||||
{
|
||||
auto regionElement = element->InsertNewChildElement("Region");
|
||||
regionElement->SetAttribute("Id", i);
|
||||
regionElement->SetAttribute("Name", region.name.c_str());
|
||||
regionElement->SetAttribute("CropX", region.crop.x);
|
||||
regionElement->SetAttribute("CropY", region.crop.y);
|
||||
regionElement->SetAttribute("PivotX", region.pivot.x);
|
||||
regionElement->SetAttribute("PivotY", region.pivot.y);
|
||||
regionElement->SetAttribute("Width", region.size.x);
|
||||
regionElement->SetAttribute("Height", region.size.y);
|
||||
if (regionOrder.size() != regions.size())
|
||||
{
|
||||
regionOrder.clear();
|
||||
regionOrder.reserve(regions.size());
|
||||
for (auto id : regions | std::views::keys)
|
||||
regionOrder.push_back(id);
|
||||
}
|
||||
|
||||
for (auto id : regionOrder)
|
||||
{
|
||||
if (!regions.contains(id)) continue;
|
||||
auto& region = regions.at(id);
|
||||
auto regionElement = element->InsertNewChildElement("Region");
|
||||
regionElement->SetAttribute("Id", id);
|
||||
regionElement->SetAttribute("Name", region.name.c_str());
|
||||
regionElement->SetAttribute("XCrop", region.crop.x);
|
||||
regionElement->SetAttribute("YCrop", region.crop.y);
|
||||
regionElement->SetAttribute("Width", region.size.x);
|
||||
regionElement->SetAttribute("Height", region.size.y);
|
||||
if (auto originString = origin_to_string(region.origin); originString)
|
||||
regionElement->SetAttribute("Origin", originString);
|
||||
else
|
||||
{
|
||||
regionElement->SetAttribute("XPivot", region.pivot.x);
|
||||
regionElement->SetAttribute("YPivot", region.pivot.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
void Spritesheet::serialize(XMLDocument& document, XMLElement* parent, int id)
|
||||
void Spritesheet::serialize(XMLDocument& document, XMLElement* parent, int id, Flags flags)
|
||||
{
|
||||
parent->InsertEndChild(to_element(document, id));
|
||||
parent->InsertEndChild(to_element(document, id, flags));
|
||||
}
|
||||
|
||||
std::string Spritesheet::to_string(int id)
|
||||
@@ -93,12 +151,17 @@ namespace anm2ed::anm2
|
||||
auto& region = regions.at(id);
|
||||
element->SetAttribute("Id", id);
|
||||
element->SetAttribute("Name", region.name.c_str());
|
||||
element->SetAttribute("CropX", region.crop.x);
|
||||
element->SetAttribute("CropY", region.crop.y);
|
||||
element->SetAttribute("PivotX", region.pivot.x);
|
||||
element->SetAttribute("PivotY", region.pivot.y);
|
||||
element->SetAttribute("XCrop", region.crop.x);
|
||||
element->SetAttribute("YCrop", region.crop.y);
|
||||
element->SetAttribute("Width", region.size.x);
|
||||
element->SetAttribute("Height", region.size.y);
|
||||
if (auto originString = origin_to_string(region.origin); originString)
|
||||
element->SetAttribute("Origin", originString);
|
||||
else
|
||||
{
|
||||
element->SetAttribute("XPivot", region.pivot.x);
|
||||
element->SetAttribute("YPivot", region.pivot.y);
|
||||
}
|
||||
document.InsertEndChild(element);
|
||||
|
||||
return xml::document_to_string(document);
|
||||
@@ -118,20 +181,30 @@ namespace anm2ed::anm2
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto element = document.FirstChildElement("Region"); element; element = element->NextSiblingElement("Region"))
|
||||
for (auto element = document.FirstChildElement("Region"); element;
|
||||
element = element->NextSiblingElement("Region"))
|
||||
{
|
||||
Region region{};
|
||||
element->QueryIntAttribute("Id", &id);
|
||||
xml::query_string_attribute(element, "Name", ®ion.name);
|
||||
element->QueryFloatAttribute("CropX", ®ion.crop.x);
|
||||
element->QueryFloatAttribute("CropY", ®ion.crop.y);
|
||||
element->QueryFloatAttribute("PivotX", ®ion.pivot.x);
|
||||
element->QueryFloatAttribute("PivotY", ®ion.pivot.y);
|
||||
element->QueryFloatAttribute("XCrop", ®ion.crop.x);
|
||||
element->QueryFloatAttribute("YCrop", ®ion.crop.y);
|
||||
element->QueryFloatAttribute("Width", ®ion.size.x);
|
||||
element->QueryFloatAttribute("Height", ®ion.size.y);
|
||||
region.origin = origin_from_string(element->Attribute("Origin"));
|
||||
if (region.origin == Spritesheet::Region::TOP_LEFT)
|
||||
region.pivot = {};
|
||||
else if (region.origin == Spritesheet::Region::ORIGIN_CENTER)
|
||||
region.pivot = glm::ivec2(region.size / 2.0f);
|
||||
else
|
||||
{
|
||||
element->QueryFloatAttribute("XPivot", ®ion.pivot.x);
|
||||
element->QueryFloatAttribute("YPivot", ®ion.pivot.y);
|
||||
}
|
||||
|
||||
if (type == merge::APPEND) id = map::next_id_get(regions);
|
||||
regions[id] = std::move(region);
|
||||
if (std::find(regionOrder.begin(), regionOrder.end(), id) == regionOrder.end()) regionOrder.push_back(id);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -149,7 +222,13 @@ namespace anm2ed::anm2
|
||||
return texture.write_png(this->path);
|
||||
}
|
||||
|
||||
void Spritesheet::reload(const std::filesystem::path& directory) { *this = Spritesheet(directory, this->path); }
|
||||
void Spritesheet::reload(const std::filesystem::path& directory, const std::filesystem::path& path)
|
||||
{
|
||||
WorkingDirectory workingDirectory(directory);
|
||||
this->path = !path.empty() ? path::make_relative(path) : this->path;
|
||||
this->path = path::lower_case_backslash_handle(this->path);
|
||||
texture = Texture(this->path);
|
||||
}
|
||||
bool Spritesheet::is_valid() { return texture.is_valid(); }
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user