From 7fd3702968ff59dea92a48db7ec21eafd856647f Mon Sep 17 00:00:00 2001 From: Albin Johansson Date: Mon, 7 Oct 2024 19:35:44 +0200 Subject: [PATCH] Add option for ellipse polygon vertex count --- .../inc/tactile/base/io/save/save_format.hpp | 6 ++-- .../tactile/core/event/map_event_handler.cpp | 3 +- .../gd3_document_converter.hpp | 5 ++++ .../godot_tscn_format/godot_scene_format.hpp | 4 ++- .../lib/src/gd3_document_converter.cpp | 8 +++-- .../lib/src/godot_scene_format.cpp | 30 ++++++++++++++----- 6 files changed, 42 insertions(+), 14 deletions(-) diff --git a/source/base/lib/inc/tactile/base/io/save/save_format.hpp b/source/base/lib/inc/tactile/base/io/save/save_format.hpp index f798d71a99..ee569ca3de 100644 --- a/source/base/lib/inc/tactile/base/io/save/save_format.hpp +++ b/source/base/lib/inc/tactile/base/io/save/save_format.hpp @@ -4,19 +4,19 @@ #include // expected #include // path -#include // string +#include // string_view #include // error_code #include // unordered_map -#include "tactile/base/container/string_map.hpp" #include "tactile/base/io/save/ir.hpp" +#include "tactile/base/meta/attribute.hpp" #include "tactile/base/prelude.hpp" namespace tactile { class IMapView; -using SaveFormatExtraSettings = StringMap; +using SaveFormatExtraSettings = std::unordered_map; /** * Provides save format parse options. diff --git a/source/core/src/tactile/core/event/map_event_handler.cpp b/source/core/src/tactile/core/event/map_event_handler.cpp index 23503d2a28..c60c7faab9 100644 --- a/source/core/src/tactile/core/event/map_event_handler.cpp +++ b/source/core/src/tactile/core/event/map_event_handler.cpp @@ -130,7 +130,8 @@ void MapEventHandler::on_export_as_godot_scene(const ExportAsGodotSceneEvent& ev } SaveFormatExtraSettings extra_settings {}; - extra_settings.insert_or_assign("godot::version", std::to_string(event.version)); + extra_settings["version"] = Attribute {event.version}; + extra_settings["ellipse_polygon_vertices"] = Attribute {32}; const SaveFormatWriteOptions options { .extra = std::move(extra_settings), diff --git a/source/godot_tscn_format/lib/inc/tactile/godot_tscn_format/gd3_document_converter.hpp b/source/godot_tscn_format/lib/inc/tactile/godot_tscn_format/gd3_document_converter.hpp index 42cc313054..d0ad191b8e 100644 --- a/source/godot_tscn_format/lib/inc/tactile/godot_tscn_format/gd3_document_converter.hpp +++ b/source/godot_tscn_format/lib/inc/tactile/godot_tscn_format/gd3_document_converter.hpp @@ -2,6 +2,8 @@ #pragma once +#include // size_t + #include "tactile/base/document/document_visitor.hpp" #include "tactile/base/io/save/save_format.hpp" #include "tactile/godot_tscn_format/api.hpp" @@ -22,6 +24,8 @@ class TACTILE_GODOT_API Gd3DocumentConverter final : public IDocumentVisitor */ explicit Gd3DocumentConverter(SaveFormatWriteOptions options); + void set_ellipse_polygon_vertices(std::size_t count); + [[nodiscard]] auto visit(const IComponentView& component) -> std::expected override; @@ -52,6 +56,7 @@ class TACTILE_GODOT_API Gd3DocumentConverter final : public IDocumentVisitor private: SaveFormatWriteOptions m_options; Gd3Map m_map; + std::size_t m_ellipse_polygon_vertices {}; }; } // namespace tactile::godot diff --git a/source/godot_tscn_format/lib/inc/tactile/godot_tscn_format/godot_scene_format.hpp b/source/godot_tscn_format/lib/inc/tactile/godot_tscn_format/godot_scene_format.hpp index be906a3b2e..aef23deaf6 100644 --- a/source/godot_tscn_format/lib/inc/tactile/godot_tscn_format/godot_scene_format.hpp +++ b/source/godot_tscn_format/lib/inc/tactile/godot_tscn_format/godot_scene_format.hpp @@ -13,7 +13,9 @@ namespace tactile::godot { * * \details * This save format supports the following custom settings. - * - \c "godot::version": An integer indicating which major version of Godot to target. + * - \c "version": An integer indicating which major version of Godot to target. + * - \c "ellipse_polygon_vertices": An integer indicating the number of vertices to use when + * approximating ellipse objects as polygons. * * \see https://docs.godotengine.org/en/stable/contributing/development/file_formats/tscn.html * \see https://docs.godotengine.org/en/3.6/development/file_formats/tscn.html diff --git a/source/godot_tscn_format/lib/src/gd3_document_converter.cpp b/source/godot_tscn_format/lib/src/gd3_document_converter.cpp index 36917de1b8..52259f1fd3 100644 --- a/source/godot_tscn_format/lib/src/gd3_document_converter.cpp +++ b/source/godot_tscn_format/lib/src/gd3_document_converter.cpp @@ -248,6 +248,11 @@ Gd3DocumentConverter::Gd3DocumentConverter(SaveFormatWriteOptions options) m_map {} {} +void Gd3DocumentConverter::set_ellipse_polygon_vertices(const std::size_t count) +{ + m_ellipse_polygon_vertices = count; +} + auto Gd3DocumentConverter::visit(const IComponentView&) -> std::expected { return {}; @@ -370,8 +375,7 @@ auto Gd3DocumentConverter::visit(const IObjectView& object) auto& gd_polygon = gd_object.value.emplace(); const auto radius = object.get_size() * 0.5f; - constexpr std::size_t point_count = 32; // TODO setting - gd_polygon.points = _approximate_ellipse_as_polygon(radius, point_count); + gd_polygon.points = _approximate_ellipse_as_polygon(radius, m_ellipse_polygon_vertices); break; } diff --git a/source/godot_tscn_format/lib/src/godot_scene_format.cpp b/source/godot_tscn_format/lib/src/godot_scene_format.cpp index 6cc97a889a..a2b3d7434f 100644 --- a/source/godot_tscn_format/lib/src/godot_scene_format.cpp +++ b/source/godot_tscn_format/lib/src/godot_scene_format.cpp @@ -7,6 +7,7 @@ #include "tactile/base/document/map_view.hpp" #include "tactile/base/io/int_parser.hpp" +#include "tactile/base/numeric/saturate_cast.hpp" #include "tactile/godot_tscn_format/gd3_document_converter.hpp" #include "tactile/godot_tscn_format/gd3_exporter.hpp" #include "tactile/runtime/logging.hpp" @@ -15,21 +16,33 @@ namespace tactile::godot { namespace { [[nodiscard]] -auto _deduce_godot_version(const SaveFormatExtraSettings& settings) -> std::optional +auto _deduce_godot_version(const SaveFormatExtraSettings& settings) -> int { int version {3}; - if (const auto iter = settings.find("godot::version"); iter != settings.end()) { - if (const auto parsed_version = parse(iter->second)) { - version = *parsed_version; + if (const auto iter = settings.find("version"); iter != settings.end()) { + const auto parsed_version = iter->second.as_int(); + if (parsed_version == 3 || parsed_version == 4) { + version = parsed_version; } } - if (version != 3 && version != 4) { - return std::nullopt; + return version; +} + +[[nodiscard]] +auto _deduce_ellipse_polygon_vertices(const SaveFormatExtraSettings& settings) -> std::size_t +{ + std::size_t vertices {32}; + + if (const auto iter = settings.find("ellipse_polygon_vertices"); iter != settings.end()) { + const auto parsed_vertices = saturate_cast(iter->second.as_int()); + if (parsed_vertices >= 4) { + vertices = parsed_vertices; + } } - return version; + return vertices; } } // namespace @@ -51,9 +64,12 @@ auto GodotSceneFormat::save_map(const IMapView& map, { try { const auto version = _deduce_godot_version(options.extra); + const auto ellipse_polygon_vertices = _deduce_ellipse_polygon_vertices(options.extra); if (version == 3) { Gd3DocumentConverter converter {options}; + converter.set_ellipse_polygon_vertices(ellipse_polygon_vertices); + map.accept(converter); const auto& gd_map = converter.get_map();