diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2022-06-08 21:17:51 +0200 |
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-06-08 21:17:51 +0200 |
| commit | 9fa9dda6052d584326a68ed69fa8e8619f13b99b (patch) | |
| tree | ca044644e30d6b9d355f22ecf570020e44b938cf /crop-tool | |
| parent | 66968b083c8e2ee12819735f9aa9583192dc8091 (diff) | |
update
Diffstat (limited to 'crop-tool')
| -rw-r--r-- | crop-tool/atlas.cpp | 2 | ||||
| -rw-r--r-- | crop-tool/crop-tool.cpp | 37 | ||||
| -rw-r--r-- | crop-tool/serialize.cpp | 103 | ||||
| -rw-r--r-- | crop-tool/serialize.hpp (renamed from crop-tool/atlas.hpp) | 17 |
4 files changed, 139 insertions, 20 deletions
diff --git a/crop-tool/atlas.cpp b/crop-tool/atlas.cpp deleted file mode 100644 index 0cb6eaf8..00000000 --- a/crop-tool/atlas.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "atlas.hpp" -#include "../json.hpp" diff --git a/crop-tool/crop-tool.cpp b/crop-tool/crop-tool.cpp index 1acbc397..6de44a96 100644 --- a/crop-tool/crop-tool.cpp +++ b/crop-tool/crop-tool.cpp @@ -1,5 +1,5 @@ #include "../defs.hpp" -#include "atlas.hpp" +#include "serialize.hpp" #include <Corrade/Utility/Arguments.h> #include <Corrade/Utility/Debug.h> #include <Corrade/Utility/DebugStl.h> @@ -15,6 +15,9 @@ #include <cstring> #include <cmath> +#undef MIN +#undef MAX + #ifdef _WIN32 # define EX_OK 0 /* successful termination */ # define EX_USAGE 64 /* command line usage error */ @@ -24,18 +27,20 @@ # include <sysexits.h> #endif +#if 0 static std::string fix_path_separators(const std::filesystem::path& path) { auto str = path.string(); std::replace(str.begin(), str.end(), '\\', '/'); return str; } +#endif struct file { std::filesystem::path name; cv::Mat4b mat; - cv::Point2i offset, orig_size; + cv::Point2i offset; }; struct dir @@ -85,8 +90,6 @@ find_image_bounds(const std::filesystem::path& path, const cv::Mat4b& mat) static std::optional<file> load_file(const std::filesystem::path& filename) { - Debug{} << "load" << fix_path_separators(filename.string()); - auto mat = progn( cv::Mat mat_ = cv::imread(filename.string(), cv::IMREAD_UNCHANGED); if (mat_.empty() || mat_.type() != CV_8UC4) @@ -135,7 +138,7 @@ static std::optional<file> load_file(const std::filesystem::path& filename) cv::Mat4b resized{size}; cv::resize(mat({start, size}), resized, dest_size, 0, 0, cv::INTER_LANCZOS4); - file ret {filename, resized.clone(), start, size}; + file ret { filename, resized.clone(), offset }; return std::make_optional(std::move(ret)); } @@ -147,8 +150,6 @@ static std::optional<dir> load_directory(const std::filesystem::path& dirname) return std::nullopt; } - Debug{} << "loading" << dirname.string(); - dir ret; for (int i = 1; i <= 9999; i++) { @@ -184,15 +185,21 @@ int main(int argc, char** argv) if (auto* c = strrchr(argv[0], '/'); c && c[1]) args.setCommand(c+1); #endif - args.addOption('o', "output", "output") - .addArrayArgument("directories") + args.addOption('o', "output", "./output") + .addArgument("directory") .addOption('W', "width", "") .addOption('H', "height", "") .addOption('x', "offset") .setHelp("offset", {}, "WxH"); args.parse(argc, argv); - auto output = args.value<std::string>("output"); + std::filesystem::path output = args.value<std::string>("output"); + std::filesystem::path pathname = args.value<std::string>("directory"); std::vector<dir> dirs; + auto anim_info = anim::from_json(pathname / "atlas.json"); + + if (!anim_info) + goto usage; + if (unsigned w = args.value<unsigned>("width"); w != 0) options.width = w; if (unsigned h = args.value<unsigned>("height"); h != 0) @@ -220,12 +227,14 @@ int main(int argc, char** argv) options.offset = {x, y}; } - for (std::size_t i = 0, cnt = args.arrayValueCount("directories"); i < cnt; i++) + using anim_dir_t = std::underlying_type_t<anim_direction>; + for (auto i = (anim_dir_t)anim_direction::MIN; i < (anim_dir_t)anim_direction::MAX; i++) { - auto dir = load_directory(args.arrayValue("directories", i)); - if (!dir) + auto name = anim_direction_group::anim_direction_string((anim_direction)i); + auto result = load_directory(pathname / name); + if (!result) goto usage; - dirs.push_back(std::move(*dir)); + dirs.push_back(std::move(*result)); } return 0; diff --git a/crop-tool/serialize.cpp b/crop-tool/serialize.cpp new file mode 100644 index 00000000..8d3a5cf7 --- /dev/null +++ b/crop-tool/serialize.cpp @@ -0,0 +1,103 @@ +#include "serialize.hpp" +#include "../json.hpp" + +#include <algorithm> +#include <utility> +#include <fstream> +#include <Corrade/Utility/Debug.h> +#include <Corrade/Utility/DebugStl.h> + +using Corrade::Utility::Debug; +using Corrade::Utility::Error; + +static constexpr +std::pair<anim_direction, const char*> anim_direction_map[] = { + { anim_direction::Invalid, "x" }, + { anim_direction::N, "N" }, + { anim_direction::NE, "NE" }, + { anim_direction::E, "E" }, + { anim_direction::SE, "SE" }, + { anim_direction::S, "S" }, + { anim_direction::SW, "SW" }, + { anim_direction::W, "W" }, + { anim_direction::NW, "NW" }, +}; + +namespace nlohmann { + +template<> +struct adl_serializer<Magnum::Vector2i> final { + static void to_json(json& j, const Magnum::Vector2i& x) + { + j["x"] = x[0]; + j["y"] = x[1]; + } + + static void from_json(const json& j, Magnum::Vector2i& x) + { + j.at("x").get_to(x[0]); + j.at("y").get_to(x[1]); + } +}; + +template<> +struct adl_serializer<anim_direction> final { + static void to_json(json& j, anim_direction x) + { + auto it = std::find_if(std::cbegin(anim_direction_map), std::cend(anim_direction_map), + [=](const auto& pair) { return x == pair.first; }); + if (it != std::cend(anim_direction_map)) + j = it->second; + else + j = anim_direction_map[0].second; + } + static void from_json(const json& j, anim_direction& x) + { + std::string str = j; + auto it = std::find_if(std::cbegin(anim_direction_map), std::cend(anim_direction_map), + [&](const auto& pair) { return str == pair.second; }); + if (it != std::cend(anim_direction_map)) + x = it->first; + else + x = anim_direction::Invalid; + } +}; + +} // namespace nlohmann + +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(anim_frame, ground); +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(anim_direction_group, group, frames); +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(anim, name, nframes, actionframe, fps, directions); + +std::optional<anim> anim::from_json(const std::filesystem::path& pathname) +{ + using namespace nlohmann; + std::ifstream s; + s.exceptions(s.exceptions() | std::ios::failbit); + try { + s.open(pathname, std::ios_base::in); + } catch (const std::ios_base::failure& e) { + Error{} << "failed to open" << pathname << ":" << e.what(); + return std::nullopt; + } + anim ret; + try { + json j; + s >> j; + using nlohmann::from_json; + from_json(j, ret); + } catch (const std::exception& e) { + Error{} << "failed to parse" << pathname.string() << ":" << e.what(); + } + return std::make_optional(std::move(ret)); +} + +const char* anim_direction_group::anim_direction_string(anim_direction group) +{ + auto it = std::find_if(std::cbegin(anim_direction_map), std::cend(anim_direction_map), + [=](const auto& pair) { return group == pair.first; }); + if (it != std::cend(anim_direction_map)) + return it->second; + else + return "(unknown)"; +} diff --git a/crop-tool/atlas.hpp b/crop-tool/serialize.hpp index ad74fe4d..e93cf6f4 100644 --- a/crop-tool/atlas.hpp +++ b/crop-tool/serialize.hpp @@ -1,12 +1,15 @@ #pragma once + +#include <string> #include <array> #include <vector> +#include <optional> +#include <filesystem> #include <Magnum/Trade/ImageData.h> struct anim_frame { - Magnum::Trade::ImageData2D image; - Magnum::Vector2us ground_offset = {}; + Magnum::Vector2i ground = {}; }; enum class anim_direction : unsigned char @@ -18,14 +21,20 @@ enum class anim_direction : unsigned char struct anim_direction_group { + static const char* anim_direction_string(anim_direction group); + anim_direction group; std::vector<anim_frame> frames; - anim_direction dir = anim_direction::Invalid; + + Magnum::Vector2i ground = {}; }; struct anim { + std::string name; std::array<anim_direction_group, (unsigned)anim_direction::MAX> directions; - int num_frames = 0, action_frame = 0, fps = default_fps; + int nframes = 0, actionframe = 0, fps = default_fps; + + static std::optional<anim> from_json(const std::filesystem::path& pathname); static constexpr int default_fps = 24; }; |
