1.5: Fuckin' UE5... #38

Manually merged
williamjcm merged 126 commits from one-point-five into master 2024-07-22 11:06:13 +02:00
16 changed files with 484 additions and 220 deletions
Showing only changes of commit 8b8fbee6ba - Show all commits

View file

@ -27,6 +27,8 @@
#include <SDL.h> #include <SDL.h>
#include <imgui_internal.h>
#include <wtypesbase.h> #include <wtypesbase.h>
#include <shellapi.h> #include <shellapi.h>
#include <wtsapi32.h> #include <wtsapi32.h>
@ -419,6 +421,104 @@ Application::drawCheckbox(Containers::StringView label, bool value) {
return ImGui::Checkbox(label.data(), &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 void
Application::openUri(Containers::StringView uri) { Application::openUri(Containers::StringView uri) {
if(!conf().isRunningInWine()) { if(!conf().isRunningInWine()) {

View file

@ -34,7 +34,6 @@
#include <SDL_timer.h> #include <SDL_timer.h>
#include <imgui.h> #include <imgui.h>
#include <imgui_internal.h>
#include <efsw/efsw.hpp> #include <efsw/efsw.hpp>
@ -167,6 +166,23 @@ class Application: public Platform::Sdl2Application, public efsw::FileWatchListe
void drawHelpMarker(Containers::StringView text, float wrap_pos = 0.0f); void drawHelpMarker(Containers::StringView text, float wrap_pos = 0.0f);
void drawTooltip(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); 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<typename Functor, typename... Args> template<typename Functor, typename... Args>
bool drawUnsafeWidget(Functor func, Args... args) { bool drawUnsafeWidget(Functor func, Args... args) {

View file

@ -19,6 +19,8 @@
#include <Magnum/ImGuiIntegration/Integration.h> #include <Magnum/ImGuiIntegration/Integration.h>
#include <imgui_internal.h>
#include "../Configuration/Configuration.h" #include "../Configuration/Configuration.h"
#include "../FontAwesome/IconsFontAwesome5.h" #include "../FontAwesome/IconsFontAwesome5.h"
#include "../GameData/Accessories.h" #include "../GameData/Accessories.h"
@ -450,12 +452,17 @@ Application::drawDecalEditor(GameObjects::Decal& decal) {
ImGui::SameLine(); ImGui::SameLine();
drawHelpMarker("Right-click for more option, click the coloured square for the full picker."); drawHelpMarker("Right-click for more option, click the coloured square for the full picker.");
ImGui::PushMultiItemsWidths(2, ImGui::CalcItemWidth()); std::visit(
ImGui::SliderFloat("##OffsetX", &decal.offset.x(), 0.0f, 1.0f, "X: %.3f"); [this](auto& arg){
ImGui::PopItemWidth(); using T = std::decay_t<decltype(arg)>;
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); if constexpr (std::is_same_v<T, Vector2>) {
ImGui::SliderFloat("##OffsetY", &decal.offset.y(), 0.0f, 1.0f, "Y: %.3f"); drawVector2Slider("##Offset", arg, Vector2{0.0f}, Vector2{1.0f}, "X: %.3f", "Y: %.3f");
ImGui::PopItemWidth(); }
else if constexpr (std::is_same_v<T, Vector2d>) {
drawVector2dSlider("##Offset", arg, Vector2d{0.0}, Vector2d{1.0}, "X: %.3f", "Y: %.3f");
}
}, decal.offset
);
ImGui::SameLine(); ImGui::SameLine();
drawHelpMarker("0.0 = -100 in-game\n1.0 = 100 in-game"); drawHelpMarker("0.0 = -100 in-game\n1.0 = 100 in-game");
@ -489,35 +496,48 @@ Application::drawDecalEditor(GameObjects::Decal& decal) {
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::PushItemWidth(-1.0f); ImGui::PushItemWidth(-1.0f);
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); std::visit(
ImGui::DragFloat("##PosX", &decal.position.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f"); [this](auto& arg){
ImGui::PopItemWidth(); using T = std::decay_t<decltype(arg)>;
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); if constexpr (std::is_same_v<T, Vector3>) {
ImGui::DragFloat("##PosY", &decal.position.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Y: %.3f"); drawVector3Drag("##Position", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, "X: %.3f",
ImGui::PopItemWidth(); "Y: %.3f", "Z: %.3f");
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); }
ImGui::DragFloat("##PosZ", &decal.position.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Z: %.3f"); else if constexpr (std::is_same_v<T, Vector3d>) {
ImGui::PopItemWidth(); drawVector3dDrag("##Position", arg, 1.0f, Vector3d{-DBL_MAX}, Vector3d{DBL_MAX}, "X: %.3f",
"Y: %.3f", "Z: %.3f");
}
}, decal.position
);
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); std::visit(
ImGui::DragFloat("##UX", &decal.uAxis.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f"); [this](auto& arg){
ImGui::PopItemWidth(); using T = std::decay_t<decltype(arg)>;
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); if constexpr (std::is_same_v<T, Vector3>) {
ImGui::DragFloat("##UY", &decal.uAxis.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Y: %.3f"); drawVector3Drag("##U", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, "X: %.3f", "Y: %.3f",
ImGui::PopItemWidth(); "Z: %.3f");
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); }
ImGui::DragFloat("##UZ", &decal.uAxis.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Z: %.3f"); else if constexpr (std::is_same_v<T, Vector3d>) {
ImGui::PopItemWidth(); 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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
drawVector3Drag("##V", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, "X: %.3f", "Y: %.3f",
"Z: %.3f");
}
else if constexpr (std::is_same_v<T, Vector3d>) {
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::PopItemWidth();
ImGui::EndGroup(); ImGui::EndGroup();
} }
@ -638,15 +658,15 @@ Application::drawAccessoryEditor(GameObjects::Accessory& accessory, Containers::
ImGui::Separator(); ImGui::Separator();
if(ImGui::BeginListBox("##AccessoryListbox", {-1.0f, 0.0f})) { if(ImGui::BeginListBox("##AccessoryListbox", {-1.0f, 0.0f})) {
for(const auto& acc : GameData::accessories) { for(const auto& [id, acc] : GameData::accessories) {
if(acc.first >= tab * 1000 && acc.first < ((tab + 1) * 1000) && (!size || *size == acc.second.size)) { if(id >= tab * 1000 && id < ((tab + 1) * 1000) && (!size || *size == acc.size)) {
if(ImGui::Selectable(Utility::format("#{:.4d} - {} ({})", acc.first, acc.second.name, size_labels[acc.second.size]).data(), if(ImGui::Selectable(Utility::format("#{:.4d} - {} ({})", id, acc.name, size_labels[acc.size]).data(),
acc.first == accessory.id)) id == accessory.id))
{ {
accessory.id = acc.first; accessory.id = id;
accessory.attachIndex = 0; accessory.attachIndex = 0;
} }
if(acc.first == accessory.id) { if(id == accessory.id) {
ImGui::SetItemDefaultFocus(); ImGui::SetItemDefaultFocus();
} }
} }
@ -706,60 +726,78 @@ Application::drawAccessoryEditor(GameObjects::Accessory& accessory, Containers::
ImGui::PopItemWidth(); ImGui::PopItemWidth();
if(conf().advancedMode()) { if(conf().advancedMode()) {
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); std::visit(
ImGui::DragFloat("##PosX", &accessory.relativePosition.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f"); [this](auto& arg){
ImGui::PopItemWidth(); using T = std::decay_t<decltype(arg)>;
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); if constexpr (std::is_same_v<T, Vector3>) {
ImGui::DragFloat("##PosY", &accessory.relativePosition.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Y: %.3f"); drawVector3Drag("##RelativePosition", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, "X: %.3f",
ImGui::PopItemWidth(); "Y: %.3f", "Z: %.3f");
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); }
ImGui::DragFloat("##PosZ", &accessory.relativePosition.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Z: %.3f"); else if constexpr (std::is_same_v<T, Vector3d>) {
ImGui::PopItemWidth(); drawVector3dDrag("##RelativePosition", arg, 1.0f, Vector3d{-DBL_MAX}, Vector3d{DBL_MAX}, "X: %.3f",
"Y: %.3f", "Z: %.3f");
}
}, accessory.relativePosition
);
} }
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); std::visit(
ImGui::SliderFloat("##PosOffsetX", &accessory.relativePositionOffset.x(), -500.0f, +500.0f, "X: %.3f"); [this](auto& arg){
ImGui::PopItemWidth(); using T = std::decay_t<decltype(arg)>;
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); if constexpr (std::is_same_v<T, Vector3>) {
ImGui::SliderFloat("##PosOffsetY", &accessory.relativePositionOffset.y(), -500.0f, +500.0f, "Y: %.3f"); drawVector3Slider("##OffsetPosition", arg, Vector3{-500.0f}, Vector3{500.0f}, "X: %.3f", "Y: %.3f",
ImGui::PopItemWidth(); "Z: %.3f");
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); }
ImGui::SliderFloat("##PosOffsetZ", &accessory.relativePositionOffset.z(), -500.0f, +500.0f, "Z: %.3f"); else if constexpr (std::is_same_v<T, Vector3d>) {
ImGui::PopItemWidth(); drawVector3dSlider("##OffsetPosition", arg, Vector3d{-500.0}, Vector3d{500.0}, "X: %.3f", "Y: %.3f",
"Z: %.3f");
}
}, accessory.relativePositionOffset
);
ImGui::SameLine(); ImGui::SameLine();
drawHelpMarker("+/-500.0 = +/-250 in-game"); drawHelpMarker("+/-500.0 = +/-250 in-game");
if(conf().advancedMode()) { if(conf().advancedMode()) {
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); std::visit(
ImGui::DragFloat("##RotX", &accessory.relativeRotation.x(), 1.0f, -FLT_MAX, +FLT_MAX, "Roll: %.3f"); [this](auto& arg){
ImGui::PopItemWidth(); using T = std::decay_t<decltype(arg)>;
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); if constexpr (std::is_same_v<T, Vector3>) {
ImGui::DragFloat("##RotY", &accessory.relativeRotation.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Yaw: %.3f"); drawVector3Drag("##RelativeRotation", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, "Roll: %.3f",
ImGui::PopItemWidth(); "Yaw: %.3f", "Pitch: %.3f");
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); }
ImGui::DragFloat("##RotZ", &accessory.relativeRotation.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Pitch: %.3f"); else if constexpr (std::is_same_v<T, Vector3d>) {
ImGui::PopItemWidth(); drawVector3dDrag("##RelativeRotation", arg, 1.0f, Vector3d{-DBL_MAX}, Vector3d{DBL_MAX},
"Roll: %.3f", "Yaw: %.3f", "Pitch: %.3f");
}
}, accessory.relativePosition
);
} }
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); std::visit(
ImGui::SliderFloat("##RotOffsetX", &accessory.relativeRotationOffset.x(), -180.0f, +180.0f, "Roll: %.3f"); [this](auto& arg){
ImGui::PopItemWidth(); using T = std::decay_t<decltype(arg)>;
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); if constexpr (std::is_same_v<T, Vector3>) {
ImGui::SliderFloat("##RotOffsetY", &accessory.relativeRotationOffset.y(), -180.0f, +180.0f, "Yaw: %.3f"); drawVector3Slider("##OffsetRotation", arg, Vector3{-180.0f}, Vector3{180.0f}, "Roll: %.3f",
ImGui::PopItemWidth(); "Yaw: %.3f", "Pitch: %.3f");
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); }
ImGui::SliderFloat("##RotOffsetZ", &accessory.relativeRotationOffset.z(), -180.0f, +180.0f, "Pitch: %.3f"); else if constexpr (std::is_same_v<T, Vector3d>) {
ImGui::PopItemWidth(); drawVector3dSlider("##OffsetRotation", arg, Vector3d{-180.0}, Vector3d{180.0}, "Roll: %.3f",
"Yaw: %.3f", "Pitch: %.3f");
}
}, accessory.relativeRotationOffset
);
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); std::visit(
ImGui::SliderFloat("##ScaleX", &accessory.localScale.x(), -3.0f, +3.0f, "X: %.3f"); [this](auto& arg){
ImGui::PopItemWidth(); using T = std::decay_t<decltype(arg)>;
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); if constexpr (std::is_same_v<T, Vector3>) {
ImGui::SliderFloat("##ScaleY", &accessory.localScale.y(), -3.0f, +3.0f, "Y: %.3f"); drawVector3Slider("##Scale", arg, Vector3{-3.0f}, Vector3{3.0f}, "X: %.3f", "Y: %.3f", "Z: %.3f");
ImGui::PopItemWidth(); }
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); else if constexpr (std::is_same_v<T, Vector3d>) {
ImGui::SliderFloat("##ScaleZ", &accessory.localScale.z(), -3.0f, +3.0f, "Z: %.3f"); drawVector3dSlider("##Scale", arg, Vector3d{-3.0}, Vector3d{3.0}, "X: %.3f", "Y: %.3f", "Z: %.3f");
ImGui::PopItemWidth(); }
}, accessory.localScale
);
ImGui::SameLine(); ImGui::SameLine();
drawHelpMarker("+/-3.0 = +/-150 in-game"); drawHelpMarker("+/-3.0 = +/-150 in-game");
ImGui::EndGroup(); ImGui::EndGroup();

