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 <imgui_internal.h>
#include <wtypesbase.h>
#include <shellapi.h>
#include <wtsapi32.h>
@ -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()) {

View file

@ -34,7 +34,6 @@
#include <SDL_timer.h>
#include <imgui.h>
#include <imgui_internal.h>
#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 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<typename Functor, typename... Args>
bool drawUnsafeWidget(Functor func, Args... args) {

View file

@ -19,6 +19,8 @@
#include <Magnum/ImGuiIntegration/Integration.h>
#include <imgui_internal.h>
#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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector2>) {
drawVector2Slider("##Offset", arg, Vector2{0.0f}, Vector2{1.0f}, "X: %.3f", "Y: %.3f");
}
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();
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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
drawVector3Drag("##Position", 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("##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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
drawVector3Drag("##U", 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("##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::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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
drawVector3Drag("##RelativePosition", 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("##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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
drawVector3Slider("##OffsetPosition", arg, Vector3{-500.0f}, Vector3{500.0f}, "X: %.3f", "Y: %.3f",
"Z: %.3f");
}
else if constexpr (std::is_same_v<T, Vector3d>) {
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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
drawVector3Drag("##RelativeRotation", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX}, "Roll: %.3f",
"Yaw: %.3f", "Pitch: %.3f");
}
else if constexpr (std::is_same_v<T, Vector3d>) {
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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
drawVector3Slider("##OffsetRotation", arg, Vector3{-180.0f}, Vector3{180.0f}, "Roll: %.3f",
"Yaw: %.3f", "Pitch: %.3f");
}
else if constexpr (std::is_same_v<T, Vector3d>) {
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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
drawVector3Slider("##Scale", arg, Vector3{-3.0f}, Vector3{3.0f}, "X: %.3f", "Y: %.3f", "Z: %.3f");
}
else if constexpr (std::is_same_v<T, Vector3d>) {
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();

View file

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <imgui_internal.h>
#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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
drawVector3Drag("##RelativePosition", 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("##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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
drawVector3Slider("##OffsetPosition", arg, Vector3{-500.0f}, Vector3{500.0f}, "X: %.3f", "Y: %.3f",
"Z: %.3f");
}
else if constexpr (std::is_same_v<T, Vector3d>) {
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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
drawVector3Drag("##RelativeRotation", arg, 1.0f, Vector3{-FLT_MAX}, Vector3{FLT_MAX},
"Pitch: %.3f", "Yaw: %.3f", "Roll: %.3f");
}
else if constexpr (std::is_same_v<T, Vector3d>) {
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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
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<T, Vector3d>) {
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<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector3>) {
drawVector3Slider("##Scale", arg, Vector3{0.5f}, Vector3{1.5f}, "X: %.3f", "Y: %.3f", "Z: %.3f");
}
else if constexpr (std::is_same_v<T, Vector3d>) {
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();

View file

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

View file

@ -16,6 +16,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <variant>
#include <Corrade/Containers/StaticArray.h>
#include <Magnum/Magnum.h>
@ -24,17 +26,19 @@
using namespace Corrade;
using namespace Magnum;
typedef std::variant<Vector3, Vector3d> 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}};
};
}

View file

@ -16,7 +16,7 @@
// You should have received a copy of the GNU General Public License
// 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/Math/Vector3.h>
@ -24,6 +24,8 @@
using namespace Corrade;
using namespace Magnum;
typedef std::variant<Vector3, Vector3d> 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;
};
}

View file

@ -16,6 +16,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <variant>
#include <Magnum/Magnum.h>
#include <Magnum/Math/Color.h>
#include <Magnum/Math/Vector2.h>
@ -23,15 +25,18 @@
using namespace Magnum;
typedef std::variant<Vector2, Vector2d> Vector2Variant;
typedef std::variant<Vector3, Vector3d> 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;

View file

@ -255,15 +255,15 @@ Mass::getBulletLauncherAttachments() {
}
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);
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);
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);
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);
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);
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<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(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;
}
}

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);
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);
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);
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);
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);
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.rotation = decal_prop->at<Gvas::Types::FloatProperty>(MASS_DECAL_ROTATION)->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->a = decal.colour.a();
auto pos_prop = decal_prop->at<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(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<Gvas::Types::Vector2DStructProperty>(MASS_DECAL_OFFSET);
offset_prop->x = decal.offset.x();
offset_prop->y = decal.offset.y();
offset_prop->vector = decal.offset;
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::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;
}
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);
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);
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);
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);
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];
}
auto rel_pos_prop = acc_prop->at<Gvas::Types::VectorStructProperty>(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<Gvas::Types::VectorStructProperty>(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<Gvas::Types::RotatorStructProperty>(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<Gvas::Types::RotatorStructProperty>(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<Gvas::Types::VectorStructProperty>(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;
}
}

View file

@ -28,11 +28,27 @@ RotatorProperty::deserialiseProperty(Containers::StringView name, Containers::St
{
auto prop = Containers::pointer<Types::RotatorStructProperty>();
if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y) || !reader.readFloat(prop->z)) {
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<float>(rotator->x) +
writer.writeValueToArray<float>(rotator->y) +
writer.writeValueToArray<float>(rotator->z);
std::visit(
[&bytes_written, &writer](auto& arg){
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;
}

View file

@ -29,11 +29,27 @@ Vector2DProperty::deserialiseProperty(Containers::StringView name, Containers::S
{
auto prop = Containers::pointer<Types::Vector2DStructProperty>();
if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y)) {
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<float>(vector->x) +
writer.writeValueToArray<float>(vector->y);
std::visit(
[&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;
}

View file

@ -29,11 +29,27 @@ VectorProperty::deserialiseProperty(Containers::StringView name, Containers::Str
{
auto prop = Containers::pointer<Types::VectorStructProperty>();
if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y) || !reader.readFloat(prop->z)) {
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<float>(vector->x) +
writer.writeValueToArray<float>(vector->y) +
writer.writeValueToArray<float>(vector->z);
std::visit(
[&bytes_written, &writer](auto& arg){
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;
}

View file

@ -16,12 +16,19 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <variant>
#include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/StringView.h>
#include <Magnum/Math/Vector3.h>
#include "StructProperty.h"
using namespace Corrade;
using namespace Magnum;
typedef std::variant<Vector3, Vector3d> 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;
};
}

View file

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