diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-25 19:37:06 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-25 19:37:06 +0100 |
commit | e46dd0f45d1cab35c7441d72f5dcac83720cc539 (patch) | |
tree | 1611ed041680e6dcccb115cbc7c99e098b809d33 | |
parent | 1831d5d1eab5c9a607270a8a9b72a2ac1e6ce62a (diff) |
add scenery horizontal mirroring
-rw-r--r-- | anim-crop-tool/main.cpp | 3 | ||||
-rw-r--r-- | anim/table.json | 11 | ||||
-rw-r--r-- | anim/table.tga | bin | 175134 -> 87626 bytes | |||
-rw-r--r-- | draw/anim.cpp | 3 | ||||
-rw-r--r-- | editor/draw.cpp | 6 | ||||
-rw-r--r-- | editor/update.cpp | 2 | ||||
-rw-r--r-- | loader/atlas.cpp | 16 | ||||
-rw-r--r-- | main/clickable.hpp | 1 | ||||
-rw-r--r-- | main/draw.cpp | 3 | ||||
-rw-r--r-- | serialize/anim.cpp | 27 | ||||
-rw-r--r-- | src/anim-atlas.cpp | 22 | ||||
-rw-r--r-- | src/anim-atlas.hpp | 2 | ||||
-rw-r--r-- | src/anim.hpp | 2 | ||||
-rw-r--r-- | src/scenery.cpp | 4 |
14 files changed, 78 insertions, 24 deletions
diff --git a/anim-crop-tool/main.cpp b/anim-crop-tool/main.cpp index ec08b257..5b6fa31e 100644 --- a/anim-crop-tool/main.cpp +++ b/anim-crop-tool/main.cpp @@ -130,6 +130,9 @@ static bool load_file(anim_group& group, options& opts, anim_atlas_& atlas, Stri [[nodiscard]] static bool load_directory(anim_group& group, options& opts, anim_atlas_& atlas) { + if (!group.mirror_from.isEmpty()) + return true; + const auto input_dir = Path::join(opts.input_dir, group.name); if (!Path::exists(Path::join(input_dir, "."))) diff --git a/anim/table.json b/anim/table.json index 3b15dbc0..f472a4cd 100644 --- a/anim/table.json +++ b/anim/table.json @@ -20,14 +20,7 @@ ]
},
{
- "frames": [
- {
- "ground": "90 x 88",
- "offset": "0 x 164",
- "size": "180 x 164"
- }
- ],
- "ground": "959 x 712",
+ "mirror-from": "n",
"name": "w",
"offset": [
0,
@@ -39,6 +32,6 @@ "height": 0,
"nframes": 1,
"object_name": "table",
- "pixel_size": "180 x 328",
+ "pixel_size": "180 x 164",
"width": 180
}
diff --git a/anim/table.tga b/anim/table.tga Binary files differindex a3c6aed6..1f6083fc 100644 --- a/anim/table.tga +++ b/anim/table.tga diff --git a/draw/anim.cpp b/draw/anim.cpp index 558dd197..82f0d746 100644 --- a/draw/anim.cpp +++ b/draw/anim.cpp @@ -26,7 +26,8 @@ void anim_mesh::draw(tile_shader& shader, anim_atlas& atlas, rotation r, std::si { const auto center = Vector3(xy.x, xy.y, 0.f) * TILE_SIZE; const auto pos = atlas.frame_quad(center, r, frame); - const auto texcoords = atlas.texcoords_for_frame(r, frame); + const auto& g = atlas.group(r); + const auto texcoords = atlas.texcoords_for_frame(r, frame, !g.mirror_from.isEmpty()); const float depth = tile_shader::depth_value(xy, .25f); quad_data array; for (std::size_t i = 0; i < 4; i++) diff --git a/editor/draw.cpp b/editor/draw.cpp index 17be7aeb..dd4cf96b 100644 --- a/editor/draw.cpp +++ b/editor/draw.cpp @@ -52,7 +52,11 @@ clickable_scenery* app::find_clickable_scenery(Vector2i pixel_) for (clickable_scenery& c : array) if (c.depth > depth && c.dest.contains(pixel)) { - const auto pos = pixel - c.dest.min() + c.src.min(); + + const auto pos_ = pixel - c.dest.min() + c.src.min(); + const auto pos = c.atlas.group(c.item.r).mirror_from.isEmpty() + ? pos_ + : Vector2ui(c.src.sizeX() - pos_[0], pos_[1]); const auto stride = c.atlas.info().pixel_size[0]; std::size_t idx = pos.y() * stride + pos.x(); fm_debug_assert(idx < c.bitmask.size()); diff --git a/editor/update.cpp b/editor/update.cpp index 9e479050..0c347f1d 100644 --- a/editor/update.cpp +++ b/editor/update.cpp @@ -31,7 +31,7 @@ void app::maybe_initialize_chunk_(const chunk_coords& pos, chunk& c) c[{K, K+1}].wall_north() = { _wall1, 0 }; c[{K+1, K }].wall_west() = { _wall2, 0 }; c[{K+3, K+1}].scenery() = { scenery::door, rotation::N, _door, false }; - c[{ 3, 4 }].scenery() = { scenery::generic, rotation::N, _table }; + c[{ 3, 4 }].scenery() = { scenery::generic, rotation::W, _table }; c[{K, K+1}].scenery() = { scenery::generic, rotation::N, _control_panel, true }; c.mark_modified(); } diff --git a/loader/atlas.cpp b/loader/atlas.cpp index 1aaa4e31..659f716a 100644 --- a/loader/atlas.cpp +++ b/loader/atlas.cpp @@ -3,6 +3,7 @@ #include "src/emplacer.hpp" #include "src/tile-atlas.hpp" #include "src/anim-atlas.hpp" +#include <algorithm> #include <Corrade/Containers/ArrayViewStl.h> #include <Corrade/Containers/Pair.h> #include <Corrade/Containers/StridedArrayView.h> @@ -34,6 +35,21 @@ std::shared_ptr<anim_atlas> loader_impl::anim_atlas(StringView name) { const auto path = Path::join(ANIM_PATH, Path::splitExtension(name).first()); auto anim_info = deserialize_anim(path + ".json"); + + for (anim_group& group : anim_info.groups) + { + if (!group.mirror_from.isEmpty()) + { + auto it = std::find_if(anim_info.groups.cbegin(), anim_info.groups.cend(), + [&](const anim_group& x) { return x.name == group.mirror_from; }); + if (it == anim_info.groups.cend()) + fm_abort("can't find group '%s' to mirror from '%s'", group.mirror_from.data(), group.name.data()); + group.frames = it->frames; + for (anim_frame& f : group.frames) + f.ground = Vector2i((Int)f.size[0] - f.ground[0], f.ground[1]); + } + } + auto tex = texture("", path); fm_assert(!anim_info.object_name.isEmpty()); diff --git a/main/clickable.hpp b/main/clickable.hpp index efc1a7fa..3eee243f 100644 --- a/main/clickable.hpp +++ b/main/clickable.hpp @@ -15,6 +15,7 @@ struct clickable final { float depth = 0; chunk_coords chunk; local_coords pos; + bool mirrored = false; }; } // namespace floormat diff --git a/main/draw.cpp b/main/draw.cpp index aa1b6f2e..0b797449 100644 --- a/main/draw.cpp +++ b/main/draw.cpp @@ -122,7 +122,8 @@ void main_impl::draw_anim() noexcept clickable<anim_atlas, scenery> item = { *atlas, s, { f.offset, f.offset + f.size }, { offset, offset + f.size }, - atlas->bitmask(), tile_shader::depth_value(xy, 0.25f), pos, xy + atlas->bitmask(), tile_shader::depth_value(xy, 0.25f), pos, xy, + !g.mirror_from.isEmpty(), }; _clickable_scenery.push_back(item); } diff --git a/serialize/anim.cpp b/serialize/anim.cpp index 8080bb02..fd5e7315 100644 --- a/serialize/anim.cpp +++ b/serialize/anim.cpp @@ -18,8 +18,31 @@ namespace nlohmann { void adl_serializer<anim_frame>::to_json(json& j, const anim_frame& val) { using nlohmann::to_json; to_json(j, val); } void adl_serializer<anim_frame>::from_json(const json& j, anim_frame& val) { using nlohmann::from_json; from_json(j, val); } -void adl_serializer<anim_group>::to_json(json& j, const anim_group& val) { using nlohmann::to_json; to_json(j, val); } -void adl_serializer<anim_group>::from_json(const json& j, anim_group& val) { using nlohmann::from_json; from_json(j, val); } +void adl_serializer<anim_group>::to_json(json& j, const anim_group& val) +{ + using nlohmann::to_json; + if (!val.mirror_from.isEmpty()) + { + j["name"] = val.name; + j["mirror-from"] = val.mirror_from; + j["offset"] = val.offset; + } + else + to_json(j, val); +} + +void adl_serializer<anim_group>::from_json(const json& j, anim_group& val) +{ + using nlohmann::from_json; + if (j.contains("mirror-from")) + { + val.name = j["name"]; + val.mirror_from = j["mirror-from"]; + val.offset = j["offset"]; + } + else + from_json(j, val); +} void adl_serializer<anim_def>::to_json(json& j, const anim_def& val) { using nlohmann::to_json; to_json(j, val); } void adl_serializer<anim_def>::from_json(const json& j, anim_def& val) { using nlohmann::from_json; from_json(j, val); } diff --git a/src/anim-atlas.cpp b/src/anim-atlas.cpp index 33b107df..e8d4bd9b 100644 --- a/src/anim-atlas.cpp +++ b/src/anim-atlas.cpp @@ -70,18 +70,26 @@ auto anim_atlas::frame(rotation r, std::size_t frame) const noexcept -> const an return g.frames[frame]; } -auto anim_atlas::texcoords_for_frame(rotation r, std::size_t i) const noexcept -> texcoords +auto anim_atlas::texcoords_for_frame(rotation r, std::size_t i, bool mirror) const noexcept -> texcoords { const auto f = frame(r, i); const Vector2 p0(f.offset), p1(f.size); const auto x0 = p0.x()+.5f, x1 = p1.x()-1, y0 = p0.y()+.5f, y1 = p1.y()-1; const auto size = _info.pixel_size; - return {{ - { (x0+x1) / size[0], 1 - (y0+y1) / size[1] }, // bottom right - { (x0+x1) / size[0], 1 - y0 / size[1] }, // top right - { x0 / size[0], 1 - (y0+y1) / size[1] }, // bottom left - { x0 / size[0], 1 - y0 / size[1] }, // top left - }}; + if (!mirror) + return {{ + { (x0+x1) / size[0], 1 - (y0+y1) / size[1] }, // bottom right + { (x0+x1) / size[0], 1 - y0 / size[1] }, // top right + { x0 / size[0], 1 - (y0+y1) / size[1] }, // bottom left + { x0 / size[0], 1 - y0 / size[1] }, // top left + }}; + else + return {{ + { x0 / size[0], 1 - (y0+y1) / size[1] }, // bottom right + { x0 / size[0], 1 - y0 / size[1] }, // top right + { (x0+x1) / size[0], 1 - (y0+y1) / size[1] }, // bottom left + { (x0+x1) / size[0], 1 - y0 / size[1] }, // top left + }}; } auto anim_atlas::frame_quad(const Vector3& center, rotation r, std::size_t i) const noexcept -> quad diff --git a/src/anim-atlas.hpp b/src/anim-atlas.hpp index 5b79ca19..b25ff489 100644 --- a/src/anim-atlas.hpp +++ b/src/anim-atlas.hpp @@ -30,7 +30,7 @@ struct anim_atlas final const anim_group& group(rotation r) const noexcept; const anim_frame& frame(rotation r, std::size_t frame) const noexcept; - texcoords texcoords_for_frame(rotation r, std::size_t frame) const noexcept; + texcoords texcoords_for_frame(rotation r, std::size_t frame, bool mirror) const noexcept; quad frame_quad(const Vector3& center, rotation r, std::size_t frame) const noexcept; BitArrayView bitmask() const; diff --git a/src/anim.hpp b/src/anim.hpp index 1a4011dc..674895ed 100644 --- a/src/anim.hpp +++ b/src/anim.hpp @@ -22,7 +22,7 @@ enum class anim_direction : unsigned char struct anim_group final { - String name; + String name, mirror_from; std::vector<anim_frame> frames; Vector2ui ground; Vector3b offset; diff --git a/src/scenery.cpp b/src/scenery.cpp index 7c3001b0..eb90b598 100644 --- a/src/scenery.cpp +++ b/src/scenery.cpp @@ -56,6 +56,9 @@ scenery::scenery(float dt, frame_t frame, rotation r, bool passable, scenery_typ bool scenery::can_activate() const noexcept { +#if 0 + return true; +#else switch (type) { default: @@ -65,6 +68,7 @@ bool scenery::can_activate() const noexcept case scenery_type::object: return true; } +#endif } void scenery::update(float dt, const anim_atlas& anim) |