View file

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <imgui_internal.h>
#include "../FontAwesome/IconsFontAwesome5.h" #include "../FontAwesome/IconsFontAwesome5.h"
#include "../GameData/ArmourSets.h" #include "../GameData/ArmourSets.h"
#include "../GameData/StyleNames.h" #include "../GameData/StyleNames.h"
@ -267,57 +269,75 @@ Application::drawBLAttachment() {
ImGui::SameLine(); ImGui::SameLine();
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); std::visit(
ImGui::DragFloat("##RelPosX", &placement.relativeLocation.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f"); [this](auto& arg){
ImGui::PopItemWidth(); using T = std::decay_t<decltype(arg)>;
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); if constexpr (std::is_same_v<T, Vector3>) {
ImGui::DragFloat("##RelPosY", &placement.relativeLocation.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Y: %.3f"); drawVector3Drag("##RelativePosition", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, "X: %.3f",
ImGui::PopItemWidth(); "Y: %.3f", "Z: %.3f");
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); }
ImGui::DragFloat("##RelPosZ", &placement.relativeLocation.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Z: %.3f"); else if constexpr (std::is_same_v<T, Vector3d>) {
ImGui::PopItemWidth(); drawVector3dDrag("##RelativePosition", arg, 1.0f, Vector3d{-DBL_MAX}, Vector3d{DBL_MAX},
"X: %.3f", "Y: %.3f", "Z: %.3f");
}
}, placement.relativeLocation
);
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); std::visit(
ImGui::SliderFloat("##OffPosX", &placement.offsetLocation.x(), -500.0f, +500.0f, "X: %.3f"); [this](auto& arg){
ImGui::PopItemWidth(); using T = std::decay_t<decltype(arg)>;
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); if constexpr (std::is_same_v<T, Vector3>) {
ImGui::SliderFloat("##OffPosY", &placement.offsetLocation.y(), -500.0f, +500.0f, "Y: %.3f"); drawVector3Slider("##OffsetPosition", arg, Vector3{-500.0f}, Vector3{500.0f}, "X: %.3f", "Y: %.3f",
ImGui::PopItemWidth(); "Z: %.3f");
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); }
ImGui::SliderFloat("##OffPosZ", &placement.offsetLocation.z(), -500.0f, +500.0f, "Z: %.3f"); else if constexpr (std::is_same_v<T, Vector3d>) {
ImGui::PopItemWidth(); drawVector3dSlider("##OffsetPosition", arg, Vector3d{-500.0}, Vector3d{500.0}, "X: %.3f",
"Y: %.3f", "Z: %.3f");
}
}, placement.offsetLocation
);
ImGui::SameLine(); ImGui::SameLine();
drawHelpMarker("+/-500.0 = +/-250 in-game"); drawHelpMarker("+/-500.0 = +/-250 in-game");
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); std::visit(
ImGui::DragFloat("##RotX", &placement.relativeRotation.x(), 1.0f, -FLT_MAX, +FLT_MAX, "Roll: %.3f"); [this](auto& arg){
ImGui::PopItemWidth(); using T = std::decay_t<decltype(arg)>;
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); if constexpr (std::is_same_v<T, Vector3>) {
ImGui::DragFloat("##RotY", &placement.relativeRotation.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Yaw: %.3f"); drawVector3Drag("##RelativeRotation", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX},
ImGui::PopItemWidth(); "Pitch: %.3f", "Yaw: %.3f", "Roll: %.3f");
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); }
ImGui::DragFloat("##RotZ", &placement.relativeRotation.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Pitch: %.3f"); else if constexpr (std::is_same_v<T, Vector3d>) {
ImGui::PopItemWidth(); drawVector3dDrag("##RelativeRotation", arg, 1.0f, Vector3d{-DBL_MAX}, Vector3d{DBL_MAX},
"Pitch: %.3f", "Yaw: %.3f", "Roll: %.3f");
}
}, placement.relativeRotation
);
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); std::visit(
ImGui::SliderFloat("##RotOffsetZ", &placement.offsetRotation.z(), -180.0f, +180.0f, "Roll: %.3f"); [this](auto& arg){
ImGui::PopItemWidth(); using T = std::decay_t<decltype(arg)>;
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); if constexpr (std::is_same_v<T, Vector3>) {
ImGui::SliderFloat("##RotOffsetX", &placement.offsetRotation.x(), -30.0f, +30.0f, "Pitch: %.3f"); drawVector3Slider("##OffsetRotation", arg, Vector3{-30.0f, -30.0f, -180.0f},
ImGui::PopItemWidth(); Vector3{30.0f, 30.0f, 180.0f}, "Pitch: %.3f", "Yaw: %.3f", "Roll: %.3f");
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); }
ImGui::SliderFloat("##RotOffsetY", &placement.offsetRotation.y(), -30.0f, +30.0f, "Yaw: %.3f"); else if constexpr (std::is_same_v<T, Vector3d>) {
ImGui::PopItemWidth(); 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()); std::visit(
ImGui::SliderFloat("##ScaleX", &placement.relativeScale.x(), 0.5f, 1.5f, "X: %.3f"); [this](auto& arg){
ImGui::PopItemWidth(); using T = std::decay_t<decltype(arg)>;
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); if constexpr (std::is_same_v<T, Vector3>) {
ImGui::SliderFloat("##ScaleY", &placement.relativeScale.y(), 0.5f, 1.5f, "Y: %.3f"); drawVector3Slider("##Scale", arg, Vector3{0.5f}, Vector3{1.5f}, "X: %.3f", "Y: %.3f", "Z: %.3f");
ImGui::PopItemWidth(); }
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); else if constexpr (std::is_same_v<T, Vector3d>) {
ImGui::SliderFloat("##ScaleZ", &placement.relativeScale.z(), 0.5f, 1.5f, "Z: %.3f"); drawVector3dSlider("##Scale", arg, Vector3d{0.5}, Vector3d{1.5}, "X: %.3f", "Y: %.3f", "Z: %.3f");
ImGui::PopItemWidth(); }
}, placement.relativeScale
);
ImGui::SameLine(); ImGui::SameLine();
drawHelpMarker("0.5 = 50 in-game\n1.5 = 150 in-game"); drawHelpMarker("0.5 = 50 in-game\n1.5 = 150 in-game");
ImGui::EndGroup(); ImGui::EndGroup();

