Files
o3de/Gems/LmbrCentral/Code/Source/Shape/EditorPolygonPrismShapeComponentMode.cpp
T
Esteban Papp 1f9b284de2 Merge branch 'development' into cmake/SPEC-7179
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>

# Conflicts:
#	Code/Editor/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin_precompiled.h
#	Code/Editor/Plugins/EditorCommon/EditorCommon_precompiled.h
#	Code/Editor/Plugins/EditorCommon/stdafx.cpp
#	Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h
#	Code/Editor/Plugins/PerforcePlugin/PerforcePlugin_precompiled.h
#	Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsTool_precompiled.h
#	Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFramework_precompiled.h
#	Code/Tools/AssetProcessor/native/precompiled.h
#	Code/Tools/Standalone/StandaloneTools_precompiled.h
#	Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer_precompiled.h
#	Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageProcessing_precompiled.h
#	Gems/Atom/RHI/DX12/Code/Source/RHI/Atom_RHI_DX12_precompiled.h
#	Gems/Atom/RHI/Metal/Code/Include/Platform/Mac/Atom_RHI_Metal_precompiled_Platform.h
#	Gems/Atom/RHI/Metal/Code/Include/Platform/iOS/Atom_RHI_Metal_precompiled_Platform.h
#	Gems/Atom/RHI/Metal/Code/Source/Atom_RHI_Metal_precompiled.h
#	Gems/Atom/RHI/Metal/Code/atom_rhi_metal_common_files.cmake
#	Gems/Atom/RHI/Null/Code/Source/Atom_RHI_Null_precompiled.h
#	Gems/Atom/RHI/Null/Code/atom_rhi_null_common_files.cmake
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Android/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Linux/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Mac/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Windows/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Source/Atom_RHI_Vulkan_precompiled.h
#	Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp
#	Gems/Atom/RHI/Vulkan/Code/atom_rhi_vulkan_common_files.cmake
#	Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont_precompiled.h
#	Gems/Blast/Code/Source/StdAfx.cpp
#	Gems/Camera/Code/Source/Camera_precompiled.h
#	Gems/EMotionFX/Code/Source/EMotionFX_precompiled.h
#	Gems/FastNoise/Code/Source/FastNoise_precompiled.h
#	Gems/Gestures/Code/Source/Gestures_precompiled.h
#	Gems/GradientSignal/Code/Source/GradientSignal_precompiled.h
#	Gems/GraphCanvas/Code/precompiled.h
#	Gems/ImGui/Code/Source/ImGui_precompiled.h
#	Gems/InAppPurchases/Code/Source/InAppPurchases_precompiled.h
#	Gems/LmbrCentral/Code/Source/LmbrCentral_precompiled.h
#	Gems/LmbrCentral/Code/Tests/ShapeGeometryUtilTest.cpp
#	Gems/LyShine/Code/Editor/UiCanvasEditor_precompiled.h
#	Gems/LyShine/Code/Source/Animation/LyShine_precompiled.h
#	Gems/LyShine/Code/Source/LyShine_precompiled.h
#	Gems/LyShineExamples/Code/Source/LyShineExamples_precompiled.h
#	Gems/Maestro/Code/Source/Cinematics/Maestro_precompiled.h
#	Gems/Maestro/Code/Source/Maestro_precompiled.h
#	Gems/MessagePopup/Code/Source/MessagePopup_precompiled.h
#	Gems/Metastream/Code/Source/Metastream_precompiled.h
#	Gems/Microphone/Code/Source/Microphone_precompiled.h
#	Gems/Multiplayer/Code/Source/Multiplayer_precompiled.h
#	Gems/PhysX/Code/NumericalMethods/Source/NumericalMethods_precompiled.h
#	Gems/PhysX/Code/Source/PhysXUnsupported_precompiled.h
#	Gems/PhysX/Code/Source/PhysX_precompiled.h
#	Gems/PhysX/Code/physx_unsupported_files.cmake
#	Gems/PhysXDebug/Code/Source/PhysXDebugUnsupported_precompiled.h
#	Gems/PhysXDebug/Code/Source/PhysXDebug_precompiled.h
#	Gems/ScriptCanvas/Code/Editor/precompiled.h
#	Gems/ScriptCanvas/Code/Source/precompiled.h
#	Gems/ScriptCanvasDeveloper/Code/Source/precompiled.h
#	Gems/ScriptCanvasPhysics/Code/Source/ScriptCanvasPhysics_precompiled.h
#	Gems/ScriptEvents/Code/Source/precompiled.h
#	Gems/ScriptEvents/Code/Tests/Editor/EditorTests.cpp
#	Gems/ScriptedEntityTweener/Code/Source/ScriptedEntityTweener_precompiled.h
#	Gems/SliceFavorites/Code/Source/SliceFavorites_precompiled.h
#	Gems/StartingPointCamera/Code/Source/StartingPointCamera_precompiled.h
#	Gems/StartingPointInput/Code/Source/StartingPointInput_precompiled.h
#	Gems/StartingPointMovement/Code/Source/StartingPointMovement_precompiled.h
#	Gems/SurfaceData/Code/Source/SurfaceData_precompiled.h
#	Gems/TextureAtlas/Code/Source/TextureAtlas_precompiled.h
#	Gems/TickBusOrderViewer/Code/Source/TickBusOrderViewer_precompiled.h
#	Gems/Twitch/Code/Source/Twitch_precompiled.h
#	Gems/VirtualGamepad/Code/Source/VirtualGamepad_precompiled.h
#	Gems/WhiteBox/Code/Source/WhiteBoxUnsupported_precompiled.h
#	Gems/WhiteBox/Code/Source/WhiteBox_precompiled.h
2021-07-16 15:42:37 -07:00

