diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.h index 9de9f0dee3..576c543dce 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.h @@ -42,6 +42,7 @@ namespace AzToolsFramework ~LinearManipulator() = default; /// A Manipulator must only be created and managed through a shared_ptr. + /// @note worldFromLocal should not contain scale. static AZStd::shared_ptr MakeShared(const AZ::Transform& worldFromLocal); /// Unchanging data set once for the linear manipulator. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp index a61f042049..f72de82f36 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp @@ -1,20 +1,20 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ -#include +#include +#include #include #include -#include -#include +#include namespace AzToolsFramework { @@ -32,12 +32,13 @@ namespace AzToolsFramework serializeContext->Class() ->Version(1) ->Field("NonUniformScale", &EditorNonUniformScaleComponent::m_scale) - ; + ->Field("ComponentMode", &EditorNonUniformScaleComponent::m_componentModeDelegate); if (AZ::EditContext* editContext = serializeContext->GetEditContext()) { - editContext->Class("Non-uniform Scale", - "Non-uniform scale for this entity only (does not propagate through hierarchy)") + editContext + ->Class( + "Non-uniform Scale", "Non-uniform scale for this entity only (does not propagate through hierarchy)") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::FixedComponentListIndex, 1) ->Attribute(AZ::Edit::Attributes::RemoveableByUser, true) @@ -50,7 +51,10 @@ namespace AzToolsFramework ->Attribute(AZ::Edit::Attributes::Max, AZ::MaxTransformScale) ->Attribute(AZ::Edit::Attributes::Step, 0.1f) ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorNonUniformScaleComponent::OnScaleChanged) - ; + ->DataElement( + AZ::Edit::UIHandlers::Default, &EditorNonUniformScaleComponent::m_componentModeDelegate, "Component Mode", + "Non-uniform Scale Component Mode") + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly); } } } @@ -74,10 +78,16 @@ namespace AzToolsFramework void EditorNonUniformScaleComponent::Activate() { AZ::NonUniformScaleRequestBus::Handler::BusConnect(GetEntityId()); + + // ComponentMode + m_componentModeDelegate.ConnectWithSingleComponentMode( + AZ::EntityComponentIdPair(GetEntityId(), GetId()), nullptr); } void EditorNonUniformScaleComponent::Deactivate() { + m_componentModeDelegate.Disconnect(); + AZ::NonUniformScaleRequestBus::Handler::BusDisconnect(); } @@ -96,7 +106,8 @@ namespace AzToolsFramework else { AZ::Vector3 clampedScale = scale.GetClamp(AZ::Vector3(AZ::MinTransformScale), AZ::Vector3(AZ::MaxTransformScale)); - AZ_Warning("Editor Non-uniform Scale Component", false, "SetScale value was clamped from %s to %s for entity %s", + AZ_Warning( + "Editor Non-uniform Scale Component", false, "SetScale value was clamped from %s to %s for entity %s", AZ::ToString(scale).c_str(), AZ::ToString(clampedScale).c_str(), GetEntity()->GetName().c_str()); m_scale = clampedScale; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h index ea67ab3962..eb51fe3d80 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h @@ -13,6 +13,9 @@ #pragma once #include +#include +#include +#include #include namespace AzToolsFramework @@ -52,6 +55,9 @@ namespace AzToolsFramework AZ::Vector3 m_scale = AZ::Vector3::CreateOne(); AZ::NonUniformScaleChangedEvent m_scaleChangedEvent; + + //! Responsible for detecting ComponentMode activation and creating a concrete ComponentMode. + AzToolsFramework::ComponentModeFramework::ComponentModeDelegate m_componentModeDelegate; }; } // namespace Components } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponentMode.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponentMode.cpp new file mode 100644 index 0000000000..97e27ac748 --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponentMode.cpp @@ -0,0 +1,92 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include +#include +#include +#include + +namespace AzToolsFramework +{ + namespace Components + { + NonUniformScaleComponentMode::NonUniformScaleComponentMode( + const AZ::EntityComponentIdPair& entityComponentIdPair, AZ::Uuid componentType) + : EditorBaseComponentMode(entityComponentIdPair, componentType) + { + m_entityComponentIdPair = entityComponentIdPair; + + AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); + AZ::TransformBus::EventResult(worldFromLocal, m_entityComponentIdPair.GetEntityId(), &AZ::TransformBus::Events::GetWorldTM); + worldFromLocal.ExtractScale(); + m_manipulators = AZStd::make_unique(worldFromLocal); + m_manipulators->Register(g_mainManipulatorManagerId); + m_manipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ()); + const float axisLength = 2.0f; + m_manipulators->ConfigureView( + axisLength, AzFramework::ViewportColors::XAxisColor, AzFramework::ViewportColors::YAxisColor, + AzFramework::ViewportColors::ZAxisColor); + + auto mouseDownCallback = [this](const LinearManipulator::Action& action) { + AZ::Vector3 nonUniformScale = AZ::Vector3::CreateOne(); + + AZ::NonUniformScaleRequestBus::EventResult( + nonUniformScale, m_entityComponentIdPair.GetEntityId(), &AZ::NonUniformScaleRequests::GetScale); + + m_initialScale = nonUniformScale + action.m_start.m_scaleSnapOffset; + + AZ::NonUniformScaleRequestBus::Event( + m_entityComponentIdPair.GetEntityId(), &AZ::NonUniformScaleRequests::SetScale, m_initialScale); + }; + + m_manipulators->InstallAxisLeftMouseDownCallback(mouseDownCallback); + + m_manipulators->InstallAxisMouseMoveCallback([this](const LinearManipulator::Action& action) { + const AZ::Vector3 scaleMultiplier = + (AZ::Vector3::CreateOne() + ((action.LocalScaleOffset() * action.m_start.m_sign) / m_initialScale)); + + AZ::NonUniformScaleRequestBus::Event( + m_entityComponentIdPair.GetEntityId(), &AZ::NonUniformScaleRequests::SetScale, + (scaleMultiplier * m_initialScale).GetClamp(AZ::Vector3(AZ::MinTransformScale), AZ::Vector3(AZ::MaxTransformScale))); + }); + + m_manipulators->InstallUniformLeftMouseDownCallback(mouseDownCallback); + + m_manipulators->InstallUniformMouseMoveCallback([this](const LinearManipulator::Action& action) { + const auto sumVectorElements = [](const AZ::Vector3& vec) { return vec.GetX() + vec.GetY() + vec.GetZ(); }; + + const float minScaleMultiplier = AZ::MinTransformScale / m_initialScale.GetMinElement(); + const float maxScaleMultiplier = AZ::MaxTransformScale / m_initialScale.GetMaxElement(); + const float scaleMultiplier = AZ::GetClamp( + 1.0f + sumVectorElements(action.m_start.m_sign * action.LocalScaleOffset() / m_initialScale), minScaleMultiplier, + maxScaleMultiplier); + + AZ::NonUniformScaleRequestBus::Event( + m_entityComponentIdPair.GetEntityId(), &AZ::NonUniformScaleRequests::SetScale, scaleMultiplier * m_initialScale); + }); + } + + NonUniformScaleComponentMode::~NonUniformScaleComponentMode() + { + if (m_manipulators) + { + m_manipulators->Unregister(); + } + m_manipulators.reset(); + } + + void NonUniformScaleComponentMode::Refresh() + { + } + } // namespace Components +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponentMode.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponentMode.h new file mode 100644 index 0000000000..1169a4f13e --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponentMode.h @@ -0,0 +1,43 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#pragma once + +#include +#include + +namespace AzToolsFramework +{ + namespace Components + { + class NonUniformScaleComponentMode : public AzToolsFramework::ComponentModeFramework::EditorBaseComponentMode + { + public: + AZ_CLASS_ALLOCATOR(NonUniformScaleComponentMode, AZ::SystemAllocator, 0) + + NonUniformScaleComponentMode(const AZ::EntityComponentIdPair& entityComponentIdPair, AZ::Uuid componentType); + NonUniformScaleComponentMode(const NonUniformScaleComponentMode&) = delete; + NonUniformScaleComponentMode& operator=(const NonUniformScaleComponentMode&) = delete; + NonUniformScaleComponentMode(NonUniformScaleComponentMode&&) = delete; + NonUniformScaleComponentMode& operator=(NonUniformScaleComponentMode&&) = delete; + ~NonUniformScaleComponentMode(); + + // EditorBaseComponentMode overrides ... + void Refresh() override; + + private: + AZ::EntityComponentIdPair m_entityComponentIdPair; + AZStd::unique_ptr m_manipulators; + AZ::Vector3 m_initialScale; + }; + } // namespace Components +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake index 06f78ecdd3..45f52704bf 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake @@ -303,6 +303,8 @@ set(FILES ToolsComponents/AzToolsFrameworkConfigurationSystemComponent.cpp ToolsComponents/EditorNonUniformScaleComponent.h ToolsComponents/EditorNonUniformScaleComponent.cpp + ToolsComponents/EditorNonUniformScaleComponentMode.h + ToolsComponents/EditorNonUniformScaleComponentMode.cpp ToolsMessaging/EntityHighlightBus.h UI/Docking/DockWidgetUtils.cpp UI/Docking/DockWidgetUtils.h