diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2022-09-30 18:48:50 +0200 |
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-09-30 18:50:32 +0200 |
| commit | 5c9863cf0998b5f1b6107ce09b54cd3e8b484221 (patch) | |
| tree | 7ca268c80a0ec7ac0c1b815d984cf11309b96840 /tile-tool | |
| parent | d3a29055d8b1dce89c77af0988ea840e949d2450 (diff) | |
.
Diffstat (limited to 'tile-tool')
| -rw-r--r-- | tile-tool/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | tile-tool/big-atlas.cpp | 67 | ||||
| -rw-r--r-- | tile-tool/big-atlas.hpp | 33 | ||||
| -rw-r--r-- | tile-tool/tile-tool.cpp | 34 |
4 files changed, 144 insertions, 0 deletions
diff --git a/tile-tool/CMakeLists.txt b/tile-tool/CMakeLists.txt new file mode 100644 index 00000000..8f148751 --- /dev/null +++ b/tile-tool/CMakeLists.txt @@ -0,0 +1,10 @@ +find_package(OpenCV QUIET REQUIRED COMPONENTS core imgcodecs imgproc) +set(self "${PROJECT_NAME}-tile-tool") + +include_directories(SYSTEM PRIVATE ${OpenCV_INCLUDE_DIRS}) +link_libraries(Corrade::Utility) +link_libraries(${PROJECT_NAME}-tile) + +file(GLOB sources "*.cpp" CONFIGURE_ARGS) +add_executable(${self} ${sources}) +install(TARGETS ${self} RUNTIME DESTINATION "bin") diff --git a/tile-tool/big-atlas.cpp b/tile-tool/big-atlas.cpp new file mode 100644 index 00000000..a9f877bd --- /dev/null +++ b/tile-tool/big-atlas.cpp @@ -0,0 +1,67 @@ +#undef NDEBUG + +#include "big-atlas.hpp" +#include <cassert> +#include <filesystem> +#include <Corrade/Utility/DebugStl.h> +#include <opencv2/imgproc/imgproc.hpp> +#include <opencv2/imgcodecs/imgcodecs.hpp> + +std::vector<big_atlas_frame> big_atlas_builder::add_atlas(const std::filesystem::path& filename) +{ + using Corrade::Utility::Error; + std::vector<big_atlas_frame> ret; + cv::Mat mat = cv::imread(filename.string(), cv::IMREAD_UNCHANGED); + if (mat.empty() || (mat.type() != CV_8UC4 && mat.type() != CV_8UC3)) + { + Error{} << "failed to load" << filename << "as RGBA32 image"; + return {}; + } + if (mat.type() == CV_8UC3) { + cv::Mat mat2; + cv::cvtColor(mat, mat2, cv::COLOR_RGB2RGBA); + mat = mat2.clone(); + } + + Error{} << "file" << filename; + + assert(mat.cols % TILE_SIZE[0] == 0 && mat.rows % TILE_SIZE[1] == 0); + + for (int y = 0; y + TILE_SIZE[1] <= mat.rows; y += TILE_SIZE[1]) + for (int x = 0; x + TILE_SIZE[0] <= mat.cols; x += TILE_SIZE[0]) + { + Error{} << "convert" << x << y; + cv::Rect roi { x, y, TILE_SIZE[0], TILE_SIZE[1] }; + auto frame = add_frame(mat(roi)); + ret.push_back(frame); + } + + return ret; +} + +big_atlas_frame big_atlas_builder::add_frame(const cv::Mat4b& frame) +{ + auto& row = maybe_next_row(); + big_atlas_frame ret { frame, { row.xpos, row.ypos } }; + row.frames.push_back(ret); + row.xpos += TILE_SIZE[0]; + maxx = std::max(maxx, row.xpos); + return ret; +} + +big_atlas_row& big_atlas_builder::maybe_next_row() +{ + auto& row = rows.back(); + + if (row.xpos + TILE_SIZE[0] > MAX_TEXTURE_SIZE[0]) + { + ypos += TILE_SIZE[1]; + rows.emplace_back(); + auto& row = rows.back(); + row.ypos = ypos; + + return row; + } + else + return row; +} diff --git a/tile-tool/big-atlas.hpp b/tile-tool/big-atlas.hpp new file mode 100644 index 00000000..77961be0 --- /dev/null +++ b/tile-tool/big-atlas.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include <Magnum/Magnum.h> +#include <Magnum/Math/Vector2.h> +#include <opencv2/core/mat.hpp> + +namespace std::filesystem { class path; } + +struct big_atlas_frame { + cv::Mat4b frame; + Magnum::Vector2i position; +}; + +struct big_atlas_row { + std::vector<big_atlas_frame> frames; + int xpos = 0, ypos = 0; +}; + +struct big_atlas_builder { + [[nodiscard]] std::vector<big_atlas_frame> add_atlas(const std::filesystem::path& filename); + big_atlas_frame add_frame(const cv::Mat4b& frame); + big_atlas_row& maybe_next_row(); + +private: + static constexpr Magnum::Vector2i TILE_SIZE = { 100, 100 }, + MAX_TEXTURE_SIZE = { 512, 512 }; + + std::vector<big_atlas_row> rows = {{}}; + int ypos = 0, maxx = 0; + + static_assert(!!TILE_SIZE[0] && !!TILE_SIZE[1] && !!MAX_TEXTURE_SIZE[0] && !!MAX_TEXTURE_SIZE[1]); + static_assert(MAX_TEXTURE_SIZE[0] >= TILE_SIZE[0] && MAX_TEXTURE_SIZE[1] >= TILE_SIZE[1]); +}; diff --git a/tile-tool/tile-tool.cpp b/tile-tool/tile-tool.cpp new file mode 100644 index 00000000..edc882ad --- /dev/null +++ b/tile-tool/tile-tool.cpp @@ -0,0 +1,34 @@ +#include "big-atlas.hpp" +#include "tile/serialize.hpp" +#include <tuple> +#include <filesystem> +#include <Corrade/Utility/Arguments.h> + +using Corrade::Utility::Arguments; + +struct options final { + std::filesystem::path input_dir, output_file; +}; + +static std::tuple<options, Arguments, bool> parse_cmdline(int argc, const char* const* argv) noexcept +{ + Corrade::Utility::Arguments args{}; + args.addOption('o', "output") + .addArrayArgument("input"); + args.parse(argc, argv); + options opts; + opts.input_dir = args.value<std::string>("input"); + + if (opts.input_dir.empty()) + opts.output_file = opts.input_dir.parent_path() / "big-atlas.json"; + + return { std::move(opts), std::move(args), true }; +} + +int main(int argc, char** argv) +{ + big_atlas_builder builder; + builder.add_atlas("images/metal1.png"); + builder.add_atlas("images/metal2.png"); + return 0; +} |
