summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--anim-crop-tool/main.cpp46
-rw-r--r--floormat/main.hpp4
-rw-r--r--loader/atlas.cpp4
-rw-r--r--loader/vobj.cpp20
-rw-r--r--main/main-impl.cpp3
-rw-r--r--main/main-impl.hpp8
-rw-r--r--serialize/anim.cpp6
-rw-r--r--serialize/corrade-array.hpp28
-rw-r--r--serialize/world-reader.cpp1
-rw-r--r--src/anim-atlas.cpp2
-rw-r--r--src/anim.hpp6
-rw-r--r--src/path-search.hpp3
12 files changed, 93 insertions, 38 deletions
diff --git a/anim-crop-tool/main.cpp b/anim-crop-tool/main.cpp
index 3f314719..5c96de62 100644
--- a/anim-crop-tool/main.cpp
+++ b/anim-crop-tool/main.cpp
@@ -9,12 +9,10 @@
#include "serialize/json-helper.hpp"
#include "serialize/anim.hpp"
-#include <cerrno>
-#include <cmath>
-#include <cstring>
-#include <algorithm>
#include <tuple>
+#include <algorithm>
+#include <Corrade/Containers/GrowableArray.h>
#include <Corrade/Containers/Pair.h>
#include <Corrade/Containers/StringView.h>
#include <Corrade/Containers/String.h>
@@ -24,6 +22,8 @@
#include <Corrade/Utility/Move.h>
#include <Corrade/Utility/Path.h>
+#include <Magnum/Math/Functions.h>
+
#include <opencv2/core/mat.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>
@@ -43,8 +43,14 @@ struct options
anim_scale scale;
};
+struct image_bounds_tuple
+{
+ cv::Vec2i start, end;
+ bool ret;
+};
+
[[nodiscard]]
-std::tuple<cv::Vec2i, cv::Vec2i, bool> find_image_bounds(const cv::Mat4b& mat) noexcept
+image_bounds_tuple find_image_bounds(const cv::Mat4b& mat) noexcept
{
cv::Vec2i start{mat.cols, mat.rows}, end{0, 0};
for (int y = 0; y < mat.rows; y++)
@@ -55,10 +61,10 @@ std::tuple<cv::Vec2i, cv::Vec2i, bool> find_image_bounds(const cv::Mat4b& mat) n
enum {R, G, B, A};
if (cv::Vec4b px = ptr[x]; px[A] != 0)
{
- start[0] = std::min(x, start[0]);
- start[1] = std::min(y, start[1]);
- end[0] = std::max(x+1, end[0]);
- end[1] = std::max(y+1, end[1]);
+ start[0] = Math::min(x, start[0]);
+ start[1] = Math::min(y, start[1]);
+ end[0] = Math::max(x+1, end[0]);
+ end[1] = Math::max(y+1, end[1]);
}
}
}
@@ -117,13 +123,13 @@ bool load_file(anim_group& group, options& opts, anim_atlas_& atlas, StringView
cv::resize(mat({start, size}), resized, dest_size, 0, 0, cv::INTER_LANCZOS4);
const Vector2i ground = {
- (int)std::round(((int)group.ground[0] - start[0]) * factor),
- (int)std::round(((int)group.ground[1] - start[1]) * factor),
+ (int)Math::round(((int)group.ground[0] - start[0]) * factor),
+ (int)Math::round(((int)group.ground[1] - start[1]) * factor),
};
const Vector2ui dest_size_ = { (unsigned)dest_size.width, (unsigned)dest_size.height };
- group.frames.push_back({ground, atlas.offset(), dest_size_});
+ arrayAppend(group.frames, {ground, atlas.offset(), dest_size_});
atlas.add_entry({&group.frames.back(), Utility::move(resized)});
return true;
}
@@ -166,11 +172,10 @@ bool load_directory(anim_group& group, options& opts, anim_atlas_& atlas)
return false;
}
- group.frames.clear();
+ arrayReserve(group.frames, (size_t)max-1);
+ arrayResize(group.frames, 0);
// atlas stores its entries through a pointer.
- // vector::reserve() is necessary to avoid use-after-free.
- group.frames.reserve((size_t)max-1);
-
+ // arrayReserve() is necessary to avoid use-after-free.
for (unsigned i = 1; i < max; i++)
{
char filename[9];
@@ -196,7 +201,14 @@ inline String fixsep(String str)
using Corrade::Utility::Arguments;
-std::tuple<options, Arguments, bool> parse_cmdline(int argc, const char* const* argv) noexcept
+struct arg_tuple
+{
+ options opts;
+ Arguments args;
+ bool ret;
+};
+
+arg_tuple parse_cmdline(int argc, const char* const* argv) noexcept
{
Corrade::Utility::Arguments args{};
args.addOption('o', "output").setHelp("output", "", "DIR")
diff --git a/floormat/main.hpp b/floormat/main.hpp
index cfb41f1d..a6f67ab0 100644
--- a/floormat/main.hpp
+++ b/floormat/main.hpp
@@ -23,7 +23,7 @@ struct wall_mesh;
struct anim_mesh;
struct texture_unit_cache;
class path_search;
-struct astar;
+class astar;
struct floormat_main
{
@@ -82,7 +82,7 @@ struct floormat_main
virtual struct texture_unit_cache& texture_unit_cache() = 0;
virtual path_search& search() = 0;
- virtual struct astar& astar() = 0;
+ virtual class astar& astar() = 0;
[[nodiscard]] static floormat_main* create(floormat_app& app, fm_settings&& options);
[[maybe_unused]] static void debug_break();
diff --git a/loader/atlas.cpp b/loader/atlas.cpp
index f61502fe..100f638e 100644
--- a/loader/atlas.cpp
+++ b/loader/atlas.cpp
@@ -75,7 +75,7 @@ std::shared_ptr<anim_atlas> loader_impl::anim_atlas(StringView name, StringView
[&](const anim_group& x) { return x.name == group.mirror_from; });
if (it == anim_info.groups.cend())
fm_throw("can't find group '{}' to mirror from '{}'"_cf, group.mirror_from, group.name);
- group.frames = it->frames;
+ group.frames = array(arrayView(it->frames));
for (anim_frame& f : group.frames)
f.ground = Vector2i((Int)f.size[0] - f.ground[0], f.ground[1]);
}
@@ -85,7 +85,7 @@ std::shared_ptr<anim_atlas> loader_impl::anim_atlas(StringView name, StringView
fm_soft_assert(!anim_info.object_name.isEmpty());
fm_soft_assert(anim_info.pixel_size.product() > 0);
- fm_soft_assert(!anim_info.groups.empty());
+ fm_soft_assert(!anim_info.groups.isEmpty());
fm_soft_assert(anim_info.nframes > 0);
fm_soft_assert(anim_info.nframes == 1 || anim_info.fps > 0);
const auto size = tex.pixels().size();
diff --git a/loader/vobj.cpp b/loader/vobj.cpp
index 637ba776..5f7fc2fe 100644
--- a/loader/vobj.cpp
+++ b/loader/vobj.cpp
@@ -57,13 +57,19 @@ std::shared_ptr<class anim_atlas> loader_impl::make_vobj_anim_atlas(StringView n
def.pixel_size = { width, height };
def.nframes = 1;
def.fps = 0;
- def.groups = {{
- .name = "n"_s,
- .frames = {{
- .ground = Vector2i(def.pixel_size/2),
- .size = def.pixel_size
- }}
- }};
+ {
+ auto group = anim_group {
+ .name = "n"_s,
+ .frames = { InPlaceInit, {
+ anim_frame {
+ .ground = Vector2i(def.pixel_size/2),
+ .size = def.pixel_size,
+ }},
+ },
+ };
+ def.groups = Array<anim_group>{1};
+ def.groups[0] = std::move(group);
+ }
auto atlas = std::make_shared<class anim_atlas>(name, tex, std::move(def));
return atlas;
}
diff --git a/main/main-impl.cpp b/main/main-impl.cpp
index cb74de85..6875f751 100644
--- a/main/main-impl.cpp
+++ b/main/main-impl.cpp
@@ -1,4 +1,5 @@
#include "main-impl.hpp"
+#include "src/path-search.hpp"
#include <Corrade/Utility/Move.h>
#include <Magnum/Platform/Sdl2Application.h>
@@ -63,7 +64,7 @@ uint32_t main_impl::cursor() const noexcept
}
struct texture_unit_cache& main_impl::texture_unit_cache() { return _tuc; }
-path_search& main_impl::search() { return _search; }
+path_search& main_impl::search() { return *_search; }
astar& main_impl::astar() { return _astar; }
} // namespace floormat
diff --git a/main/main-impl.hpp b/main/main-impl.hpp
index b6d1b1f4..522183e6 100644
--- a/main/main-impl.hpp
+++ b/main/main-impl.hpp
@@ -31,6 +31,8 @@ struct floormat_app;
struct scenery;
class anim_atlas;
struct clickable;
+class path_search;
+class astar;
struct main_impl final : Platform::Sdl2Application, floormat_main
{
@@ -98,7 +100,7 @@ struct main_impl final : Platform::Sdl2Application, floormat_main
struct texture_unit_cache& texture_unit_cache() override;
path_search& search() override;
- struct astar& astar() override;
+ class astar& astar() override;
private:
struct texture_unit_cache _tuc;
@@ -117,8 +119,8 @@ private:
#ifdef FM_USE_DEPTH32
Framebuffer framebuffer;
#endif
- path_search _search;
- struct astar _astar;
+ safe_ptr<path_search> _search;
+ class astar _astar;
struct {
float value = 0;
diff --git a/serialize/anim.cpp b/serialize/anim.cpp
index 443fc34b..4b5dee77 100644
--- a/serialize/anim.cpp
+++ b/serialize/anim.cpp
@@ -1,7 +1,10 @@
#include "serialize/magnum-vector.hpp"
#include "serialize/corrade-string.hpp"
#include "serialize/anim.hpp"
+#include "serialize/corrade-array.hpp"
#include "compat/exception.hpp"
+#include <Corrade/Containers/Array.h>
+#include <Corrade/Containers/ArrayViewStl.h>
#include <nlohmann/json.hpp>
#include <tuple>
@@ -115,8 +118,9 @@ static void from_json(const json& j, anim_def& val)
val.action_frame2 = j["action-frame-2"];
if (j.contains("fps"))
val.fps = j["fps"];
+
val.groups = j["groups"];
- fm_soft_assert(!val.groups.empty());
+ fm_soft_assert(!val.groups.isEmpty());
val.scale = j["scale"];
fm_soft_assert(val.scale.type != anim_scale_type::invalid);
}
diff --git a/serialize/corrade-array.hpp b/serialize/corrade-array.hpp
new file mode 100644
index 00000000..ea450870
--- /dev/null
+++ b/serialize/corrade-array.hpp
@@ -0,0 +1,28 @@
+#pragma once
+#include "compat/exception.hpp"
+#include <Corrade/Containers/Array.h>
+#include <nlohmann/json.hpp>
+
+namespace nlohmann {
+
+template<typename T, typename D>
+struct adl_serializer<Corrade::Containers::Array<T, D>>
+{
+ static void to_json(json& j, const Corrade::Containers::Array<T, D>& array)
+ {
+ j.clear();
+ for (const T& x : array)
+ j.push_back(x);
+ }
+
+ static void from_json(const json& j, Corrade::Containers::Array<T>& array)
+ {
+ fm_soft_assert(j.is_array());
+ auto size = (uint32_t)j.size();
+ array = Corrade::Containers::Array<T>{size};
+ for (uint32_t i = 0; i < size; i++)
+ array[i] = j[i];
+ }
+};
+
+} // namespace nlohmann
diff --git a/serialize/world-reader.cpp b/serialize/world-reader.cpp
index 6bfcaa47..366648d5 100644
--- a/serialize/world-reader.cpp
+++ b/serialize/world-reader.cpp
@@ -14,6 +14,7 @@
#include <cerrno>
#include <cstring>
#include <memory>
+#include <vector>
namespace {
diff --git a/src/anim-atlas.cpp b/src/anim-atlas.cpp
index c6a7c2f2..353ebb34 100644
--- a/src/anim-atlas.cpp
+++ b/src/anim-atlas.cpp
@@ -40,7 +40,7 @@ anim_atlas::anim_atlas(String name, const ImageView2D& image, anim_def info) :
_name{std::move(name)}, _bitmask{make_bitmask(image)},
_info{std::move(info)}, _group_indices{make_group_indices(_info)}
{
- fm_soft_assert(!_info.groups.empty());
+ fm_soft_assert(!_info.groups.isEmpty());
const Size<3> size = image.pixels().size();
fm_soft_assert(size[0]*size[1] == _info.pixel_size.product());
diff --git a/src/anim.hpp b/src/anim.hpp
index 3b4d70a9..3c25f51c 100644
--- a/src/anim.hpp
+++ b/src/anim.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include <vector> // todo use <Corrade/Containers/GrowableArray.h>
+#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/String.h>
#include <Magnum/Magnum.h>
#include <Magnum/Math/Vector2.h>
@@ -23,7 +23,7 @@ enum class anim_direction : unsigned char
struct anim_group final
{
String name{}, mirror_from{};
- std::vector<anim_frame> frames{};
+ Array<anim_frame> frames{};
Vector2ui ground{}; // for use in anim-crop-tool only
Vector2s z_offset{}, depth_offset{};
Vector3b offset{};
@@ -54,7 +54,7 @@ struct anim_scale final
struct anim_def final
{
String object_name{}, anim_name{};
- std::vector<anim_group> groups{};
+ Array<anim_group> groups{};
Vector2ui pixel_size{};
anim_scale scale = anim_scale::ratio{1};
size_t nframes = 0, fps = 0, action_frame = 0, action_frame2 = 0;
diff --git a/src/path-search.hpp b/src/path-search.hpp
index 8e56f4fd..512a507f 100644
--- a/src/path-search.hpp
+++ b/src/path-search.hpp
@@ -65,8 +65,9 @@ public:
static bool is_passable(world& w, chunk_coords_ ch0, const bbox<float>& bb, object_id own_id, const pred& p = never_continue());
};
-struct astar
+class astar
{
+public:
struct visited
{
uint32_t dist = (uint32_t)-1;