summaryrefslogtreecommitdiffhomepage
path: root/tile-tool
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-09-30 18:48:50 +0200
committerStanislaw Halik <sthalik@misaki.pl>2022-09-30 18:50:32 +0200
commit5c9863cf0998b5f1b6107ce09b54cd3e8b484221 (patch)
tree7ca268c80a0ec7ac0c1b815d984cf11309b96840 /tile-tool
parentd3a29055d8b1dce89c77af0988ea840e949d2450 (diff)
.
Diffstat (limited to 'tile-tool')
-rw-r--r--tile-tool/CMakeLists.txt10
-rw-r--r--tile-tool/big-atlas.cpp67
-rw-r--r--tile-tool/big-atlas.hpp33
-rw-r--r--tile-tool/tile-tool.cpp34
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;
+}