View file

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <imgui_internal.h>
#include "../FontAwesome/IconsFontAwesome5.h" #include "../FontAwesome/IconsFontAwesome5.h"
#include "../GameData/StyleNames.h" #include "../GameData/StyleNames.h"

View file

@ -16,6 +16,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <variant>
#include <Corrade/Containers/StaticArray.h> #include <Corrade/Containers/StaticArray.h>
#include <Magnum/Magnum.h> #include <Magnum/Magnum.h>
@ -24,17 +26,19 @@
using namespace Corrade; using namespace Corrade;
using namespace Magnum; using namespace Magnum;
typedef std::variant<Vector3, Vector3d> Vector3Variant;
namespace mbst::GameObjects { namespace mbst::GameObjects {
struct Accessory { struct Accessory {
std::int32_t attachIndex = -1; std::int32_t attachIndex = -1;
std::int32_t id = -1; std::int32_t id = -1;
Containers::StaticArray<2, std::int32_t> styles{ValueInit}; Containers::StaticArray<2, std::int32_t> styles{ValueInit};
Vector3 relativePosition{0.0f}; Vector3Variant relativePosition{Vector3{}};
Vector3 relativePositionOffset{0.0f}; Vector3Variant relativePositionOffset{Vector3{}};
Vector3 relativeRotation{0.0f}; Vector3Variant relativeRotation{Vector3{}};
Vector3 relativeRotationOffset{0.0f}; Vector3Variant relativeRotationOffset{Vector3{}};
Vector3 localScale{1.0f}; Vector3Variant localScale{Vector3{1.0f}};
}; };
} }

