From 8b8fbee6ba3580d99fc9bf56d72fed40d7e07ef4 Mon Sep 17 00:00:00 2001 From: Guillaume Jacquemin Date: Sun, 14 Jul 2024 19:26:12 +0200 Subject: [PATCH] Gvas,GameObjects,Application: fix UE5 builds. --- src/Application/Application.cpp | 100 +++++++++ src/Application/Application.h | 18 +- src/Application/Application_MassViewer.cpp | 206 +++++++++++------- .../Application_MassViewer_Armour.cpp | 110 ++++++---- .../Application_MassViewer_Frame.cpp | 2 + src/GameObjects/Accessory.h | 14 +- src/GameObjects/BulletLauncherAttachment.h | 14 +- src/GameObjects/Decal.h | 13 +- src/GameObjects/Mass_Armour.cpp | 30 +-- src/GameObjects/Mass_DecalsAccessories.cpp | 53 ++--- src/Gvas/Serialisers/RotatorProperty.cpp | 40 +++- src/Gvas/Serialisers/Vector2DProperty.cpp | 37 +++- src/Gvas/Serialisers/VectorProperty.cpp | 40 +++- src/Gvas/Types/RotatorStructProperty.h | 9 +- src/Gvas/Types/Vector2DStructProperty.h | 9 +- src/Gvas/Types/VectorStructProperty.h | 9 +- 16 files changed, 484 insertions(+), 220 deletions(-) diff --git a/src/Application/Application.cpp b/src/Application/Application.cpp index 33f67d0..eaa712d 100644 --- a/src/Application/Application.cpp +++ b/src/Application/Application.cpp @@ -27,6 +27,8 @@ #include +#include + #include #include #include @@ -419,6 +421,104 @@ Application::drawCheckbox(Containers::StringView label, bool value) { return ImGui::Checkbox(label.data(), &value); } +void +Application::drawVector3Drag(Containers::StringView id, Vector3& vec, float speed, Vector3 min, Vector3 max, + const char* x_format, const char* y_format, const char* z_format, ImGuiSliderFlags_ flags) +{ + ImGui::PushID(id.cbegin()); + ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); + ImGui::DragFloat("##X", &vec.x(), speed, min.x(), max.x(), x_format, flags); + ImGui::PopItemWidth(); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::DragFloat("##Y", &vec.y(), speed, min.y(), max.y(), y_format, flags); + ImGui::PopItemWidth(); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::DragFloat("##Z", &vec.z(), speed, min.z(), max.z(), z_format, flags); + ImGui::PopItemWidth(); + ImGui::PopID(); +} + +void +Application::drawVector3dDrag(Containers::StringView id, Vector3d& vec, float speed, Vector3d min, Vector3d max, + const char* x_format, const char* y_format, const char* z_format, + ImGuiSliderFlags_ flags) +{ + ImGui::PushID(id.cbegin()); + ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); + ImGui::DragScalar("##X", ImGuiDataType_Double, &vec.x(), speed, &min.x(), &max.x(), x_format, flags); + ImGui::PopItemWidth(); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::DragScalar("##Y", ImGuiDataType_Double, &vec.y(), speed, &min.y(), &max.y(), y_format, flags); + ImGui::PopItemWidth(); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::DragScalar("##X", ImGuiDataType_Double, &vec.x(), speed, &min.z(), &max.z(), z_format, flags); + ImGui::PopItemWidth(); + ImGui::PopID(); +} + +void +Application::drawVector3Slider(Containers::StringView id, Vector3& vec, Vector3 min, Vector3 max, const char* x_format, + const char* y_format, const char* z_format, ImGuiSliderFlags_ flags) +{ + ImGui::PushID(id.cbegin()); + ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); + ImGui::SliderFloat("##X", &vec.x(), min.x(), max.x(), x_format, flags); + ImGui::PopItemWidth(); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::SliderFloat("##Y", &vec.y(), min.y(), max.y(), y_format, flags); + ImGui::PopItemWidth(); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::SliderFloat("##Z", &vec.z(), min.z(), max.z(), z_format, flags); + ImGui::PopItemWidth(); + ImGui::PopID(); +} + +void +Application::drawVector3dSlider(Containers::StringView id, Vector3d& vec, Vector3d min, Vector3d max, + const char* x_format, const char* y_format, const char* z_format, + ImGuiSliderFlags_ flags) +{ + ImGui::PushID(id.cbegin()); + ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); + ImGui::SliderScalar("##X", ImGuiDataType_Double, &vec.x(), &min.x(), &max.x(), x_format, flags); + ImGui::PopItemWidth(); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::SliderScalar("##Y", ImGuiDataType_Double, &vec.y(), &min.y(), &max.y(), y_format, flags); + ImGui::PopItemWidth(); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::SliderScalar("##X", ImGuiDataType_Double, &vec.x(), &min.z(), &max.z(), z_format, flags); + ImGui::PopItemWidth(); + ImGui::PopID(); +} + +void +Application::drawVector2Slider(Containers::StringView id, Vector2& vec, Vector2 min, Vector2 max, const char* x_format, + const char* y_format, ImGuiSliderFlags_ flags) +{ + ImGui::PushID(id.cbegin()); + ImGui::PushMultiItemsWidths(2, ImGui::CalcItemWidth()); + ImGui::SliderFloat("##X", &vec.x(), min.x(), max.x(), x_format, flags); + ImGui::PopItemWidth(); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::SliderFloat("##Y", &vec.y(), min.y(), max.y(), y_format, flags); + ImGui::PopItemWidth(); + ImGui::PopID(); +} + +void +Application::drawVector2dSlider(Containers::StringView id, Vector2d& vec, Vector2d min, Vector2d max, + const char* x_format, const char* y_format, ImGuiSliderFlags_ flags) +{ + ImGui::PushID(id.cbegin()); + ImGui::PushMultiItemsWidths(2, ImGui::CalcItemWidth()); + ImGui::SliderScalar("##X", ImGuiDataType_Double, &vec.x(), &min.x(), &max.x(), x_format, flags); + ImGui::PopItemWidth(); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::SliderScalar("##Y", ImGuiDataType_Double, &vec.y(), &min.y(), &max.y(), y_format, flags); + ImGui::PopItemWidth(); + ImGui::PopID(); +} + void Application::openUri(Containers::StringView uri) { if(!conf().isRunningInWine()) { diff --git a/src/Application/Application.h b/src/Application/Application.h index 00ce53a..12e9dbb 100644 --- a/src/Application/Application.h +++ b/src/Application/Application.h @@ -34,7 +34,6 @@ #include #include -#include #include @@ -167,6 +166,23 @@ class Application: public Platform::Sdl2Application, public efsw::FileWatchListe void drawHelpMarker(Containers::StringView text, float wrap_pos = 0.0f); void drawTooltip(Containers::StringView text, float wrap_pos = 0.0f); bool drawCheckbox(Containers::StringView label, bool value); + void drawVector3Drag(Containers::StringView id, Vector3& vec, float speed, Vector3 min, Vector3 max, + const char* x_format, const char* y_format, const char* z_format, + ImGuiSliderFlags_ flags = ImGuiSliderFlags_None); + void drawVector3dDrag(Containers::StringView id, Vector3d& vec, float speed, Vector3d min, Vector3d max, + const char* x_format, const char* y_format, const char* z_format, + ImGuiSliderFlags_ flags = ImGuiSliderFlags_None); + void drawVector3Slider(Containers::StringView id, Vector3& vec, Vector3 min, Vector3 max, const char* x_format, + const char* y_format, const char* z_format, + ImGuiSliderFlags_ flags = ImGuiSliderFlags_None); + void drawVector3dSlider(Containers::StringView id, Vector3d& vec, Vector3d min, Vector3d max, + const char* x_format, const char* y_format, const char* z_format, + ImGuiSliderFlags_ flags = ImGuiSliderFlags_None); + void drawVector2Slider(Containers::StringView id, Vector2& vec, Vector2 min, Vector2 max, const char* x_format, + const char* y_format, ImGuiSliderFlags_ flags = ImGuiSliderFlags_None); + void drawVector2dSlider(Containers::StringView id, Vector2d& vec, Vector2d min, Vector2d max, + const char* x_format, const char* y_format, + ImGuiSliderFlags_ flags = ImGuiSliderFlags_None); template bool drawUnsafeWidget(Functor func, Args... args) { diff --git a/src/Application/Application_MassViewer.cpp b/src/Application/Application_MassViewer.cpp index 1cda5f6..1bd38b9 100644 --- a/src/Application/Application_MassViewer.cpp +++ b/src/Application/Application_MassViewer.cpp @@ -19,6 +19,8 @@ #include +#include + #include "../Configuration/Configuration.h" #include "../FontAwesome/IconsFontAwesome5.h" #include "../GameData/Accessories.h" @@ -450,12 +452,17 @@ Application::drawDecalEditor(GameObjects::Decal& decal) { ImGui::SameLine(); drawHelpMarker("Right-click for more option, click the coloured square for the full picker."); - ImGui::PushMultiItemsWidths(2, ImGui::CalcItemWidth()); - ImGui::SliderFloat("##OffsetX", &decal.offset.x(), 0.0f, 1.0f, "X: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::SliderFloat("##OffsetY", &decal.offset.y(), 0.0f, 1.0f, "Y: %.3f"); - ImGui::PopItemWidth(); + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector2Slider("##Offset", arg, Vector2{0.0f}, Vector2{1.0f}, "X: %.3f", "Y: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector2dSlider("##Offset", arg, Vector2d{0.0}, Vector2d{1.0}, "X: %.3f", "Y: %.3f"); + } + }, decal.offset + ); ImGui::SameLine(); drawHelpMarker("0.0 = -100 in-game\n1.0 = 100 in-game"); @@ -489,35 +496,48 @@ Application::drawDecalEditor(GameObjects::Decal& decal) { ImGui::BeginGroup(); ImGui::PushItemWidth(-1.0f); - ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); - ImGui::DragFloat("##PosX", &decal.position.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##PosY", &decal.position.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Y: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##PosZ", &decal.position.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Z: %.3f"); - ImGui::PopItemWidth(); + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector3Drag("##Position", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, "X: %.3f", + "Y: %.3f", "Z: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector3dDrag("##Position", arg, 1.0f, Vector3d{-DBL_MAX}, Vector3d{DBL_MAX}, "X: %.3f", + "Y: %.3f", "Z: %.3f"); + } + }, decal.position + ); - ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); - ImGui::DragFloat("##UX", &decal.uAxis.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##UY", &decal.uAxis.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Y: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##UZ", &decal.uAxis.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Z: %.3f"); - ImGui::PopItemWidth(); + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector3Drag("##U", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, "X: %.3f", "Y: %.3f", + "Z: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector3dDrag("##U", arg, 1.0f, Vector3d{-DBL_MAX}, Vector3d{DBL_MAX}, "X: %.3f", "Y: %.3f", + "Z: %.3f"); + } + }, decal.uAxis + ); + + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector3Drag("##V", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, "X: %.3f", "Y: %.3f", + "Z: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector3dDrag("##V", arg, 1.0f, Vector3d{-DBL_MAX}, Vector3d{DBL_MAX}, "X: %.3f", "Y: %.3f", + "Z: %.3f"); + } + }, decal.vAxis + ); - ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); - ImGui::DragFloat("##VX", &decal.vAxis.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##VY", &decal.vAxis.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Y: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##VZ", &decal.vAxis.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Z: %.3f"); - ImGui::PopItemWidth(); ImGui::PopItemWidth(); ImGui::EndGroup(); } @@ -638,15 +658,15 @@ Application::drawAccessoryEditor(GameObjects::Accessory& accessory, Containers:: ImGui::Separator(); if(ImGui::BeginListBox("##AccessoryListbox", {-1.0f, 0.0f})) { - for(const auto& acc : GameData::accessories) { - if(acc.first >= tab * 1000 && acc.first < ((tab + 1) * 1000) && (!size || *size == acc.second.size)) { - if(ImGui::Selectable(Utility::format("#{:.4d} - {} ({})", acc.first, acc.second.name, size_labels[acc.second.size]).data(), - acc.first == accessory.id)) + for(const auto& [id, acc] : GameData::accessories) { + if(id >= tab * 1000 && id < ((tab + 1) * 1000) && (!size || *size == acc.size)) { + if(ImGui::Selectable(Utility::format("#{:.4d} - {} ({})", id, acc.name, size_labels[acc.size]).data(), + id == accessory.id)) { - accessory.id = acc.first; + accessory.id = id; accessory.attachIndex = 0; } - if(acc.first == accessory.id) { + if(id == accessory.id) { ImGui::SetItemDefaultFocus(); } } @@ -706,60 +726,78 @@ Application::drawAccessoryEditor(GameObjects::Accessory& accessory, Containers:: ImGui::PopItemWidth(); if(conf().advancedMode()) { - ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); - ImGui::DragFloat("##PosX", &accessory.relativePosition.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##PosY", &accessory.relativePosition.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Y: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##PosZ", &accessory.relativePosition.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Z: %.3f"); - ImGui::PopItemWidth(); + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector3Drag("##RelativePosition", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, "X: %.3f", + "Y: %.3f", "Z: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector3dDrag("##RelativePosition", arg, 1.0f, Vector3d{-DBL_MAX}, Vector3d{DBL_MAX}, "X: %.3f", + "Y: %.3f", "Z: %.3f"); + } + }, accessory.relativePosition + ); } - ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); - ImGui::SliderFloat("##PosOffsetX", &accessory.relativePositionOffset.x(), -500.0f, +500.0f, "X: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::SliderFloat("##PosOffsetY", &accessory.relativePositionOffset.y(), -500.0f, +500.0f, "Y: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::SliderFloat("##PosOffsetZ", &accessory.relativePositionOffset.z(), -500.0f, +500.0f, "Z: %.3f"); - ImGui::PopItemWidth(); + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector3Slider("##OffsetPosition", arg, Vector3{-500.0f}, Vector3{500.0f}, "X: %.3f", "Y: %.3f", + "Z: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector3dSlider("##OffsetPosition", arg, Vector3d{-500.0}, Vector3d{500.0}, "X: %.3f", "Y: %.3f", + "Z: %.3f"); + } + }, accessory.relativePositionOffset + ); ImGui::SameLine(); drawHelpMarker("+/-500.0 = +/-250 in-game"); if(conf().advancedMode()) { - ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); - ImGui::DragFloat("##RotX", &accessory.relativeRotation.x(), 1.0f, -FLT_MAX, +FLT_MAX, "Roll: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##RotY", &accessory.relativeRotation.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Yaw: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##RotZ", &accessory.relativeRotation.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Pitch: %.3f"); - ImGui::PopItemWidth(); + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector3Drag("##RelativeRotation", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, "Roll: %.3f", + "Yaw: %.3f", "Pitch: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector3dDrag("##RelativeRotation", arg, 1.0f, Vector3d{-DBL_MAX}, Vector3d{DBL_MAX}, + "Roll: %.3f", "Yaw: %.3f", "Pitch: %.3f"); + } + }, accessory.relativePosition + ); } - ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); - ImGui::SliderFloat("##RotOffsetX", &accessory.relativeRotationOffset.x(), -180.0f, +180.0f, "Roll: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::SliderFloat("##RotOffsetY", &accessory.relativeRotationOffset.y(), -180.0f, +180.0f, "Yaw: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::SliderFloat("##RotOffsetZ", &accessory.relativeRotationOffset.z(), -180.0f, +180.0f, "Pitch: %.3f"); - ImGui::PopItemWidth(); + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector3Slider("##OffsetRotation", arg, Vector3{-180.0f}, Vector3{180.0f}, "Roll: %.3f", + "Yaw: %.3f", "Pitch: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector3dSlider("##OffsetRotation", arg, Vector3d{-180.0}, Vector3d{180.0}, "Roll: %.3f", + "Yaw: %.3f", "Pitch: %.3f"); + } + }, accessory.relativeRotationOffset + ); - ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); - ImGui::SliderFloat("##ScaleX", &accessory.localScale.x(), -3.0f, +3.0f, "X: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::SliderFloat("##ScaleY", &accessory.localScale.y(), -3.0f, +3.0f, "Y: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::SliderFloat("##ScaleZ", &accessory.localScale.z(), -3.0f, +3.0f, "Z: %.3f"); - ImGui::PopItemWidth(); + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector3Slider("##Scale", arg, Vector3{-3.0f}, Vector3{3.0f}, "X: %.3f", "Y: %.3f", "Z: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector3dSlider("##Scale", arg, Vector3d{-3.0}, Vector3d{3.0}, "X: %.3f", "Y: %.3f", "Z: %.3f"); + } + }, accessory.localScale + ); ImGui::SameLine(); drawHelpMarker("+/-3.0 = +/-150 in-game"); ImGui::EndGroup(); diff --git a/src/Application/Application_MassViewer_Armour.cpp b/src/Application/Application_MassViewer_Armour.cpp index cc323d8..a6e5b3b 100644 --- a/src/Application/Application_MassViewer_Armour.cpp +++ b/src/Application/Application_MassViewer_Armour.cpp @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include + #include "../FontAwesome/IconsFontAwesome5.h" #include "../GameData/ArmourSets.h" #include "../GameData/StyleNames.h" @@ -267,57 +269,75 @@ Application::drawBLAttachment() { ImGui::SameLine(); ImGui::BeginGroup(); - ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); - ImGui::DragFloat("##RelPosX", &placement.relativeLocation.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##RelPosY", &placement.relativeLocation.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Y: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##RelPosZ", &placement.relativeLocation.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Z: %.3f"); - ImGui::PopItemWidth(); + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector3Drag("##RelativePosition", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, "X: %.3f", + "Y: %.3f", "Z: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector3dDrag("##RelativePosition", arg, 1.0f, Vector3d{-DBL_MAX}, Vector3d{DBL_MAX}, + "X: %.3f", "Y: %.3f", "Z: %.3f"); + } + }, placement.relativeLocation + ); - ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); - ImGui::SliderFloat("##OffPosX", &placement.offsetLocation.x(), -500.0f, +500.0f, "X: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::SliderFloat("##OffPosY", &placement.offsetLocation.y(), -500.0f, +500.0f, "Y: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::SliderFloat("##OffPosZ", &placement.offsetLocation.z(), -500.0f, +500.0f, "Z: %.3f"); - ImGui::PopItemWidth(); + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector3Slider("##OffsetPosition", arg, Vector3{-500.0f}, Vector3{500.0f}, "X: %.3f", "Y: %.3f", + "Z: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector3dSlider("##OffsetPosition", arg, Vector3d{-500.0}, Vector3d{500.0}, "X: %.3f", + "Y: %.3f", "Z: %.3f"); + } + }, placement.offsetLocation + ); ImGui::SameLine(); drawHelpMarker("+/-500.0 = +/-250 in-game"); - ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); - ImGui::DragFloat("##RotX", &placement.relativeRotation.x(), 1.0f, -FLT_MAX, +FLT_MAX, "Roll: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##RotY", &placement.relativeRotation.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Yaw: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::DragFloat("##RotZ", &placement.relativeRotation.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Pitch: %.3f"); - ImGui::PopItemWidth(); + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector3Drag("##RelativeRotation", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, + "Pitch: %.3f", "Yaw: %.3f", "Roll: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector3dDrag("##RelativeRotation", arg, 1.0f, Vector3d{-DBL_MAX}, Vector3d{DBL_MAX}, + "Pitch: %.3f", "Yaw: %.3f", "Roll: %.3f"); + } + }, placement.relativeRotation + ); - ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); - ImGui::SliderFloat("##RotOffsetZ", &placement.offsetRotation.z(), -180.0f, +180.0f, "Roll: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::SliderFloat("##RotOffsetX", &placement.offsetRotation.x(), -30.0f, +30.0f, "Pitch: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::SliderFloat("##RotOffsetY", &placement.offsetRotation.y(), -30.0f, +30.0f, "Yaw: %.3f"); - ImGui::PopItemWidth(); + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector3Slider("##OffsetRotation", arg, Vector3{-30.0f, -30.0f, -180.0f}, + Vector3{30.0f, 30.0f, 180.0f}, "Pitch: %.3f", "Yaw: %.3f", "Roll: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector3dSlider("##OffsetRotation", arg, Vector3d{-30.0, -30.0, -180.0}, + Vector3d{30.0, 30.0, 180.0}, "Pitch: %.3f", "Yaw: %.3f", "Roll: %.3f"); + } + }, placement.offsetRotation + ); - ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); - ImGui::SliderFloat("##ScaleX", &placement.relativeScale.x(), 0.5f, 1.5f, "X: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::SliderFloat("##ScaleY", &placement.relativeScale.y(), 0.5f, 1.5f, "Y: %.3f"); - ImGui::PopItemWidth(); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::SliderFloat("##ScaleZ", &placement.relativeScale.z(), 0.5f, 1.5f, "Z: %.3f"); - ImGui::PopItemWidth(); + std::visit( + [this](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + drawVector3Slider("##Scale", arg, Vector3{0.5f}, Vector3{1.5f}, "X: %.3f", "Y: %.3f", "Z: %.3f"); + } + else if constexpr (std::is_same_v) { + drawVector3dSlider("##Scale", arg, Vector3d{0.5}, Vector3d{1.5}, "X: %.3f", "Y: %.3f", "Z: %.3f"); + } + }, placement.relativeScale + ); ImGui::SameLine(); drawHelpMarker("0.5 = 50 in-game\n1.5 = 150 in-game"); ImGui::EndGroup(); diff --git a/src/Application/Application_MassViewer_Frame.cpp b/src/Application/Application_MassViewer_Frame.cpp index 49d4a71..2ccead1 100644 --- a/src/Application/Application_MassViewer_Frame.cpp +++ b/src/Application/Application_MassViewer_Frame.cpp @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include + #include "../FontAwesome/IconsFontAwesome5.h" #include "../GameData/StyleNames.h" diff --git a/src/GameObjects/Accessory.h b/src/GameObjects/Accessory.h index d6e6cae..fbc967d 100644 --- a/src/GameObjects/Accessory.h +++ b/src/GameObjects/Accessory.h @@ -16,6 +16,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include + #include #include @@ -24,17 +26,19 @@ using namespace Corrade; using namespace Magnum; +typedef std::variant Vector3Variant; + namespace mbst::GameObjects { struct Accessory { std::int32_t attachIndex = -1; std::int32_t id = -1; Containers::StaticArray<2, std::int32_t> styles{ValueInit}; - Vector3 relativePosition{0.0f}; - Vector3 relativePositionOffset{0.0f}; - Vector3 relativeRotation{0.0f}; - Vector3 relativeRotationOffset{0.0f}; - Vector3 localScale{1.0f}; + Vector3Variant relativePosition{Vector3{}}; + Vector3Variant relativePositionOffset{Vector3{}}; + Vector3Variant relativeRotation{Vector3{}}; + Vector3Variant relativeRotationOffset{Vector3{}}; + Vector3Variant localScale{Vector3{1.0f}}; }; } diff --git a/src/GameObjects/BulletLauncherAttachment.h b/src/GameObjects/BulletLauncherAttachment.h index a83ffda..6f0234a 100644 --- a/src/GameObjects/BulletLauncherAttachment.h +++ b/src/GameObjects/BulletLauncherAttachment.h @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include +#include #include #include @@ -24,6 +24,8 @@ using namespace Corrade; using namespace Magnum; +typedef std::variant Vector3Variant; + namespace mbst::GameObjects { enum class BulletLauncherAttachmentStyle { @@ -39,11 +41,11 @@ struct BulletLauncherAttachment { #undef c }; Socket socket = Socket::Auto; - Vector3 relativeLocation; - Vector3 offsetLocation; - Vector3 relativeRotation; - Vector3 offsetRotation; - Vector3 relativeScale; + Vector3Variant relativeLocation; + Vector3Variant offsetLocation; + Vector3Variant relativeRotation; + Vector3Variant offsetRotation; + Vector3Variant relativeScale; }; } diff --git a/src/GameObjects/Decal.h b/src/GameObjects/Decal.h index 7d75670..ed11afc 100644 --- a/src/GameObjects/Decal.h +++ b/src/GameObjects/Decal.h @@ -16,6 +16,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include + #include #include #include @@ -23,15 +25,18 @@ using namespace Magnum; +typedef std::variant Vector2Variant; +typedef std::variant Vector3Variant; + namespace mbst::GameObjects { struct Decal { std::int32_t id = -1; Color4 colour{0.0f}; - Vector3 position{0.0f}; - Vector3 uAxis{0.0f}; - Vector3 vAxis{0.0f}; - Vector2 offset{0.5f}; + Vector3Variant position{Vector3{}}; + Vector3Variant uAxis{Vector3{}}; + Vector3Variant vAxis{Vector3{}}; + Vector2Variant offset{Vector2{0.5f}}; float scale = 0.5f; float rotation = 0.0f; bool flip = false; diff --git a/src/GameObjects/Mass_Armour.cpp b/src/GameObjects/Mass_Armour.cpp index 2de6d08..6a27f0a 100644 --- a/src/GameObjects/Mass_Armour.cpp +++ b/src/GameObjects/Mass_Armour.cpp @@ -255,15 +255,15 @@ Mass::getBulletLauncherAttachments() { } auto rel_loc_prop = attachment_prop->at(MASS_BL_ATTACHMENT_RELLOC); - attachment.relativeLocation = Vector3{rel_loc_prop->x, rel_loc_prop->y, rel_loc_prop->z}; + attachment.relativeLocation = rel_loc_prop->vector; auto off_loc_prop = attachment_prop->at(MASS_BL_ATTACHMENT_OFFLOC); - attachment.offsetLocation = Vector3{off_loc_prop->x, off_loc_prop->y, off_loc_prop->z}; + attachment.offsetLocation = off_loc_prop->vector; auto rel_rot_prop = attachment_prop->at(MASS_BL_ATTACHMENT_RELROT); - attachment.relativeRotation = Vector3{rel_rot_prop->x, rel_rot_prop->y, rel_rot_prop->z}; + attachment.relativeRotation = rel_rot_prop->vector; auto off_rot_prop = attachment_prop->at(MASS_BL_ATTACHMENT_OFFROT); - attachment.offsetRotation = Vector3{off_rot_prop->x, off_rot_prop->y, off_rot_prop->z}; + attachment.offsetRotation = off_rot_prop->vector; auto rel_scale_prop = attachment_prop->at(MASS_BL_ATTACHMENT_RELSCALE); - attachment.relativeScale = Vector3{rel_scale_prop->x, rel_scale_prop->y, rel_scale_prop->z}; + attachment.relativeScale = rel_scale_prop->vector; } } @@ -331,25 +331,15 @@ Mass::writeBulletLauncherAttachments() { } auto rel_loc_prop = attachment_prop->at(MASS_BL_ATTACHMENT_RELLOC); - rel_loc_prop->x = attachment.relativeLocation.x(); - rel_loc_prop->y = attachment.relativeLocation.y(); - rel_loc_prop->z = attachment.relativeLocation.z(); + rel_loc_prop->vector = attachment.relativeLocation; auto off_loc_prop = attachment_prop->at(MASS_BL_ATTACHMENT_OFFLOC); - off_loc_prop->x = attachment.offsetLocation.x(); - off_loc_prop->y = attachment.offsetLocation.y(); - off_loc_prop->z = attachment.offsetLocation.z(); + off_loc_prop->vector = attachment.offsetLocation; auto rel_rot_prop = attachment_prop->at(MASS_BL_ATTACHMENT_RELROT); - rel_rot_prop->x = attachment.relativeRotation.x(); - rel_rot_prop->y = attachment.relativeRotation.y(); - rel_rot_prop->z = attachment.relativeRotation.z(); + rel_rot_prop->vector = attachment.relativeRotation; auto off_rot_prop = attachment_prop->at(MASS_BL_ATTACHMENT_OFFROT); - off_rot_prop->x = attachment.offsetRotation.x(); - off_rot_prop->y = attachment.offsetRotation.y(); - off_rot_prop->z = attachment.offsetRotation.z(); + off_rot_prop->vector = attachment.offsetRotation; auto rel_scale_prop = attachment_prop->at(MASS_BL_ATTACHMENT_RELSCALE); - rel_scale_prop->x = attachment.relativeScale.x(); - rel_scale_prop->y = attachment.relativeScale.y(); - rel_scale_prop->z = attachment.relativeScale.z(); + rel_scale_prop->vector = attachment.relativeScale; } } diff --git a/src/GameObjects/Mass_DecalsAccessories.cpp b/src/GameObjects/Mass_DecalsAccessories.cpp index 6b94fc5..02ed1b2 100644 --- a/src/GameObjects/Mass_DecalsAccessories.cpp +++ b/src/GameObjects/Mass_DecalsAccessories.cpp @@ -42,13 +42,13 @@ Mass::getDecals(Containers::ArrayView decals, Gvas::Types::ArrayProperty* auto colour_prop = decal_prop->at(MASS_DECAL_COLOUR); decal.colour = Color4{colour_prop->r, colour_prop->g, colour_prop->b, colour_prop->a}; auto pos_prop = decal_prop->at(MASS_DECAL_POSITION); - decal.position = Vector3{pos_prop->x, pos_prop->y, pos_prop->z}; + decal.position = pos_prop->vector; auto u_prop = decal_prop->at(MASS_DECAL_UAXIS); - decal.uAxis = Vector3{u_prop->x, u_prop->y, u_prop->z}; + decal.uAxis = u_prop->vector; auto v_prop = decal_prop->at(MASS_DECAL_VAXIS); - decal.vAxis = Vector3{v_prop->x, v_prop->y, v_prop->z}; + decal.vAxis = v_prop->vector; auto offset_prop = decal_prop->at(MASS_DECAL_OFFSET); - decal.offset = Vector2{offset_prop->x, offset_prop->y}; + decal.offset = offset_prop->vector; decal.scale = decal_prop->at(MASS_DECAL_SCALE)->value; decal.rotation = decal_prop->at(MASS_DECAL_ROTATION)->value; decal.flip = decal_prop->at(MASS_DECAL_FLIP)->value; @@ -70,20 +70,13 @@ Mass::writeDecals(Containers::ArrayView decals, Gvas::Types::ArrayPropert colour_prop->b = decal.colour.b(); colour_prop->a = decal.colour.a(); auto pos_prop = decal_prop->at(MASS_DECAL_POSITION); - pos_prop->x = decal.position.x(); - pos_prop->y = decal.position.y(); - pos_prop->z = decal.position.z(); + pos_prop->vector = decal.position; auto u_prop = decal_prop->at(MASS_DECAL_UAXIS); - u_prop->x = decal.uAxis.x(); - u_prop->y = decal.uAxis.y(); - u_prop->z = decal.uAxis.z(); + u_prop->vector = decal.uAxis; auto v_prop = decal_prop->at(MASS_DECAL_VAXIS); - v_prop->x = decal.vAxis.x(); - v_prop->y = decal.vAxis.y(); - v_prop->z = decal.vAxis.z(); + v_prop->vector = decal.vAxis; auto offset_prop = decal_prop->at(MASS_DECAL_OFFSET); - offset_prop->x = decal.offset.x(); - offset_prop->y = decal.offset.y(); + offset_prop->vector = decal.offset; decal_prop->at(MASS_DECAL_SCALE)->value = decal.scale; decal_prop->at(MASS_DECAL_ROTATION)->value = decal.rotation; decal_prop->at(MASS_DECAL_FLIP)->value = decal.flip; @@ -105,15 +98,15 @@ Mass::getAccessories(Containers::ArrayView accessories, Gvas::Types:: accessory.styles[j] = acc_styles->at(j)->value; } auto rel_pos_prop = acc_prop->at(MASS_ACCESSORY_RELPOS); - accessory.relativePosition = Vector3{rel_pos_prop->x, rel_pos_prop->y, rel_pos_prop->z}; + accessory.relativePosition = rel_pos_prop->vector; auto rel_pos_offset_prop = acc_prop->at(MASS_ACCESSORY_OFFPOS); - accessory.relativePositionOffset = Vector3{rel_pos_offset_prop->x, rel_pos_offset_prop->y, rel_pos_offset_prop->z}; + accessory.relativePositionOffset = rel_pos_offset_prop->vector; auto rel_rot_prop = acc_prop->at(MASS_ACCESSORY_RELROT); - accessory.relativeRotation = Vector3{rel_rot_prop->x, rel_rot_prop->y, rel_rot_prop->z}; + accessory.relativeRotation = rel_rot_prop->vector; auto rel_rot_offset_prop = acc_prop->at(MASS_ACCESSORY_OFFROT); - accessory.relativeRotationOffset = Vector3{rel_rot_offset_prop->x, rel_rot_offset_prop->y, rel_rot_offset_prop->z}; + accessory.relativeRotationOffset = rel_rot_offset_prop->vector; auto local_scale_prop = acc_prop->at(MASS_ACCESSORY_SCALE); - accessory.localScale = Vector3{local_scale_prop->x, local_scale_prop->y, local_scale_prop->z}; + accessory.localScale = local_scale_prop->vector; } } @@ -131,25 +124,15 @@ Mass::writeAccessories(Containers::ArrayView accessories, Gvas::Types acc_styles->at(j)->value = accessory.styles[j]; } auto rel_pos_prop = acc_prop->at(MASS_ACCESSORY_RELPOS); - rel_pos_prop->x = accessory.relativePosition.x(); - rel_pos_prop->y = accessory.relativePosition.y(); - rel_pos_prop->z = accessory.relativePosition.z(); + rel_pos_prop->vector = accessory.relativePosition; auto rel_pos_offset_prop = acc_prop->at(MASS_ACCESSORY_OFFPOS); - rel_pos_offset_prop->x = accessory.relativePositionOffset.x(); - rel_pos_offset_prop->y = accessory.relativePositionOffset.y(); - rel_pos_offset_prop->z = accessory.relativePositionOffset.z(); + rel_pos_offset_prop->vector = accessory.relativePositionOffset; auto rel_rot_prop = acc_prop->at(MASS_ACCESSORY_RELROT); - rel_rot_prop->x = accessory.relativeRotation.x(); - rel_rot_prop->y = accessory.relativeRotation.y(); - rel_rot_prop->z = accessory.relativeRotation.z(); + rel_rot_prop->vector = accessory.relativeRotation; auto rel_rot_offset_prop = acc_prop->at(MASS_ACCESSORY_OFFROT); - rel_rot_offset_prop->x = accessory.relativeRotationOffset.x(); - rel_rot_offset_prop->y = accessory.relativeRotationOffset.y(); - rel_rot_offset_prop->z = accessory.relativeRotationOffset.z(); + rel_rot_offset_prop->vector = accessory.relativeRotationOffset; auto local_scale_prop = acc_prop->at(MASS_ACCESSORY_SCALE); - local_scale_prop->x = accessory.localScale.x(); - local_scale_prop->y = accessory.localScale.y(); - local_scale_prop->z = accessory.localScale.z(); + local_scale_prop->vector = accessory.localScale; } } diff --git a/src/Gvas/Serialisers/RotatorProperty.cpp b/src/Gvas/Serialisers/RotatorProperty.cpp index bb495d9..380a618 100644 --- a/src/Gvas/Serialisers/RotatorProperty.cpp +++ b/src/Gvas/Serialisers/RotatorProperty.cpp @@ -28,9 +28,25 @@ RotatorProperty::deserialiseProperty(Containers::StringView name, Containers::St { auto prop = Containers::pointer(); - if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y) || !reader.readFloat(prop->z)) { - LOG_ERROR_FORMAT("Couldn't read rotator property {}'s value.", name); - return nullptr; + if(value_length == 12) { // UE4 + float x, y, z; + + if(!reader.readFloat(x) || !reader.readFloat(y) || !reader.readFloat(z)) { + LOG_ERROR_FORMAT("Couldn't read rotator property {}'s value.", name); + return nullptr; + } + + prop->vector = Vector3{x, y, z}; + } + else if(value_length == 24) { // UE5 + double x, y, z; + + if(!reader.readDouble(x) || !reader.readDouble(y) || !reader.readDouble(z)) { + LOG_ERROR_FORMAT("Couldn't read rotator property {}'s value.", name); + return nullptr; + } + + prop->vector = Vector3d{x, y, z}; } return prop; @@ -46,9 +62,21 @@ RotatorProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::si return false; } - bytes_written += writer.writeValueToArray(rotator->x) + - writer.writeValueToArray(rotator->y) + - writer.writeValueToArray(rotator->z); + std::visit( + [&bytes_written, &writer](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + bytes_written += writer.writeValueToArray(arg.x()) + + writer.writeValueToArray(arg.y()) + + writer.writeValueToArray(arg.z()); + } + else if constexpr (std::is_same_v) { + bytes_written += writer.writeValueToArray(arg.x()) + + writer.writeValueToArray(arg.y()) + + writer.writeValueToArray(arg.z()); + } + }, rotator->vector + ); return true; } diff --git a/src/Gvas/Serialisers/Vector2DProperty.cpp b/src/Gvas/Serialisers/Vector2DProperty.cpp index 97d228f..48adf80 100644 --- a/src/Gvas/Serialisers/Vector2DProperty.cpp +++ b/src/Gvas/Serialisers/Vector2DProperty.cpp @@ -29,9 +29,25 @@ Vector2DProperty::deserialiseProperty(Containers::StringView name, Containers::S { auto prop = Containers::pointer(); - if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y)) { - LOG_ERROR_FORMAT("Couldn't read 2D vector property {}'s value.", name); - return nullptr; + if(value_length == 8) { // UE4 + float x, y; + + if(!reader.readFloat(x) || !reader.readFloat(y)) { + LOG_ERROR_FORMAT("Couldn't read 2D vector property {}'s value.", name); + return nullptr; + } + + prop->vector = Vector2{x, y}; + } + else if(value_length == 16) { // UE5 + double x, y; + + if(!reader.readDouble(x) || !reader.readDouble(y)) { + LOG_ERROR_FORMAT("Couldn't read 2D vector property {}'s value.", name); + return nullptr; + } + + prop->vector = Vector2d{x, y}; } return prop; @@ -47,8 +63,19 @@ Vector2DProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::s return false; } - bytes_written += writer.writeValueToArray(vector->x) + - writer.writeValueToArray(vector->y); + std::visit( + [&bytes_written, &writer](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + bytes_written += writer.writeValueToArray(arg.x()) + + writer.writeValueToArray(arg.y()); + } + else if constexpr (std::is_same_v) { + bytes_written += writer.writeValueToArray(arg.x()) + + writer.writeValueToArray(arg.y()); + } + }, vector->vector + ); return true; } diff --git a/src/Gvas/Serialisers/VectorProperty.cpp b/src/Gvas/Serialisers/VectorProperty.cpp index 3243a1f..b66a64f 100644 --- a/src/Gvas/Serialisers/VectorProperty.cpp +++ b/src/Gvas/Serialisers/VectorProperty.cpp @@ -29,9 +29,25 @@ VectorProperty::deserialiseProperty(Containers::StringView name, Containers::Str { auto prop = Containers::pointer(); - if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y) || !reader.readFloat(prop->z)) { - LOG_ERROR_FORMAT("Couldn't read vector property {}'s value.", name); - return nullptr; + if(value_length == 12) { // UE4 + float x, y, z; + + if(!reader.readFloat(x) || !reader.readFloat(y) || !reader.readFloat(z)) { + LOG_ERROR_FORMAT("Couldn't read vector property {}'s value.", name); + return nullptr; + } + + prop->vector = Vector3{x, y, z}; + } + else if(value_length == 24) { // UE5 + double x, y, z; + + if(!reader.readDouble(x) || !reader.readDouble(y) || !reader.readDouble(z)) { + LOG_ERROR_FORMAT("Couldn't read vector property {}'s value.", name); + return nullptr; + } + + prop->vector = Vector3d{x, y, z}; } return prop; @@ -47,9 +63,21 @@ VectorProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::siz return false; } - bytes_written += writer.writeValueToArray(vector->x) + - writer.writeValueToArray(vector->y) + - writer.writeValueToArray(vector->z); + std::visit( + [&bytes_written, &writer](auto& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) { + bytes_written += writer.writeValueToArray(arg.x()) + + writer.writeValueToArray(arg.y()) + + writer.writeValueToArray(arg.z()); + } + else if constexpr (std::is_same_v) { + bytes_written += writer.writeValueToArray(arg.x()) + + writer.writeValueToArray(arg.y()) + + writer.writeValueToArray(arg.z()); + } + }, vector->vector + ); return true; } diff --git a/src/Gvas/Types/RotatorStructProperty.h b/src/Gvas/Types/RotatorStructProperty.h index 26d353f..7260930 100644 --- a/src/Gvas/Types/RotatorStructProperty.h +++ b/src/Gvas/Types/RotatorStructProperty.h @@ -16,12 +16,19 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include + #include #include +#include + #include "StructProperty.h" using namespace Corrade; +using namespace Magnum; + +typedef std::variant Vector3Variant; namespace Gvas::Types { @@ -33,7 +40,7 @@ struct RotatorStructProperty : public StructProperty { structType = "Rotator"_s; } - float x = 0.0f, y = 0.0f, z = 0.0f; + Vector3Variant vector; }; } diff --git a/src/Gvas/Types/Vector2DStructProperty.h b/src/Gvas/Types/Vector2DStructProperty.h index f6a7e1f..6a2afeb 100644 --- a/src/Gvas/Types/Vector2DStructProperty.h +++ b/src/Gvas/Types/Vector2DStructProperty.h @@ -16,12 +16,19 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include + #include #include +#include + #include "StructProperty.h" using namespace Corrade; +using namespace Magnum; + +typedef std::variant Vector2Variant; namespace Gvas::Types { @@ -33,7 +40,7 @@ struct Vector2DStructProperty : public StructProperty { structType = "Vector2D"_s; } - float x = 0.0f, y = 0.0f; + Vector2Variant vector; }; } diff --git a/src/Gvas/Types/VectorStructProperty.h b/src/Gvas/Types/VectorStructProperty.h index c65c117..e9bda3e 100644 --- a/src/Gvas/Types/VectorStructProperty.h +++ b/src/Gvas/Types/VectorStructProperty.h @@ -16,12 +16,19 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include + #include #include +#include + #include "StructProperty.h" using namespace Corrade; +using namespace Magnum; + +typedef std::variant Vector3Variant; namespace Gvas::Types { @@ -33,7 +40,7 @@ struct VectorStructProperty : public StructProperty { structType = "Vector"_s; } - float x = 0.0f, y = 0.0f, z = 0.0f; + Vector3Variant vector{Vector3{}}; }; }