changes + more windows bs
This commit is contained in:
@@ -2,10 +2,12 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <limits>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "file_.hpp"
|
||||
#include "map_.hpp"
|
||||
#include "math_.hpp"
|
||||
#include "time_.hpp"
|
||||
#include "vector_.hpp"
|
||||
#include "working_directory.hpp"
|
||||
@@ -58,6 +60,69 @@ namespace anm2ed::anm2
|
||||
{
|
||||
Anm2::Anm2() { info.createdOn = time::get("%m/%d/%Y %I:%M:%S %p"); }
|
||||
|
||||
Frame Anm2::frame_effective(int layerId, const Frame& frame) const
|
||||
{
|
||||
auto resolved = frame;
|
||||
if (frame.regionID == -1) return resolved;
|
||||
if (!content.layers.contains(layerId)) return resolved;
|
||||
|
||||
auto spritesheet = const_cast<Anm2*>(this)->spritesheet_get(content.layers.at(layerId).spritesheetID);
|
||||
if (!spritesheet) return resolved;
|
||||
|
||||
auto regionIt = spritesheet->regions.find(frame.regionID);
|
||||
if (regionIt == spritesheet->regions.end()) return resolved;
|
||||
|
||||
resolved.crop = regionIt->second.crop;
|
||||
resolved.size = regionIt->second.size;
|
||||
resolved.pivot = regionIt->second.pivot;
|
||||
return resolved;
|
||||
}
|
||||
|
||||
vec4 Anm2::animation_rect(Animation& animation, bool isRootTransform) const
|
||||
{
|
||||
constexpr ivec2 CORNERS[4] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
|
||||
|
||||
float minX = std::numeric_limits<float>::infinity();
|
||||
float minY = std::numeric_limits<float>::infinity();
|
||||
float maxX = -std::numeric_limits<float>::infinity();
|
||||
float maxY = -std::numeric_limits<float>::infinity();
|
||||
bool any = false;
|
||||
|
||||
for (float t = 0.0f; t < (float)animation.frameNum; t += 1.0f)
|
||||
{
|
||||
mat4 transform(1.0f);
|
||||
|
||||
if (isRootTransform)
|
||||
{
|
||||
auto root = animation.rootAnimation.frame_generate(t, ROOT);
|
||||
transform *= math::quad_model_parent_get(root.position, {}, math::percent_to_unit(root.scale), root.rotation);
|
||||
}
|
||||
|
||||
for (auto& [id, layerAnimation] : animation.layerAnimations)
|
||||
{
|
||||
if (!layerAnimation.isVisible) continue;
|
||||
|
||||
auto frame = frame_effective(id, layerAnimation.frame_generate(t, LAYER));
|
||||
if (frame.size == vec2() || !frame.isVisible) continue;
|
||||
|
||||
auto layerTransform = transform * math::quad_model_get(frame.size, frame.position, frame.pivot,
|
||||
math::percent_to_unit(frame.scale), frame.rotation);
|
||||
for (auto& corner : CORNERS)
|
||||
{
|
||||
vec4 world = layerTransform * vec4(corner, 0.0f, 1.0f);
|
||||
minX = std::min(minX, world.x);
|
||||
minY = std::min(minY, world.y);
|
||||
maxX = std::max(maxX, world.x);
|
||||
maxY = std::max(maxY, world.y);
|
||||
any = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!any) return vec4(-1.0f);
|
||||
return {minX, minY, maxX - minX, maxY - minY};
|
||||
}
|
||||
|
||||
Anm2::Anm2(const std::filesystem::path& path, std::string* errorString)
|
||||
{
|
||||
XMLDocument document;
|
||||
|
||||
+3
-1
@@ -45,7 +45,7 @@ namespace anm2ed::anm2
|
||||
std::vector<std::string> spritesheet_labels_get();
|
||||
std::vector<int> spritesheet_ids_get();
|
||||
std::set<int> spritesheets_unused();
|
||||
bool spritesheets_merge(const std::set<int>&, SpritesheetMergeOrigin, bool, origin::Type);
|
||||
bool spritesheets_merge(const std::set<int>&, SpritesheetMergeOrigin, bool, bool, origin::Type);
|
||||
bool spritesheets_deserialize(const std::string&, const std::filesystem::path&, types::merge::Type type,
|
||||
std::string*);
|
||||
std::vector<std::string> region_labels_get(Spritesheet&);
|
||||
@@ -79,6 +79,8 @@ namespace anm2ed::anm2
|
||||
std::vector<std::string> animation_labels_get();
|
||||
int animations_merge(int, std::set<int>&, types::merge::Type = types::merge::APPEND, bool = true);
|
||||
bool animations_deserialize(const std::string&, int, std::set<int>&, std::string* = nullptr);
|
||||
Frame frame_effective(int, const Frame&) const;
|
||||
glm::vec4 animation_rect(Animation&, bool) const;
|
||||
|
||||
Item* item_get(int, Type, int = -1);
|
||||
Reference layer_animation_add(Reference = {}, int = -1, std::string = {}, int = 0,
|
||||
|
||||
@@ -404,7 +404,7 @@ namespace anm2ed::anm2
|
||||
}
|
||||
|
||||
bool Anm2::spritesheets_merge(const std::set<int>& ids, SpritesheetMergeOrigin mergeOrigin, bool isMakeRegions,
|
||||
origin::Type regionOrigin)
|
||||
bool isMakePrimaryRegion, origin::Type regionOrigin)
|
||||
{
|
||||
if (ids.size() < 2) return false;
|
||||
|
||||
@@ -447,19 +447,22 @@ namespace anm2ed::anm2
|
||||
base.regionOrder.push_back(id);
|
||||
}
|
||||
|
||||
auto baseLocationRegionID = map::next_id_get(base.regions);
|
||||
auto baseFilename = path::to_utf8(base.path.stem());
|
||||
auto baseLocationRegionName = baseFilename.empty() ? std::format("#{}", baseId) : baseFilename;
|
||||
auto baseLocationRegionPivot =
|
||||
regionOrigin == origin::ORIGIN_CENTER ? glm::vec2(baseTextureSize) * 0.5f : glm::vec2();
|
||||
base.regions[baseLocationRegionID] = {
|
||||
.name = baseLocationRegionName,
|
||||
.crop = {},
|
||||
.pivot = glm::ivec2(baseLocationRegionPivot),
|
||||
.size = baseTextureSize,
|
||||
.origin = regionOrigin,
|
||||
};
|
||||
base.regionOrder.push_back(baseLocationRegionID);
|
||||
if (isMakePrimaryRegion)
|
||||
{
|
||||
auto baseLocationRegionID = map::next_id_get(base.regions);
|
||||
auto baseFilename = path::to_utf8(base.path.stem());
|
||||
auto baseLocationRegionName = baseFilename.empty() ? std::format("#{}", baseId) : baseFilename;
|
||||
auto baseLocationRegionPivot =
|
||||
regionOrigin == origin::ORIGIN_CENTER ? glm::vec2(baseTextureSize) * 0.5f : glm::vec2();
|
||||
base.regions[baseLocationRegionID] = {
|
||||
.name = baseLocationRegionName,
|
||||
.crop = {},
|
||||
.pivot = glm::ivec2(baseLocationRegionPivot),
|
||||
.size = baseTextureSize,
|
||||
.origin = regionOrigin,
|
||||
};
|
||||
base.regionOrder.push_back(baseLocationRegionID);
|
||||
}
|
||||
|
||||
for (auto id : ids)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user