View file

@ -16,7 +16,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <Corrade/Containers/String.h> #include <variant>
#include <Magnum/Magnum.h> #include <Magnum/Magnum.h>
#include <Magnum/Math/Vector3.h> #include <Magnum/Math/Vector3.h>
@ -24,6 +24,8 @@
using namespace Corrade; using namespace Corrade;
using namespace Magnum; using namespace Magnum;
typedef std::variant<Vector3, Vector3d> Vector3Variant;
namespace mbst::GameObjects { namespace mbst::GameObjects {
enum class BulletLauncherAttachmentStyle { enum class BulletLauncherAttachmentStyle {
@ -39,11 +41,11 @@ struct BulletLauncherAttachment {
#undef c #undef c
}; };
Socket socket = Socket::Auto; Socket socket = Socket::Auto;
Vector3 relativeLocation; Vector3Variant relativeLocation;
Vector3 offsetLocation; Vector3Variant offsetLocation;
Vector3 relativeRotation; Vector3Variant relativeRotation;
Vector3 offsetRotation; Vector3Variant offsetRotation;
Vector3 relativeScale; Vector3Variant relativeScale;
}; };
} }

View file

@ -16,6 +16,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <variant>
#include <Magnum/Magnum.h> #include <Magnum/Magnum.h>
#include <Magnum/Math/Color.h> #include <Magnum/Math/Color.h>
#include <Magnum/Math/Vector2.h> #include <Magnum/Math/Vector2.h>
@ -23,15 +25,18 @@
using namespace Magnum; using namespace Magnum;
typedef std::variant<Vector2, Vector2d> Vector2Variant;
typedef std::variant<Vector3, Vector3d> Vector3Variant;
namespace mbst::GameObjects { namespace mbst::GameObjects {
struct Decal { struct Decal {
std::int32_t id = -1; std::int32_t id = -1;
Color4 colour{0.0f}; Color4 colour{0.0f};
Vector3 position{0.0f}; Vector3Variant position{Vector3{}};
Vector3 uAxis{0.0f}; Vector3Variant uAxis{Vector3{}};
Vector3 vAxis{0.0f}; Vector3Variant vAxis{Vector3{}};
Vector2 offset{0.5f}; Vector2Variant offset{Vector2{0.5f}};
float scale = 0.5f; float scale = 0.5f;
float rotation = 0.0f; float rotation = 0.0f;
bool flip = false; bool flip = false;

View file

@ -255,15 +255,15 @@ Mass::getBulletLauncherAttachments() {
} }
auto rel_loc_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_RELLOC); auto rel_loc_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_OFFLOC); auto off_loc_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_RELROT); auto rel_rot_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_OFFROT); auto off_rot_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_RELSCALE); auto rel_scale_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_RELLOC); auto rel_loc_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_RELLOC);
rel_loc_prop->x = attachment.relativeLocation.x(); rel_loc_prop->vector = attachment.relativeLocation;
rel_loc_prop->y = attachment.relativeLocation.y();
rel_loc_prop->z = attachment.relativeLocation.z();
auto off_loc_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_OFFLOC); auto off_loc_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_OFFLOC);
off_loc_prop->x = attachment.offsetLocation.x(); off_loc_prop->vector = attachment.offsetLocation;
off_loc_prop->y = attachment.offsetLocation.y();
off_loc_prop->z = attachment.offsetLocation.z();
auto rel_rot_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_RELROT); auto rel_rot_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_RELROT);
rel_rot_prop->x = attachment.relativeRotation.x(); rel_rot_prop->vector = attachment.relativeRotation;
rel_rot_prop->y = attachment.relativeRotation.y();
rel_rot_prop->z = attachment.relativeRotation.z();
auto off_rot_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_OFFROT); auto off_rot_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_OFFROT);
off_rot_prop->x = attachment.offsetRotation.x(); off_rot_prop->vector = attachment.offsetRotation;
off_rot_prop->y = attachment.offsetRotation.y();
off_rot_prop->z = attachment.offsetRotation.z();
auto rel_scale_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_RELSCALE); auto rel_scale_prop = attachment_prop->at<Gvas::Types::VectorStructProperty>(MASS_BL_ATTACHMENT_RELSCALE);
rel_scale_prop->x = attachment.relativeScale.x(); rel_scale_prop->vector = attachment.relativeScale;
rel_scale_prop->y = attachment.relativeScale.y();
rel_scale_prop->z = attachment.relativeScale.z();
} }
} }

