Skip to content

Commit

Permalink
[Commands] Fixed undo for Transform
Browse files Browse the repository at this point in the history
  • Loading branch information
PanosK92 committed Nov 19, 2023
1 parent 2c071e9 commit d2e2d66
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 74 deletions.
42 changes: 18 additions & 24 deletions editor/ImGui/Implementation/ImGui_TransformGizmo.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "Rendering/Renderer.h"
#include "Input/Input.h"
#include "Commands/CommandStack.h"
#include "Commands/TransformEntity.h"
#include "Commands/CommandTransform.h"
#include "Engine.h"
//======================================

namespace ImGui::TransformGizmo
{
static inline bool transform_command_done = false;
bool first_frame_in_control = true;

static inline Spartan::Math::Vector3 begin_position;
static inline Spartan::Math::Quaternion begin_rotation;
static inline Spartan::Math::Vector3 begin_scale;

static void apply_style()
void apply_style()
{
ImGuizmo::Style& style = ImGuizmo::GetStyle();
style.TranslationLineThickness = 6.0f;
Expand Down Expand Up @@ -103,46 +99,44 @@ namespace ImGui::TransformGizmo
ImGuizmo::SetOrthographic(is_orthographic);
ImGuizmo::BeginFrame();

// Map transform to ImGuizmo
// map transform to ImGuizmo
Spartan::Math::Vector3 position = transform->GetPosition();
Spartan::Math::Vector3 scale = transform->GetScale();
Spartan::Math::Quaternion rotation = transform->GetRotation();

Spartan::Math::Matrix transform_matrix = Spartan::Math::Matrix::GenerateRowFirst(position, rotation, scale);

// Set viewport rectangle
// set viewport rectangle
ImGuizmo::SetDrawlist();
ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, ImGui::GetWindowWidth(), ImGui::GetWindowHeight());

ImGuizmo::Manipulate(&matrix_view.m00, &matrix_projection.m00, transform_operation, transform_space, &transform_matrix.m00, nullptr, nullptr);

// Map ImGuizmo to transform
// map imguizmo to transform
if (ImGuizmo::IsUsing())
{
if (first_frame_in_control)
{
// add the old transform to the command stack
Spartan::CommandStack::Apply<Spartan::CommandTransform>(
entity.get(),
transform->GetPosition(), transform->GetRotation(), transform->GetScale()
);

first_frame_in_control = false;
}

transform_matrix.Transposed().Decompose(scale, rotation, position);

transform->SetPosition(position);
transform->SetRotation(rotation);
transform->SetScale(scale);

begin_position = position;
begin_rotation = rotation;
begin_scale = scale;
}
else
{
if (!transform_command_done)
{
SP_LOG_INFO("Applying command");
Spartan::CommandStack::Apply<Spartan::TransformEntity>(entity.get(), begin_position, begin_rotation, begin_scale);
transform_command_done = true;
}
}
}

static bool allow_picking()
{
transform_command_done = false;
first_frame_in_control = true;
return !ImGuizmo::IsOver() && !ImGuizmo::IsUsing();
}
}
18 changes: 9 additions & 9 deletions runtime/Commands/CommandStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,24 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

//= INCLUDES ==========================
//= INCLUDES ============
#include "pch.h"
#include "CommandStack.h"
//=====================================
//=======================

//= NAMESPACES =====
using namespace std;
//==================

namespace Spartan
{

void CommandStack::Undo()
{
if (m_undo_buffer.size() == 0)
return;

// Fetch the latest applied command, so we know what we are undoing
std::shared_ptr<Command> undo_command = m_undo_buffer.back();
shared_ptr<Command> undo_command = m_undo_buffer.back();
m_undo_buffer.pop_back();

// Actually undo
Expand All @@ -50,7 +52,7 @@ namespace Spartan
return;

// Fetch the latest undoed command, so we know what we are redoing
std::shared_ptr<Command> redo_command = m_redo_buffer.back();
shared_ptr<Command> redo_command = m_redo_buffer.back();
m_redo_buffer.pop_back();

// Actually redo
Expand All @@ -60,8 +62,6 @@ namespace Spartan
m_undo_buffer.push_back(redo_command);
}

std::vector<std::shared_ptr<Spartan::Command>> CommandStack::m_undo_buffer;

std::vector<std::shared_ptr<Spartan::Command>> CommandStack::m_redo_buffer;

vector<shared_ptr<Spartan::Command>> CommandStack::m_undo_buffer;
vector<shared_ptr<Spartan::Command>> CommandStack::m_redo_buffer;
}
1 change: 0 additions & 1 deletion runtime/Commands/CommandStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ namespace Spartan
static void Redo();

