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
300 lines
14 KiB
C++
300 lines
14 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 "SequenceAgent.h"
|
|
#include <AzCore/Math/Color.h>
|
|
#include <AzCore/Component/ComponentApplicationBus.h>
|
|
#include <AzCore/Component/Entity.h>
|
|
|
|
namespace Maestro
|
|
{
|
|
namespace SequenceAgentHelper
|
|
{
|
|
template <typename T>
|
|
AZ_INLINE void DoSafeSet(AZ::BehaviorEBus::VirtualProperty* prop, AZ::EntityId entityId, T& data)
|
|
{
|
|
if (!prop->m_setter)
|
|
{
|
|
return;
|
|
}
|
|
if (prop->m_setter->m_event)
|
|
{
|
|
prop->m_setter->m_event->Invoke(entityId, data);
|
|
}
|
|
else if (prop->m_setter->m_broadcast)
|
|
{
|
|
prop->m_setter->m_broadcast->Invoke(data);
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
AZ_INLINE void DoSafeGet(AZ::BehaviorEBus::VirtualProperty* prop, AZ::EntityId entityId, T& data)
|
|
{
|
|
if (!prop->m_getter)
|
|
{
|
|
return;
|
|
}
|
|
if (prop->m_getter->m_event)
|
|
{
|
|
prop->m_getter->m_event->InvokeResult(data, entityId);
|
|
}
|
|
else if (prop->m_getter->m_broadcast)
|
|
{
|
|
prop->m_getter->m_broadcast->InvokeResult(data);
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
void SequenceAgent::CacheAllVirtualPropertiesFromBehaviorContext()
|
|
{
|
|
AZ::BehaviorContext* behaviorContext = nullptr;
|
|
EBUS_EVENT_RESULT(behaviorContext, AZ::ComponentApplicationBus, GetBehaviorContext);
|
|
|
|
AZ::Entity::ComponentArrayType entityComponents;
|
|
GetEntityComponents(entityComponents);
|
|
|
|
m_addressToBehaviorVirtualPropertiesMap.clear();
|
|
|
|
for (AZ::Component* component : entityComponents)
|
|
{
|
|
auto findClassIter = behaviorContext->m_typeToClassMap.find(GetComponentTypeUuid(*component));
|
|
if (findClassIter != behaviorContext->m_typeToClassMap.end())
|
|
{
|
|
AZ::BehaviorClass* behaviorClass = findClassIter->second;
|
|
// go through all ebuses for this class and find all virtual properties
|
|
for (auto reqBusName = behaviorClass->m_requestBuses.begin(); reqBusName != behaviorClass->m_requestBuses.end(); reqBusName++)
|
|
{
|
|
auto findBusIter = behaviorContext->m_ebuses.find(*reqBusName);
|
|
if (findBusIter != behaviorContext->m_ebuses.end())
|
|
{
|
|
AZ::BehaviorEBus* behaviorEbus = findBusIter->second;
|
|
for (auto virtualPropertyIter = behaviorEbus->m_virtualProperties.begin(); virtualPropertyIter != behaviorEbus->m_virtualProperties.end(); virtualPropertyIter++)
|
|
{
|
|
Maestro::SequenceComponentRequests::AnimatablePropertyAddress address(component->GetId(), virtualPropertyIter->first);
|
|
m_addressToBehaviorVirtualPropertiesMap[address] = &virtualPropertyIter->second;
|
|
}
|
|
|
|
// Check for the GetAssetDuration event is present and cache it
|
|
for (auto eventIter = behaviorEbus->m_events.begin(); eventIter != behaviorEbus->m_events.end(); eventIter++)
|
|
{
|
|
if (eventIter->first == "GetAssetDuration")
|
|
{
|
|
AZ::BehaviorEBusEventSender* sender = &eventIter->second;
|
|
|
|
// Sanity check, Shouldn't be able to get here.
|
|
if (nullptr == sender)
|
|
{
|
|
AZ_Error("SequenceAgent", false, "EBus %s, GetAssetDuration sender is null.", behaviorEbus->m_name.c_str());
|
|
continue;
|
|
}
|
|
|
|
// Sanity check, m_broadcast should always be valid.
|
|
if (nullptr == sender->m_broadcast)
|
|
{
|
|
AZ_Error("SequenceAgent", false, "EBus %s, GetAssetDuration sender->m_broadcast is null.", behaviorEbus->m_name.c_str());
|
|
continue;
|
|
}
|
|
|
|
// GetAssetDuration shoulder return a float.
|
|
if (!sender->m_broadcast->HasResult())
|
|
{
|
|
AZ_Error("SequenceAgent", false, "EBus %s, GetAssetDuration should return result", behaviorEbus->m_name.c_str());
|
|
continue;
|
|
}
|
|
|
|
// GetAssetDuration should take an asset id.
|
|
if (sender->m_broadcast->GetNumArguments() != 1)
|
|
{
|
|
AZ_Error("SequenceAgent", false, "EBus %s, GetAssetDuration should take one argument, an asset id.", behaviorEbus->m_name.c_str());
|
|
continue;
|
|
}
|
|
|
|
m_addressToGetAssetDurationMap[component->GetId()] = sender;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
AZ::Uuid SequenceAgent::GetVirtualPropertyTypeId(const Maestro::SequenceComponentRequests::AnimatablePropertyAddress& animatableAddress) const
|
|
{
|
|
AZ::Uuid retTypeUuid = AZ::Uuid::CreateNull();
|
|
|
|
auto findIter = m_addressToBehaviorVirtualPropertiesMap.find(animatableAddress);
|
|
if (findIter != m_addressToBehaviorVirtualPropertiesMap.end())
|
|
{
|
|
if (findIter->second->m_getter->m_event)
|
|
{
|
|
retTypeUuid = findIter->second->m_getter->m_event->GetResult()->m_typeId;
|
|
}
|
|
else if(findIter->second->m_getter->m_broadcast)
|
|
{
|
|
retTypeUuid = findIter->second->m_getter->m_broadcast->GetResult()->m_typeId;
|
|
}
|
|
}
|
|
return retTypeUuid;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
bool SequenceAgent::SetAnimatedPropertyValue(AZ::EntityId entityId, const Maestro::SequenceComponentRequests::AnimatablePropertyAddress& animatableAddress, const Maestro::SequenceComponentRequests::AnimatedValue& value)
|
|
{
|
|
bool changed = false;
|
|
const AZ::Uuid propertyTypeId = GetVirtualPropertyTypeId(animatableAddress);
|
|
|
|
auto findIter = m_addressToBehaviorVirtualPropertiesMap.find(animatableAddress);
|
|
if (findIter != m_addressToBehaviorVirtualPropertiesMap.end())
|
|
{
|
|
if (propertyTypeId == AZ::Vector3::TYPEINFO_Uuid())
|
|
{
|
|
AZ::Vector3 vector3Value(.0f, .0f, .0f);
|
|
value.GetValue(vector3Value); // convert the generic value to a Vector3
|
|
SequenceAgentHelper::DoSafeSet(findIter->second, entityId, vector3Value);
|
|
changed = true;
|
|
}
|
|
else if (propertyTypeId == AZ::Color::TYPEINFO_Uuid())
|
|
{
|
|
AZ::Vector3 vector3Value(.0f, .0f, .0f);
|
|
value.GetValue(vector3Value); // convert the generic value to a Vector3
|
|
AZ::Color colorValue(AZ::Color::CreateFromVector3(vector3Value));
|
|
SequenceAgentHelper::DoSafeSet(findIter->second, entityId, colorValue);
|
|
changed = true;
|
|
}
|
|
else if (propertyTypeId == AZ::Quaternion::TYPEINFO_Uuid())
|
|
{
|
|
AZ::Quaternion quaternionValue(AZ::Quaternion::CreateIdentity());
|
|
value.GetValue(quaternionValue);
|
|
SequenceAgentHelper::DoSafeSet(findIter->second, entityId, quaternionValue);
|
|
changed = true;
|
|
}
|
|
else if (propertyTypeId == AZ::AzTypeInfo<bool>::Uuid())
|
|
{
|
|
bool boolValue = true;
|
|
value.GetValue(boolValue); // convert the generic value to a bool
|
|
SequenceAgentHelper::DoSafeSet(findIter->second, entityId, boolValue);
|
|
changed = true;
|
|
}
|
|
else if (propertyTypeId == AZ::AzTypeInfo<AZ::s32>::Uuid())
|
|
{
|
|
AZ::s32 s32value = 0;
|
|
value.GetValue(s32value);
|
|
findIter->second->m_setter->m_event->Invoke(entityId, s32value);
|
|
changed = true;
|
|
}
|
|
else if (propertyTypeId == AZ::AzTypeInfo<AZ::u32>::Uuid())
|
|
{
|
|
AZ::u32 u32value = 0;
|
|
value.GetValue(u32value);
|
|
findIter->second->m_setter->m_event->Invoke(entityId, u32value);
|
|
changed = true;
|
|
}
|
|
else if (propertyTypeId == AZ::AzTypeInfo<AZ::Data::AssetId>::Uuid())
|
|
{
|
|
AZ::Data::AssetId assetIdValue;
|
|
value.GetValue(assetIdValue);
|
|
findIter->second->m_setter->m_event->Invoke(entityId, assetIdValue);
|
|
changed = true;
|
|
}
|
|
else
|
|
{
|
|
// fall-through default is to cast to float
|
|
float floatValue = .0f;
|
|
value.GetValue(floatValue); // convert the generic value to a float
|
|
SequenceAgentHelper::DoSafeSet(findIter->second, entityId, floatValue);
|
|
changed = true;
|
|
}
|
|
}
|
|
return changed;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void SequenceAgent::GetAnimatedPropertyValue(Maestro::SequenceComponentRequests::AnimatedValue& returnValue, AZ::EntityId entityId, const Maestro::SequenceComponentRequests::AnimatablePropertyAddress& animatableAddress)
|
|
{
|
|
const AZ::Uuid propertyTypeId = GetVirtualPropertyTypeId(animatableAddress);
|
|
|
|
auto findIter = m_addressToBehaviorVirtualPropertiesMap.find(animatableAddress);
|
|
if (findIter != m_addressToBehaviorVirtualPropertiesMap.end())
|
|
{
|
|
if (propertyTypeId == AZ::Vector3::TYPEINFO_Uuid())
|
|
{
|
|
AZ::Vector3 vector3Value(AZ::Vector3::CreateZero());
|
|
SequenceAgentHelper::DoSafeGet(findIter->second, entityId, vector3Value);
|
|
returnValue.SetValue(vector3Value);
|
|
}
|
|
else if (propertyTypeId == AZ::Color::TYPEINFO_Uuid())
|
|
{
|
|
AZ::Color colorValue(AZ::Color::CreateZero());
|
|
SequenceAgentHelper::DoSafeGet(findIter->second, entityId, colorValue);
|
|
returnValue.SetValue((AZ::Vector3)colorValue);
|
|
}
|
|
else if (propertyTypeId == AZ::Quaternion::TYPEINFO_Uuid())
|
|
{
|
|
AZ::Quaternion quaternionValue(AZ::Quaternion::CreateIdentity());
|
|
SequenceAgentHelper::DoSafeGet(findIter->second, entityId, quaternionValue);
|
|
returnValue.SetValue(quaternionValue);
|
|
}
|
|
else if (propertyTypeId == AZ::AzTypeInfo<bool>::Uuid())
|
|
{
|
|
bool boolValue = false;
|
|
SequenceAgentHelper::DoSafeGet(findIter->second, entityId, boolValue);
|
|
returnValue.SetValue(boolValue);
|
|
}
|
|
else if (propertyTypeId == AZ::AzTypeInfo<AZ::s32>::Uuid())
|
|
{
|
|
AZ::s32 s32Value;
|
|
findIter->second->m_getter->m_event->InvokeResult(s32Value, entityId);
|
|
returnValue.SetValue(s32Value);
|
|
}
|
|
else if (propertyTypeId == AZ::AzTypeInfo<AZ::u32>::Uuid())
|
|
{
|
|
AZ::u32 u32Value;
|
|
findIter->second->m_getter->m_event->InvokeResult(u32Value, entityId);
|
|
returnValue.SetValue(u32Value);
|
|
}
|
|
else if (propertyTypeId == AZ::AzTypeInfo<AZ::Data::AssetId>::Uuid())
|
|
{
|
|
AZ::Data::AssetId assetIdValue;
|
|
findIter->second->m_getter->m_event->InvokeResult(assetIdValue, entityId);
|
|
returnValue.SetValue(assetIdValue);
|
|
}
|
|
else
|
|
{
|
|
// fall-through default is to cast to float
|
|
float floatValue = .0f;
|
|
SequenceAgentHelper::DoSafeGet(findIter->second, entityId, floatValue);
|
|
returnValue.SetValue(floatValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SequenceAgent::GetAssetDuration(Maestro::SequenceComponentRequests::AnimatedValue& returnValue, AZ::ComponentId componentId, const AZ::Data::AssetId& assetId)
|
|
{
|
|
auto findIter = m_addressToGetAssetDurationMap.find(componentId);
|
|
if (findIter != m_addressToGetAssetDurationMap.end())
|
|
{
|
|
if (nullptr != findIter->second)
|
|
{
|
|
AZ::BehaviorEBusEventSender* sender = findIter->second;
|
|
if (nullptr != sender)
|
|
{
|
|
AZ::BehaviorMethod* broadcast = sender->m_broadcast;
|
|
if (nullptr != broadcast)
|
|
{
|
|
float floatValue = 0.0f;
|
|
broadcast->InvokeResult(floatValue, assetId);
|
|
returnValue.SetValue(floatValue);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}// namespace Maestro
|