View file

@ -42,13 +42,13 @@ Mass::getDecals(Containers::ArrayView<Decal> decals, Gvas::Types::ArrayProperty*
auto colour_prop = decal_prop->at<Gvas::Types::ColourStructProperty>(MASS_DECAL_COLOUR); auto colour_prop = decal_prop->at<Gvas::Types::ColourStructProperty>(MASS_DECAL_COLOUR);
decal.colour = Color4{colour_prop->r, colour_prop->g, colour_prop->b, colour_prop->a}; decal.colour = Color4{colour_prop->r, colour_prop->g, colour_prop->b, colour_prop->a};
auto pos_prop = decal_prop->at<Gvas::Types::VectorStructProperty>(MASS_DECAL_POSITION); auto pos_prop = decal_prop->at<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(MASS_DECAL_UAXIS); auto u_prop = decal_prop->at<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(MASS_DECAL_VAXIS); auto v_prop = decal_prop->at<Gvas::Types::VectorStructProperty>(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<Gvas::Types::Vector2DStructProperty>(MASS_DECAL_OFFSET); auto offset_prop = decal_prop->at<Gvas::Types::Vector2DStructProperty>(MASS_DECAL_OFFSET);
decal.offset = Vector2{offset_prop->x, offset_prop->y}; decal.offset = offset_prop->vector;
decal.scale = decal_prop->at<Gvas::Types::FloatProperty>(MASS_DECAL_SCALE)->value; decal.scale = decal_prop->at<Gvas::Types::FloatProperty>(MASS_DECAL_SCALE)->value;
decal.rotation = decal_prop->at<Gvas::Types::FloatProperty>(MASS_DECAL_ROTATION)->value; decal.rotation = decal_prop->at<Gvas::Types::FloatProperty>(MASS_DECAL_ROTATION)->value;
decal.flip = decal_prop->at<Gvas::Types::BoolProperty>(MASS_DECAL_FLIP)->value; decal.flip = decal_prop->at<Gvas::Types::BoolProperty>(MASS_DECAL_FLIP)->value;
@ -70,20 +70,13 @@ Mass::writeDecals(Containers::ArrayView<Decal> decals, Gvas::Types::ArrayPropert
colour_prop->b = decal.colour.b(); colour_prop->b = decal.colour.b();
colour_prop->a = decal.colour.a(); colour_prop->a = decal.colour.a();
auto pos_prop = decal_prop->at<Gvas::Types::VectorStructProperty>(MASS_DECAL_POSITION); auto pos_prop = decal_prop->at<Gvas::Types::VectorStructProperty>(MASS_DECAL_POSITION);
pos_prop->x = decal.position.x(); pos_prop->vector = decal.position;
pos_prop->y = decal.position.y();
pos_prop->z = decal.position.z();
auto u_prop = decal_prop->at<Gvas::Types::VectorStructProperty>(MASS_DECAL_UAXIS); auto u_prop = decal_prop->at<Gvas::Types::VectorStructProperty>(MASS_DECAL_UAXIS);
u_prop->x = decal.uAxis.x(); u_prop->vector = decal.uAxis;
u_prop->y = decal.uAxis.y();
u_prop->z = decal.uAxis.z();
auto v_prop = decal_prop->at<Gvas::Types::VectorStructProperty>(MASS_DECAL_VAXIS); auto v_prop = decal_prop->at<Gvas::Types::VectorStructProperty>(MASS_DECAL_VAXIS);
v_prop->x = decal.vAxis.x(); v_prop->vector = decal.vAxis;
v_prop->y = decal.vAxis.y();
v_prop->z = decal.vAxis.z();
auto offset_prop = decal_prop->at<Gvas::Types::Vector2DStructProperty>(MASS_DECAL_OFFSET); auto offset_prop = decal_prop->at<Gvas::Types::Vector2DStructProperty>(MASS_DECAL_OFFSET);
offset_prop->x = decal.offset.x(); offset_prop->vector = decal.offset;
offset_prop->y = decal.offset.y();
decal_prop->at<Gvas::Types::FloatProperty>(MASS_DECAL_SCALE)->value = decal.scale; decal_prop->at<Gvas::Types::FloatProperty>(MASS_DECAL_SCALE)->value = decal.scale;
decal_prop->at<Gvas::Types::FloatProperty>(MASS_DECAL_ROTATION)->value = decal.rotation; decal_prop->at<Gvas::Types::FloatProperty>(MASS_DECAL_ROTATION)->value = decal.rotation;
decal_prop->at<Gvas::Types::BoolProperty>(MASS_DECAL_FLIP)->value = decal.flip; decal_prop->at<Gvas::Types::BoolProperty>(MASS_DECAL_FLIP)->value = decal.flip;
@ -105,15 +98,15 @@ Mass::getAccessories(Containers::ArrayView<Accessory> accessories, Gvas::Types::
accessory.styles[j] = acc_styles->at<Gvas::Types::IntProperty>(j)->value; accessory.styles[j] = acc_styles->at<Gvas::Types::IntProperty>(j)->value;
} }
auto rel_pos_prop = acc_prop->at<Gvas::Types::VectorStructProperty>(MASS_ACCESSORY_RELPOS); auto rel_pos_prop = acc_prop->at<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(MASS_ACCESSORY_OFFPOS); auto rel_pos_offset_prop = acc_prop->at<Gvas::Types::VectorStructProperty>(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<Gvas::Types::RotatorStructProperty>(MASS_ACCESSORY_RELROT); auto rel_rot_prop = acc_prop->at<Gvas::Types::RotatorStructProperty>(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<Gvas::Types::RotatorStructProperty>(MASS_ACCESSORY_OFFROT); auto rel_rot_offset_prop = acc_prop->at<Gvas::Types::RotatorStructProperty>(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<Gvas::Types::VectorStructProperty>(MASS_ACCESSORY_SCALE); auto local_scale_prop = acc_prop->at<Gvas::Types::VectorStructProperty>(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<Accessory> accessories, Gvas::Types
acc_styles->at<Gvas::Types::IntProperty>(j)->value = accessory.styles[j]; acc_styles->at<Gvas::Types::IntProperty>(j)->value = accessory.styles[j];
} }
auto rel_pos_prop = acc_prop->at<Gvas::Types::VectorStructProperty>(MASS_ACCESSORY_RELPOS); auto rel_pos_prop = acc_prop->at<Gvas::Types::VectorStructProperty>(MASS_ACCESSORY_RELPOS);
rel_pos_prop->x = accessory.relativePosition.x(); rel_pos_prop->vector = accessory.relativePosition;
rel_pos_prop->y = accessory.relativePosition.y();
rel_pos_prop->z = accessory.relativePosition.z();
auto rel_pos_offset_prop = acc_prop->at<Gvas::Types::VectorStructProperty>(MASS_ACCESSORY_OFFPOS); auto rel_pos_offset_prop = acc_prop->at<Gvas::Types::VectorStructProperty>(MASS_ACCESSORY_OFFPOS);
rel_pos_offset_prop->x = accessory.relativePositionOffset.x(); rel_pos_offset_prop->vector = accessory.relativePositionOffset;
rel_pos_offset_prop->y = accessory.relativePositionOffset.y();
rel_pos_offset_prop->z = accessory.relativePositionOffset.z();
auto rel_rot_prop = acc_prop->at<Gvas::Types::RotatorStructProperty>(MASS_ACCESSORY_RELROT); auto rel_rot_prop = acc_prop->at<Gvas::Types::RotatorStructProperty>(MASS_ACCESSORY_RELROT);
rel_rot_prop->x = accessory.relativeRotation.x(); rel_rot_prop->vector = accessory.relativeRotation;
rel_rot_prop->y = accessory.relativeRotation.y();
rel_rot_prop->z = accessory.relativeRotation.z();
auto rel_rot_offset_prop = acc_prop->at<Gvas::Types::RotatorStructProperty>(MASS_ACCESSORY_OFFROT); auto rel_rot_offset_prop = acc_prop->at<Gvas::Types::RotatorStructProperty>(MASS_ACCESSORY_OFFROT);
rel_rot_offset_prop->x = accessory.relativeRotationOffset.x(); rel_rot_offset_prop->vector = accessory.relativeRotationOffset;
rel_rot_offset_prop->y = accessory.relativeRotationOffset.y();
rel_rot_offset_prop->z = accessory.relativeRotationOffset.z();
auto local_scale_prop = acc_prop->at<Gvas::Types::VectorStructProperty>(MASS_ACCESSORY_SCALE); auto local_scale_prop = acc_prop->at<Gvas::Types::VectorStructProperty>(MASS_ACCESSORY_SCALE);
local_scale_prop->x = accessory.localScale.x(); local_scale_prop->vector = accessory.localScale;
local_scale_prop->y = accessory.localScale.y();
local_scale_prop->z = accessory.localScale.z();
} }
} }

