diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/Actions/TransformAction.cpp b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/Actions/TransformAction.cpp new file mode 100644 index 0000000000..1d4eef8533 --- /dev/null +++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/Actions/TransformAction.cpp @@ -0,0 +1,132 @@ +// Copyright 2024 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "VideoCommon/GraphicsModSystem/Runtime/Actions/TransformAction.h" + +#include "Common/JsonUtil.h" + +#include "VideoCommon/GraphicsModEditor/EditorEvents.h" + +#include + +std::unique_ptr TransformAction::Create(const picojson::value& json_data) +{ + if (!json_data.is()) + return nullptr; + + const auto& obj = json_data.get(); + + Common::Vec3 scale{1, 1, 1}; + if (const auto it = obj.find("scale"); it != obj.end()) + { + if (it->second.is()) + { + FromJson(it->second.get(), scale); + } + } + + Common::Vec3 translation{}; + if (const auto it = obj.find("translation"); it != obj.end()) + { + if (it->second.is()) + { + FromJson(it->second.get(), translation); + } + } + + Common::Vec3 rotation{}; + if (const auto it = obj.find("rotation"); it != obj.end()) + { + if (it->second.is()) + { + FromJson(it->second.get(), rotation); + } + } + return std::make_unique(std::move(rotation), std::move(scale), + std::move(translation)); +} + +std::unique_ptr TransformAction::Create() +{ + return std::make_unique(Common::Vec3{}, Common::Vec3{1, 1, 1}, Common::Vec3{}); +} + +TransformAction::TransformAction(Common::Vec3 rotation, Common::Vec3 scale, + Common::Vec3 translation) + : m_rotation(std::move(rotation)), m_scale(std::move(scale)), + m_translation(std::move(translation)), m_calculated_transform(Common::Matrix44::Identity()), + m_transform_changed(true) +{ +} + +void TransformAction::DrawImGui() +{ + if (ImGui::CollapsingHeader("Transform", ImGuiTreeNodeFlags_DefaultOpen)) + { + if (ImGui::BeginTable("TransformTable", 2)) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("Scale"); + ImGui::TableNextColumn(); + if (ImGui::InputFloat3("##Scale", m_scale.data.data())) + { + GraphicsModEditor::EditorEvents::ChangeOccurredEvent::Trigger(); + m_transform_changed = true; + } + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("Rotation"); + ImGui::TableNextColumn(); + if (ImGui::InputFloat3("##Rotation", m_rotation.data.data())) + { + GraphicsModEditor::EditorEvents::ChangeOccurredEvent::Trigger(); + m_transform_changed = true; + } + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("Translate"); + ImGui::TableNextColumn(); + if (ImGui::InputFloat3("##Translate", m_translation.data.data())) + { + GraphicsModEditor::EditorEvents::ChangeOccurredEvent::Trigger(); + m_transform_changed = true; + } + ImGui::EndTable(); + } + } +} + +void TransformAction::OnDrawStarted(GraphicsModActionData::DrawStarted* draw_started) +{ + if (!draw_started) [[unlikely]] + return; + + if (m_transform_changed) + { + const auto scale = Common::Matrix33::Scale(m_scale); + const auto rotation = Common::Quaternion::RotateXYZ(m_rotation); + m_calculated_transform = Common::Matrix44::Translate(m_translation) * + Common::Matrix44::FromQuaternion(rotation) * + Common::Matrix44::FromMatrix33(scale); + + m_transform_changed = false; + } + *draw_started->transform = m_calculated_transform; +} + +void TransformAction::SerializeToConfig(picojson::object* obj) +{ + if (!obj) [[unlikely]] + return; + + auto& json_obj = *obj; + json_obj.emplace("translation", ToJsonObject(m_translation)); + json_obj.emplace("scale", ToJsonObject(m_scale)); + json_obj.emplace("rotation", ToJsonObject(m_rotation)); +} + +std::string TransformAction::GetFactoryName() const +{ + return "transform"; +} diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/Actions/TransformAction.h b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/Actions/TransformAction.h new file mode 100644 index 0000000000..4698eeb385 --- /dev/null +++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/Actions/TransformAction.h @@ -0,0 +1,37 @@ +// Copyright 2024 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include + +#include "Common/Matrix.h" +#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModAction.h" + +class TransformAction final : public GraphicsModAction +{ +public: + static constexpr std::string_view factory_name = "transform"; + static std::unique_ptr Create(const picojson::value& json_data); + static std::unique_ptr Create(); + + TransformAction() = default; + TransformAction(Common::Vec3 rotation, Common::Vec3 scale, Common::Vec3 translation); + + void OnDrawStarted(GraphicsModActionData::DrawStarted*) override; + + void DrawImGui() override; + + void SerializeToConfig(picojson::object* obj) override; + std::string GetFactoryName() const override; + +private: + Common::Vec3 m_rotation = Common::Vec3{0, 0, 0}; + Common::Vec3 m_scale = Common::Vec3{1, 1, 1}; + Common::Vec3 m_translation = Common::Vec3{0, 0, 0}; + Common::Matrix44 m_calculated_transform = Common::Matrix44::Identity(); + bool m_transform_changed = false; +};