protected:

static std::vector<std::shared_ptr<Command>> m_undo_buffer;
static std::vector<std::shared_ptr<Command>> m_redo_buffer;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,71 +19,56 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

//= INCLUDES ==========================
//= INCLUDES ================
#include "pch.h"
#include "TransformEntity.h"
#include "CommandTransform.h"
#include "../World/World.h"
//=====================================
//===========================

//= NAMESPACES =====
using namespace std;
//==================

namespace Spartan
{

TransformEntity::TransformEntity(Spartan::Entity* entity, Math::Vector3 old_position, Math::Quaternion old_rotation, Math::Vector3 old_scale)
CommandTransform::CommandTransform(Spartan::Entity* entity, Math::Vector3 old_position, Math::Quaternion old_rotation, Math::Vector3 old_scale)
{
SP_ASSERT(entity);

// In the current implementation of GetObjectId, it may seem unneccessary to not just store a (shared) pointer to the entity
// In the current implementation of GetObjectId, it may seem unnecessary to not just store a (shared) pointer to the entity
// however if we ever move to a UUID based system, or hashed name system, and entities can be destroyed/created or unloaded/loaded with consistent ids
// we want to actually store the ID and then resolve from that.
// Right now this wont work as expected, since the object ids are just incremented on creation
m_entity_id = entity->GetObjectId();

std::shared_ptr<Transform> transform = entity->GetTransform();
SP_ASSERT(transform.get());

m_new_position = transform->GetPosition();
m_new_rotation = transform->GetRotation();
m_new_scale = transform->GetScale();


m_new_position = entity->GetTransform()->GetPosition();
m_new_rotation = entity->GetTransform()->GetRotation();
m_new_scale = entity->GetTransform()->GetScale();

m_old_position = old_position;
m_old_rotation = old_rotation;
m_old_scale = old_scale;
m_old_scale = old_scale;
}

void TransformEntity::OnApply()
void CommandTransform::OnApply()
{
std::shared_ptr<Entity> entity = Spartan::World::GetEntityById(m_entity_id);

// this may likely happen in legitimate edge cases according to my experience
shared_ptr<Entity> entity = Spartan::World::GetEntityById(m_entity_id);
if (!entity)
return;

std::shared_ptr<Transform> transform = entity->GetTransform();

SP_ASSERT_MSG(transform, "We had entity, but it didn't have a valid transform.");

transform->SetPosition(m_new_position);
transform->SetRotation(m_new_rotation);
transform->SetScale(m_new_scale);
entity->GetTransform()->SetPosition(m_new_position);
entity->GetTransform()->SetRotation(m_new_rotation);
entity->GetTransform()->SetScale(m_new_scale);
}

void TransformEntity::OnRevert()
void CommandTransform::OnRevert()
{
std::shared_ptr<Entity> entity = Spartan::World::GetEntityById(m_entity_id);

// this may likely happen in legitimate edge cases according to my experience
shared_ptr<Entity> entity = Spartan::World::GetEntityById(m_entity_id);
if (!entity)
return;

std::shared_ptr<Transform> transform = entity->GetTransform();

SP_ASSERT_MSG(transform, "We had entity, but it didn't have a valid transform.");

transform->SetPosition(m_old_position);
transform->SetRotation(m_old_rotation);
transform->SetScale(m_old_scale);
entity->GetTransform()->SetPosition(m_old_position);
entity->GetTransform()->SetRotation(m_old_rotation);
entity->GetTransform()->SetScale(m_old_scale);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ namespace Spartan
/**
* Baseclass for commands to be used in a CommandStack.
*/
class SP_CLASS TransformEntity : public Spartan::Command
class SP_CLASS CommandTransform : public Spartan::Command
{
public:
TransformEntity(Spartan::Entity* entity, Math::Vector3 old_position, Math::Quaternion old_rotation, Math::Vector3 old_scale);
CommandTransform(Spartan::Entity* entity, Math::Vector3 old_position, Math::Quaternion old_rotation, Math::Vector3 old_scale);

virtual void OnApply() override;
virtual void OnRevert() override;
Expand Down

0 comments on commit d2e2d66

Please sign in to comment.