241 lines
9.4 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorPolygonPrismShapeComponentMode.h"
#include <AzToolsFramework/Manipulators/LineHoverSelection.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <AzCore/Component/NonUniformScaleBus.h>
namespace LmbrCentral
{
AZ_CLASS_ALLOCATOR_IMPL(EditorPolygonPrismShapeComponentMode, AZ::SystemAllocator, 0)
/// Util to calculate central position of prism (to draw the height manipulator)
static AZ::Vector3 CalculateHeightManipulatorPosition(const AZ::PolygonPrism& polygonPrism)
{
const float height = polygonPrism.GetHeight();
const AZ::VertexContainer<AZ::Vector2>& vertexContainer = polygonPrism.m_vertexContainer;
AzToolsFramework::MidpointCalculator midpointCalculator;
for (const AZ::Vector2& vertex : vertexContainer.GetVertices())
{
midpointCalculator.AddPosition(AZ::Vector2ToVector3(vertex, height));
}
return midpointCalculator.CalculateMidpoint();
}
EditorPolygonPrismShapeComponentMode::EditorPolygonPrismShapeComponentMode(
const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid componentType)
: EditorBaseComponentMode(entityComponentIdPair, componentType)
, m_nonUniformScaleChangedHandler([this](const AZ::Vector3& scale){OnNonUniformScaleChanged(scale);})
{
m_currentTransform = AZ::Transform::CreateIdentity();
AZ::TransformBus::EventResult(
m_currentTransform, entityComponentIdPair.GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
m_currentNonUniformScale = AZ::Vector3::CreateOne();
AZ::NonUniformScaleRequestBus::EventResult(m_currentNonUniformScale, GetEntityId(), &AZ::NonUniformScaleRequests::GetScale);
AZ::NonUniformScaleRequestBus::Event(entityComponentIdPair.GetEntityId(),
&AZ::NonUniformScaleRequests::RegisterScaleChangedEvent, m_nonUniformScaleChangedHandler);
AZ::TransformNotificationBus::Handler::BusConnect(entityComponentIdPair.GetEntityId());
PolygonPrismShapeComponentNotificationBus::Handler::BusConnect(entityComponentIdPair.GetEntityId());
ShapeComponentNotificationsBus::Handler::BusConnect(entityComponentIdPair.GetEntityId());
CreateManipulators();
}
EditorPolygonPrismShapeComponentMode::~EditorPolygonPrismShapeComponentMode()
{
ShapeComponentNotificationsBus::Handler::BusDisconnect();
PolygonPrismShapeComponentNotificationBus::Handler::BusDisconnect();
AZ::TransformNotificationBus::Handler::BusDisconnect();
m_nonUniformScaleChangedHandler.Disconnect();
DestroyManipulators();
}
void EditorPolygonPrismShapeComponentMode::Refresh()
{
ContainerChanged();
}
AZStd::vector<AzToolsFramework::ActionOverride> EditorPolygonPrismShapeComponentMode::PopulateActionsImpl()
{
return m_vertexSelection.ActionOverrides();
}
bool EditorPolygonPrismShapeComponentMode::HandleMouseInteraction(
const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction)
{
return m_vertexSelection.HandleMouse(mouseInteraction);
}
void EditorPolygonPrismShapeComponentMode::CreateManipulators()
{
using namespace AzToolsFramework;
AZ::PolygonPrismPtr polygonPrism = nullptr;
PolygonPrismShapeComponentRequestBus::EventResult(
polygonPrism, GetEntityId(), &PolygonPrismShapeComponentRequests::GetPolygonPrism);
// if we have no vertices, do not attempt to create any manipulators
if (polygonPrism->m_vertexContainer.Empty())
{
return;
}
m_vertexSelection.Create(
GetEntityComponentIdPair(), g_mainManipulatorManagerId,
AZStd::make_unique<LineSegmentHoverSelection<AZ::Vector2>>(
GetEntityComponentIdPair(), g_mainManipulatorManagerId),
TranslationManipulators::Dimensions::Two,
ConfigureTranslationManipulatorAppearance2d);
// callback after vertices in the selection have moved
m_vertexSelection.SetVertexPositionsUpdatedCallback([this, polygonPrism]()
{
// ensure we refresh the height manipulator after vertices are moved to ensure it stays central to the prism
m_heightManipulator->SetLocalTransform(
AZ::Transform::CreateTranslation(CalculateHeightManipulatorPosition(*polygonPrism)));
m_heightManipulator->SetBoundsDirty();
});
// initialize height manipulator
m_heightManipulator = LinearManipulator::MakeShared(m_currentTransform);
m_heightManipulator->AddEntityComponentIdPair(GetEntityComponentIdPair());
m_heightManipulator->SetSpace(AzToolsFramework::TransformUniformScale(m_currentTransform));
m_heightManipulator->SetNonUniformScale(m_currentNonUniformScale);
m_heightManipulator->SetLocalTransform(
AZ::Transform::CreateTranslation(CalculateHeightManipulatorPosition(*polygonPrism)));
m_heightManipulator->SetAxis(AZ::Vector3::CreateAxisZ());
const float lineLength = 0.5f;
const float lineWidth = 0.05f;
const float coneLength = 0.28f;
const float coneRadius = 0.07f;
ManipulatorViews views;
views.emplace_back(CreateManipulatorViewLine(
*m_heightManipulator, AZ::Color(0.0f, 0.0f, 1.0f, 1.0f),
lineLength, lineWidth));
views.emplace_back(CreateManipulatorViewCone(*m_heightManipulator,
AZ::Color(0.0f, 0.0f, 1.0f, 1.0f), m_heightManipulator->GetAxis() *
(lineLength - coneLength), coneLength, coneRadius));
m_heightManipulator->SetViews(AZStd::move(views));
// height manipulator callbacks
m_heightManipulator->InstallMouseMoveCallback([this, polygonPrism](
const LinearManipulator::Action& action)
{
polygonPrism->SetHeight(AZ::GetMax<float>(action.LocalPosition().GetZ(), 0.0f));
m_heightManipulator->SetLocalTransform(
AZ::Transform::CreateTranslation(Vector2ToVector3(Vector3ToVector2(
action.LocalPosition()), AZ::GetMax<float>(0.0f, action.LocalPosition().GetZ()))));
m_heightManipulator->SetBoundsDirty();
});
m_heightManipulator->Register(g_mainManipulatorManagerId);
}
void EditorPolygonPrismShapeComponentMode::DestroyManipulators()
{
// clear all manipulators when deselected
if (m_heightManipulator)
{
m_heightManipulator->Unregister();
m_heightManipulator.reset();
}
m_vertexSelection.Destroy();
}
void EditorPolygonPrismShapeComponentMode::ContainerChanged()
{
DestroyManipulators();
CreateManipulators();
}
void EditorPolygonPrismShapeComponentMode::RefreshManipulators()
{
m_vertexSelection.RefreshLocal();
if (m_heightManipulator)
{
AZ::PolygonPrismPtr polygonPrism = nullptr;
PolygonPrismShapeComponentRequestBus::EventResult(
polygonPrism, GetEntityId(), &PolygonPrismShapeComponentRequests::GetPolygonPrism);
m_heightManipulator->SetLocalTransform(
AZ::Transform::CreateTranslation(CalculateHeightManipulatorPosition(*polygonPrism)));
m_heightManipulator->SetBoundsDirty();
}
}
void EditorPolygonPrismShapeComponentMode::OnTransformChanged(
const AZ::Transform& /*local*/, const AZ::Transform& world)
{
m_currentTransform = world;
// update the space manipulators are in after the entity has moved
m_vertexSelection.RefreshSpace(world, m_currentNonUniformScale);
if (m_heightManipulator)
{
m_heightManipulator->SetSpace(world);
}
}
void EditorPolygonPrismShapeComponentMode::OnNonUniformScaleChanged(const AZ::Vector3& scale)
{
m_currentNonUniformScale = scale;
m_vertexSelection.RefreshSpace(m_currentTransform, scale);
if (m_heightManipulator)
{
m_heightManipulator->SetNonUniformScale(scale);
}
}
void EditorPolygonPrismShapeComponentMode::OnShapeChanged(ShapeChangeReasons /*changeReason*/)
{
RefreshManipulators();
}
void EditorPolygonPrismShapeComponentMode::OnVertexAdded(size_t index)
{
ContainerChanged();
AZ::PolygonPrismPtr polygonPrism = nullptr;
PolygonPrismShapeComponentRequestBus::EventResult(
polygonPrism, GetEntityId(), &PolygonPrismShapeComponentRequests::GetPolygonPrism);
m_vertexSelection.CreateTranslationManipulator(
GetEntityComponentIdPair(), AzToolsFramework::g_mainManipulatorManagerId,
polygonPrism->m_vertexContainer.GetVertices()[index], index);
}
void EditorPolygonPrismShapeComponentMode::OnVertexRemoved([[maybe_unused]] size_t index)
{
ContainerChanged();
}
void EditorPolygonPrismShapeComponentMode::OnVerticesSet(const AZStd::vector<AZ::Vector2>& /*vertices*/)
{
ContainerChanged();
}
void EditorPolygonPrismShapeComponentMode::OnVerticesCleared()
{
ContainerChanged();
}
} // namespace LmbrCentral