1f9b284de2
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
345 lines
12 KiB
C++
345 lines
12 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 "SplineComponent.h"
|
|
|
|
#include <AzCore/RTTI/BehaviorContext.h>
|
|
#include <AzCore/Serialization/EditContext.h>
|
|
#include <AzCore/Serialization/SerializeContext.h>
|
|
#include <AzCore/std/smart_ptr/make_shared.h>
|
|
|
|
namespace LmbrCentral
|
|
{
|
|
using SplineComboBoxVec = AZStd::vector<AZStd::pair<size_t, AZStd::string>>;
|
|
static SplineComboBoxVec PopulateSplineTypeList()
|
|
{
|
|
return SplineComboBoxVec
|
|
{
|
|
AZStd::make_pair(AZ::LinearSpline::RTTI_Type().GetHash(), "Linear"),
|
|
AZStd::make_pair(AZ::BezierSpline::RTTI_Type().GetHash(), "Bezier"),
|
|
AZStd::make_pair(AZ::CatmullRomSpline::RTTI_Type().GetHash(), "Catmull-Rom")
|
|
};
|
|
}
|
|
|
|
static AZ::SplinePtr MakeSplinePtr(AZ::u64 splineType)
|
|
{
|
|
if (splineType == AZ::LinearSpline::RTTI_Type().GetHash())
|
|
{
|
|
return AZStd::make_shared<AZ::LinearSpline>();
|
|
}
|
|
|
|
if (splineType == AZ::BezierSpline::RTTI_Type().GetHash())
|
|
{
|
|
return AZStd::make_shared<AZ::BezierSpline>();
|
|
}
|
|
|
|
if (splineType == AZ::CatmullRomSpline::RTTI_Type().GetHash())
|
|
{
|
|
return AZStd::make_shared<AZ::CatmullRomSpline>();
|
|
}
|
|
|
|
AZ_Assert(false, "Unhandled spline type %d in %s", splineType, __FUNCTION__);
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
static AZ::SplinePtr CopySplinePtr(AZ::u64 splineType, const AZ::SplinePtr& spline)
|
|
{
|
|
if (splineType == AZ::LinearSpline::RTTI_Type().GetHash())
|
|
{
|
|
return AZStd::make_shared<AZ::LinearSpline>(*spline);
|
|
}
|
|
|
|
if (splineType == AZ::BezierSpline::RTTI_Type().GetHash())
|
|
{
|
|
return AZStd::make_shared<AZ::BezierSpline>(*spline);
|
|
}
|
|
|
|
if (splineType == AZ::CatmullRomSpline::RTTI_Type().GetHash())
|
|
{
|
|
return AZStd::make_shared<AZ::CatmullRomSpline>(*spline);
|
|
}
|
|
|
|
AZ_Assert(false, "Unhandled spline type %d in %s", splineType, __FUNCTION__);
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
SplineCommon::SplineCommon()
|
|
{
|
|
m_spline = MakeSplinePtr(m_splineType);
|
|
}
|
|
|
|
void SplineCommon::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<SplineCommon>()
|
|
->Version(1)
|
|
->Field("Spline Type", &SplineCommon::m_splineType)
|
|
->Field("Spline", &SplineCommon::m_spline);
|
|
|
|
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
|
{
|
|
editContext->Class<SplineCommon>("Configuration", "Spline configuration parameters")
|
|
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
|
//->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) // disabled - prevents ChangeNotify attribute firing correctly
|
|
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
|
->DataElement(AZ::Edit::UIHandlers::ComboBox, &SplineCommon::m_splineType, "Spline Type", "Interpolation type to use between vertices.")
|
|
->Attribute(AZ::Edit::Attributes::EnumValues, &PopulateSplineTypeList)
|
|
->Attribute(AZ::Edit::Attributes::ChangeNotify, &SplineCommon::OnChangeSplineType)
|
|
->DataElement(AZ::Edit::UIHandlers::Default, &SplineCommon::m_spline, "Spline", "Data representing the spline.")
|
|
//->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) // disabled - prevents ChangeNotify attribute firing correctly
|
|
->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, false)
|
|
->Attribute(AZ::Edit::Attributes::AutoExpand, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SplineCommon::ChangeSplineType(AZ::u64 splineType)
|
|
{
|
|
m_splineType = splineType;
|
|
OnChangeSplineType();
|
|
}
|
|
|
|
void SplineCommon::SetCallbacks(
|
|
const AZ::IndexFunction& OnAddVertex, const AZ::IndexFunction& OnRemoveVertex,
|
|
const AZ::IndexFunction& OnUpdateVertex, const AZ::VoidFunction& OnSetVertices,
|
|
const AZ::VoidFunction& OnClearVertices, const AZ::VoidFunction& OnChangeType,
|
|
const AZ::BoolFunction& OnOpenClose)
|
|
{
|
|
m_onAddVertex = OnAddVertex;
|
|
m_onRemoveVertex = OnRemoveVertex;
|
|
m_onUpdateVertex = OnUpdateVertex;
|
|
m_onSetVertices = OnSetVertices;
|
|
m_onClearVertices = OnClearVertices;
|
|
|
|
m_onChangeType = OnChangeType;
|
|
m_onOpenCloseChange = OnOpenClose;
|
|
|
|
m_spline->SetCallbacks(
|
|
OnAddVertex, OnRemoveVertex,
|
|
OnUpdateVertex, OnSetVertices,
|
|
OnClearVertices, OnOpenClose);
|
|
}
|
|
|
|
AZ::u32 SplineCommon::OnChangeSplineType()
|
|
{
|
|
AZ::u32 ret = AZ::Edit::PropertyRefreshLevels::None;
|
|
|
|
if (m_spline->RTTI_GetType().GetHash() != m_splineType)
|
|
{
|
|
m_spline = CopySplinePtr(m_splineType, m_spline);
|
|
m_spline->SetCallbacks(
|
|
m_onAddVertex, m_onRemoveVertex, m_onUpdateVertex,
|
|
m_onSetVertices, m_onClearVertices, m_onOpenCloseChange);
|
|
|
|
ret = AZ::Edit::PropertyRefreshLevels::EntireTree;
|
|
|
|
if (m_onChangeType)
|
|
{
|
|
m_onChangeType();
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/// BehaviorContext forwarder for SplineComponentNotificationBus
|
|
class BehaviorSplineComponentNotificationBusHandler
|
|
: public SplineComponentNotificationBus::Handler
|
|
, public AZ::BehaviorEBusHandler
|
|
{
|
|
public:
|
|
AZ_EBUS_BEHAVIOR_BINDER(BehaviorSplineComponentNotificationBusHandler, "{05816EA4-A4F0-4FB4-A82B-D6537B215D25}", AZ::SystemAllocator, OnSplineChanged);
|
|
|
|
void OnSplineChanged() override
|
|
{
|
|
Call(FN_OnSplineChanged);
|
|
}
|
|
};
|
|
|
|
void SplineComponent::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
SplineCommon::Reflect(context);
|
|
|
|
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<SplineComponent, AZ::Component>()
|
|
->Version(1)
|
|
->Field("Configuration", &SplineComponent::m_splineCommon);
|
|
}
|
|
|
|
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->EBus<SplineComponentNotificationBus>("SplineComponentNotificationBus")->
|
|
Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::All)->
|
|
Handler<BehaviorSplineComponentNotificationBusHandler>();
|
|
|
|
behaviorContext->EBus<SplineComponentRequestBus>("SplineComponentRequestBus")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Edit::Attributes::Category, "Shape")
|
|
->Attribute(AZ::Script::Attributes::Module, "shape")
|
|
->Event("GetSpline", &SplineComponentRequestBus::Events::GetSpline)
|
|
->Event("SetClosed", &SplineComponentRequestBus::Events::SetClosed)
|
|
->Event("AddVertex", &SplineComponentRequestBus::Events::AddVertex)
|
|
->Event("UpdateVertex", &SplineComponentRequestBus::Events::UpdateVertex)
|
|
->Event("InsertVertex", &SplineComponentRequestBus::Events::InsertVertex)
|
|
->Event("RemoveVertex", &SplineComponentRequestBus::Events::RemoveVertex)
|
|
->Event("ClearVertices", &SplineComponentRequestBus::Events::ClearVertices);
|
|
}
|
|
}
|
|
|
|
void SplineComponent::Activate()
|
|
{
|
|
m_currentTransform = AZ::Transform::CreateIdentity();
|
|
AZ::TransformBus::EventResult(m_currentTransform, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
|
|
|
|
AZ::TransformNotificationBus::Handler::BusConnect(GetEntityId());
|
|
SplineComponentRequestBus::Handler::BusConnect(GetEntityId());
|
|
|
|
const auto splineChanged = [this]()
|
|
{
|
|
SplineComponentNotificationBus::Event(
|
|
GetEntityId(), &SplineComponentNotificationBus::Events::OnSplineChanged);
|
|
};
|
|
|
|
const auto vertexAdded = [this, splineChanged](size_t index)
|
|
{
|
|
SplineComponentNotificationBus::Event(
|
|
GetEntityId(), &SplineComponentNotificationBus::Events::OnVertexAdded, index);
|
|
|
|
splineChanged();
|
|
};
|
|
|
|
const auto vertexRemoved = [this, splineChanged](size_t index)
|
|
{
|
|
SplineComponentNotificationBus::Event(
|
|
GetEntityId(), &SplineComponentNotificationBus::Events::OnVertexRemoved, index);
|
|
|
|
splineChanged();
|
|
};
|
|
|
|
const auto vertexUpdated = [this, splineChanged](size_t index)
|
|
{
|
|
SplineComponentNotificationBus::Event(
|
|
GetEntityId(), &SplineComponentNotificationBus::Events::OnVertexUpdated, index);
|
|
|
|
splineChanged();
|
|
};
|
|
|
|
const auto verticesSet = [this, splineChanged]()
|
|
{
|
|
SplineComponentNotificationBus::Event(
|
|
GetEntityId(),
|
|
&SplineComponentNotificationBus::Events::OnVerticesSet,
|
|
m_splineCommon.m_spline->GetVertices()
|
|
);
|
|
|
|
splineChanged();
|
|
};
|
|
|
|
const auto verticesCleared = [this, splineChanged]()
|
|
{
|
|
SplineComponentNotificationBus::Event(
|
|
GetEntityId(), &SplineComponentNotificationBus::Events::OnVerticesCleared);
|
|
|
|
splineChanged();
|
|
};
|
|
|
|
const auto openCloseChanged = [this, splineChanged](const bool closed)
|
|
{
|
|
SplineComponentNotificationBus::Event(
|
|
GetEntityId(), &SplineComponentNotificationBus::Events::OnOpenCloseChanged, closed);
|
|
|
|
splineChanged();
|
|
};
|
|
|
|
m_splineCommon.SetCallbacks(
|
|
vertexAdded,
|
|
vertexRemoved,
|
|
vertexUpdated,
|
|
verticesSet,
|
|
verticesCleared,
|
|
splineChanged,
|
|
openCloseChanged);
|
|
}
|
|
|
|
void SplineComponent::Deactivate()
|
|
{
|
|
SplineComponentRequestBus::Handler::BusDisconnect();
|
|
AZ::TransformNotificationBus::Handler::BusDisconnect();
|
|
}
|
|
|
|
void SplineComponent::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world)
|
|
{
|
|
m_currentTransform = world;
|
|
}
|
|
|
|
AZ::SplinePtr SplineComponent::GetSpline()
|
|
{
|
|
return m_splineCommon.m_spline;
|
|
}
|
|
|
|
void SplineComponent::ChangeSplineType(AZ::u64 splineType)
|
|
{
|
|
m_splineCommon.ChangeSplineType(splineType);
|
|
}
|
|
|
|
bool SplineComponent::UpdateVertex(size_t index, const AZ::Vector3& vertex)
|
|
{
|
|
return m_splineCommon.m_spline->m_vertexContainer.UpdateVertex(index, vertex);
|
|
}
|
|
|
|
bool SplineComponent::GetVertex(size_t index, AZ::Vector3& vertex) const
|
|
{
|
|
return m_splineCommon.m_spline->m_vertexContainer.GetVertex(index, vertex);
|
|
}
|
|
|
|
void SplineComponent::AddVertex(const AZ::Vector3& vertex)
|
|
{
|
|
m_splineCommon.m_spline->m_vertexContainer.AddVertex(vertex);
|
|
}
|
|
|
|
bool SplineComponent::InsertVertex(size_t index, const AZ::Vector3& vertex)
|
|
{
|
|
return m_splineCommon.m_spline->m_vertexContainer.InsertVertex(index, vertex);
|
|
}
|
|
|
|
bool SplineComponent::RemoveVertex(size_t index)
|
|
{
|
|
return m_splineCommon.m_spline->m_vertexContainer.RemoveVertex(index);
|
|
}
|
|
|
|
void SplineComponent::SetVertices(const AZStd::vector<AZ::Vector3>& vertices)
|
|
{
|
|
m_splineCommon.m_spline->m_vertexContainer.SetVertices(vertices);
|
|
}
|
|
|
|
void SplineComponent::ClearVertices()
|
|
{
|
|
m_splineCommon.m_spline->m_vertexContainer.Clear();
|
|
}
|
|
|
|
bool SplineComponent::Empty() const
|
|
{
|
|
return m_splineCommon.m_spline->m_vertexContainer.Empty();
|
|
}
|
|
|
|
size_t SplineComponent::Size() const
|
|
{
|
|
return m_splineCommon.m_spline->m_vertexContainer.Size();
|
|
}
|
|
|
|
void SplineComponent::SetClosed(const bool closed)
|
|
{
|
|
// set closed callback calls OnSplineChanged
|
|
m_splineCommon.m_spline->SetClosed(closed);
|
|
}
|
|
} // namespace LmbrCentral
|