View file

@ -28,9 +28,25 @@ RotatorProperty::deserialiseProperty(Containers::StringView name, Containers::St
{ {
auto prop = Containers::pointer<Types::RotatorStructProperty>(); auto prop = Containers::pointer<Types::RotatorStructProperty>();
if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y) || !reader.readFloat(prop->z)) { if(value_length == 12) { // UE4
LOG_ERROR_FORMAT("Couldn't read rotator property {}'s value.", name); float x, y, z;
return nullptr;
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; return prop;
@ -46,9 +62,21 @@ RotatorProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::si
return false; return false;
} }
bytes_written += writer.writeValueToArray<float>(rotator->x) + std::visit(
writer.writeValueToArray<float>(rotator->y) + [&bytes_written, &writer](auto& arg){
writer.writeValueToArray<float>(rotator->z); using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
bytes_written += writer.writeValueToArray<float>(arg.x()) +
writer.writeValueToArray<float>(arg.y()) +
writer.writeValueToArray<float>(arg.z());
}
else if constexpr (std::is_same_v<T, Vector3d>) {
bytes_written += writer.writeValueToArray<double>(arg.x()) +
writer.writeValueToArray<double>(arg.y()) +
writer.writeValueToArray<double>(arg.z());
}
}, rotator->vector
);
return true; return true;
} }

View file

@ -29,9 +29,25 @@ Vector2DProperty::deserialiseProperty(Containers::StringView name, Containers::S
{ {
auto prop = Containers::pointer<Types::Vector2DStructProperty>(); auto prop = Containers::pointer<Types::Vector2DStructProperty>();
if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y)) { if(value_length == 8) { // UE4
LOG_ERROR_FORMAT("Couldn't read 2D vector property {}'s value.", name); float x, y;
return nullptr;
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; return prop;
@ -47,8 +63,19 @@ Vector2DProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::s
return false; return false;
} }
bytes_written += writer.writeValueToArray<float>(vector->x) + std::visit(
writer.writeValueToArray<float>(vector->y); [&bytes_written, &writer](auto& arg){
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector2>) {
bytes_written += writer.writeValueToArray<float>(arg.x()) +
writer.writeValueToArray<float>(arg.y());
}
else if constexpr (std::is_same_v<T, Vector2d>) {
bytes_written += writer.writeValueToArray<double>(arg.x()) +
writer.writeValueToArray<double>(arg.y());
}
}, vector->vector
);
return true; return true;
} }

View file

@ -29,9 +29,25 @@ VectorProperty::deserialiseProperty(Containers::StringView name, Containers::Str
{ {
auto prop = Containers::pointer<Types::VectorStructProperty>(); auto prop = Containers::pointer<Types::VectorStructProperty>();
if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y) || !reader.readFloat(prop->z)) { if(value_length == 12) { // UE4
LOG_ERROR_FORMAT("Couldn't read vector property {}'s value.", name); float x, y, z;
return nullptr;
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; return prop;
@ -47,9 +63,21 @@ VectorProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::siz
return false; return false;
} }
bytes_written += writer.writeValueToArray<float>(vector->x) + std::visit(
writer.writeValueToArray<float>(vector->y) + [&bytes_written, &writer](auto& arg){
writer.writeValueToArray<float>(vector->z); using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
bytes_written += writer.writeValueToArray<float>(arg.x()) +
writer.writeValueToArray<float>(arg.y()) +
writer.writeValueToArray<float>(arg.z());
}
else if constexpr (std::is_same_v<T, Vector3d>) {
bytes_written += writer.writeValueToArray<double>(arg.x()) +
writer.writeValueToArray<double>(arg.y()) +
writer.writeValueToArray<double>(arg.z());
}
}, vector->vector
);
return true; return true;
} }

View file

@ -16,12 +16,19 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <variant>
#include <Corrade/Containers/Pointer.h> #include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Math/Vector3.h>
#include "StructProperty.h" #include "StructProperty.h"
using namespace Corrade; using namespace Corrade;
using namespace Magnum;
typedef std::variant<Vector3, Vector3d> Vector3Variant;
namespace Gvas::Types { namespace Gvas::Types {
@ -33,7 +40,7 @@ struct RotatorStructProperty : public StructProperty {
structType = "Rotator"_s; structType = "Rotator"_s;
} }
float x = 0.0f, y = 0.0f, z = 0.0f; Vector3Variant vector;
}; };
} }

View file

@ -16,12 +16,19 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <variant>
#include <Corrade/Containers/Pointer.h> #include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Math/Vector2.h>
#include "StructProperty.h" #include "StructProperty.h"
using namespace Corrade; using namespace Corrade;
using namespace Magnum;
typedef std::variant<Vector2, Vector2d> Vector2Variant;
namespace Gvas::Types { namespace Gvas::Types {
@ -33,7 +40,7 @@ struct Vector2DStructProperty : public StructProperty {
structType = "Vector2D"_s; structType = "Vector2D"_s;
} }
float x = 0.0f, y = 0.0f; Vector2Variant vector;
}; };
} }

View file

@ -16,12 +16,19 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <variant>
#include <Corrade/Containers/Pointer.h> #include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Math/Vector3.h>
#include "StructProperty.h" #include "StructProperty.h"
using namespace Corrade; using namespace Corrade;
using namespace Magnum;
typedef std::variant<Vector3, Vector3d> Vector3Variant;
namespace Gvas::Types { namespace Gvas::Types {
@ -33,7 +40,7 @@ struct VectorStructProperty : public StructProperty {
structType = "Vector"_s; structType = "Vector"_s;
} }
float x = 0.0f, y = 0.0f, z = 0.0f; Vector3Variant vector{Vector3{}};
}; };
} }