123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472 |
- /*
- * 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 <AzCore/Math/Color.h>
- #include <ScriptedEntityTweener/ScriptedEntityTweenerBus.h>
- #include "ScriptedEntityTweenerSubtask.h"
- AZ_PUSH_DISABLE_WARNING(4244, "-Wunknown-warning-option")
- #include "ScriptedEntityTweenerMath.h"
- AZ_POP_DISABLE_WARNING
- namespace ScriptedEntityTweener
- {
- namespace SubtaskHelper
- {
- template <typename T>
- AZ_INLINE void DoSafeSet(AZ::BehaviorEBus::VirtualProperty* prop, AZ::EntityId entityId, T& data)
- {
- if (!prop || !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 || !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);
- }
- }
- }
- bool ScriptedEntityTweenerSubtask::Initialize(const AnimationParameterAddressData& animParamData, const AZStd::any& targetValue, const AnimationProperties& properties)
- {
- Reset();
- if (CacheVirtualProperty(animParamData))
- {
- // Set initial value
- if (GetVirtualValue(m_valueInitial))
- {
- if (GetValueFromAny(m_valueTarget, targetValue))
- {
- m_isActive = true;
- m_animationProperties = properties;
- if (m_animationProperties.m_isFrom)
- {
- EntityAnimatedValue initialValue = m_valueInitial;
- m_valueInitial = m_valueTarget;
- m_valueTarget = initialValue;
- }
- return true;
- }
- }
- }
- AZ_Warning("ScriptedEntityTweenerSubtask", false, "ScriptedEntityTweenerSubtask::Initialize - Initialization failed for [%s, %s]", m_animParamData.m_componentName.c_str(), m_animParamData.m_virtualPropertyName.c_str());
- return false;
- }
- void ScriptedEntityTweenerSubtask::Update(float deltaTime, AZStd::set<CallbackData>& callbacks)
- {
- if (m_isPaused || !m_isActive)
- {
- return;
- }
- //TODO: Use m_animationProperties.m_amplitudeOverride
-
- float timeAnimationActive = AZ::GetClamp(m_timeSinceStart + m_animationProperties.m_timeIntoAnimation, .0f, m_animationProperties.m_timeDuration);
- //If animation is meant to complete instantly, set timeToComplete and timeAnimationActive to the same non-zero value, so GetEasingResult will return m_valueTarget
- if (m_animationProperties.m_timeDuration == 0)
- {
- m_animationProperties.m_timeDuration = timeAnimationActive = 1.0f;
- }
- EntityAnimatedValue currentValue;
- if (m_virtualPropertyTypeId == AZ::AzTypeInfo<float>::Uuid())
- {
- float initialValue;
- m_valueInitial.GetValue(initialValue);
- float targetValue;
- m_valueTarget.GetValue(targetValue);
- currentValue.SetValue(EasingEquations::GetEasingResult(m_animationProperties.m_easeMethod, m_animationProperties.m_easeType, timeAnimationActive, m_animationProperties.m_timeDuration, initialValue, targetValue));
- SetVirtualValue(currentValue);
- }
- else if (m_virtualPropertyTypeId == AZ::AzTypeInfo<AZ::Vector3>::Uuid() || m_virtualPropertyTypeId == AZ::AzTypeInfo<AZ::Color>::Uuid())
- {
- AZ::Vector3 initialValue;
- m_valueInitial.GetValue(initialValue);
- AZ::Vector3 targetValue;
- m_valueTarget.GetValue(targetValue);
- currentValue.SetValue(EasingEquations::GetEasingResult(m_animationProperties.m_easeMethod, m_animationProperties.m_easeType, timeAnimationActive, m_animationProperties.m_timeDuration, initialValue, targetValue));
- SetVirtualValue(currentValue);
- }
- else if (m_virtualPropertyTypeId == AZ::AzTypeInfo<AZ::Quaternion>::Uuid())
- {
- AZ::Quaternion initialValue;
- m_valueInitial.GetValue(initialValue);
- AZ::Quaternion targetValue;
- m_valueTarget.GetValue(targetValue);
- currentValue.SetValue(EasingEquations::GetEasingResult(m_animationProperties.m_easeMethod, m_animationProperties.m_easeType, timeAnimationActive, m_animationProperties.m_timeDuration, initialValue, targetValue));
- SetVirtualValue(currentValue);
- }
- float progressPercent = timeAnimationActive / m_animationProperties.m_timeDuration;
- if (m_animationProperties.m_isPlayingBackward)
- {
- progressPercent = 1.0f - progressPercent;
- }
- if (progressPercent >= 1.0f)
- {
- m_timesPlayed = m_timesPlayed + 1;
- if (m_timesPlayed >= m_animationProperties.m_timesToPlay && m_animationProperties.m_timesToPlay != -1)
- {
- m_isActive = false;
- if (m_animationProperties.m_onCompleteCallbackId != AnimationProperties::InvalidCallbackId)
- {
- callbacks.insert(CallbackData(CallbackTypes::OnComplete, m_animationProperties.m_onCompleteCallbackId));
- }
- if (m_animationProperties.m_onLoopCallbackId != AnimationProperties::InvalidCallbackId)
- {
- callbacks.insert(CallbackData(CallbackTypes::RemoveCallback, m_animationProperties.m_onLoopCallbackId));
- }
- if (m_animationProperties.m_onUpdateCallbackId != AnimationProperties::InvalidCallbackId)
- {
- callbacks.insert(CallbackData(CallbackTypes::RemoveCallback, m_animationProperties.m_onUpdateCallbackId));
- }
- }
- else
- {
- m_timeSinceStart = .0f;
- if (m_animationProperties.m_onLoopCallbackId != AnimationProperties::InvalidCallbackId)
- {
- callbacks.insert(CallbackData(CallbackTypes::OnLoop, m_animationProperties.m_onLoopCallbackId));
- }
- }
- }
- if (m_animationProperties.m_onUpdateCallbackId != AnimationProperties::InvalidCallbackId)
- {
- CallbackData updateCallback(CallbackTypes::OnUpdate, m_animationProperties.m_onUpdateCallbackId);
- GetValueAsAny(updateCallback.m_callbackData, currentValue);
- updateCallback.m_progressPercent = progressPercent;
- callbacks.insert(updateCallback);
- }
- if (m_animationProperties.m_isPlayingBackward)
- {
- deltaTime *= -1.0f;
- }
- m_timeSinceStart += (deltaTime * m_animationProperties.m_playbackSpeedMultiplier);
- }
- bool ScriptedEntityTweenerSubtask::CacheVirtualProperty(const AnimationParameterAddressData& animParamData)
- {
- /*
- Relies on some behavior context definitions for lookup
- behaviorContext->EBus<UiFaderBus>("UiFaderBus")
- ->Event("GetFadeValue", &UiFaderBus::Events::GetFadeValue)
- ->Event("SetFadeValue", &UiFaderBus::Events::SetFadeValue)
- ->VirtualProperty("Fade", "GetFadeValue", "SetFadeValue");
- behaviorContext->Class<UiFaderComponent>()->RequestBus("UiFaderBus");
- behaviorContext->EBus<UiFaderNotificationBus>("UiFaderNotificationBus")
- ->Handler<BehaviorUiFaderNotificationBusHandler>();
- */
- m_animParamData = animParamData;
- m_virtualProperty = nullptr;
- m_virtualPropertyTypeId = AZ::Uuid::CreateNull();
- AZ::BehaviorContext* behaviorContext = nullptr;
- AZ::ComponentApplicationBus::BroadcastResult(behaviorContext, &AZ::ComponentApplicationBus::Events::GetBehaviorContext);
- if (!behaviorContext)
- {
- AZ_Error("ScriptedEntityTweenerSubtask", false, "ScriptedEntityTweenerSubtask::CacheVirtualProperty - failed to get behavior context for caching [%s]", animParamData.m_virtualPropertyName.c_str());
- return false;
- }
- auto findClassIter = behaviorContext->m_classes.find(animParamData.m_componentName);
- if (findClassIter == behaviorContext->m_classes.end())
- {
- AZ_Warning("ScriptedEntityTweenerSubtask", false, "ScriptedEntityTweenerSubtask::CacheVirtualProperty - failed to find behavior component class by component name [%s]", animParamData.m_componentName.c_str());
- return false;
- }
- AZ::BehaviorEBus::VirtualProperty* virtualProperty = nullptr;
- AZ::Uuid virtualPropertyTypeId = AZ::Uuid::CreateNull();
- // Get the virtual property
- AZ::BehaviorClass* behaviorClass = findClassIter->second;
- 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;
- auto virtualPropertyIter = behaviorEbus->m_virtualProperties.find(animParamData.m_virtualPropertyName);
- if (virtualPropertyIter != behaviorEbus->m_virtualProperties.end())
- {
- virtualProperty = &virtualPropertyIter->second;
- break;
- }
- }
- }
- AZ_Warning("ScriptedEntityTweenerSubtask", virtualProperty, "ScriptedEntityTweenerSubtask::CacheVirtualProperty - failed to find virtual property by name [%s]", animParamData.m_virtualPropertyName.c_str());
- // Virtual properties with event setters/getters require a valid entityId
- if (virtualProperty)
- {
- if (((virtualProperty->m_setter && virtualProperty->m_setter->m_event)
- || (virtualProperty->m_getter && virtualProperty->m_getter->m_event))
- && !m_entityId.IsValid())
- {
- AZ_Warning("ScriptedEntityTweenerSubtask", false, "ScriptedEntityTweenerSubtask::CacheVirtualProperty - invalid entityId for virtual property's event setter/getter [%s, %s]", m_animParamData.m_componentName.c_str(), m_animParamData.m_virtualPropertyName.c_str());
- virtualProperty = nullptr;
- }
- }
- // Get the virtual property type
- if (virtualProperty)
- {
- if (virtualProperty->m_getter->m_event)
- {
- virtualPropertyTypeId = virtualProperty->m_getter->m_event->GetResult()->m_typeId;
- }
- else if (virtualProperty->m_getter->m_broadcast)
- {
- virtualPropertyTypeId = virtualProperty->m_getter->m_broadcast->GetResult()->m_typeId;
- }
- AZ_Warning("ScriptedEntityTweenerSubtask", !virtualPropertyTypeId.IsNull(), "ScriptedEntityTweenerSubtask::CacheVirtualProperty - failed to find virtual property type Id [%s]", animParamData.m_virtualPropertyName.c_str());
- }
- if (virtualProperty && !virtualPropertyTypeId.IsNull())
- {
- m_virtualProperty = virtualProperty;
- m_virtualPropertyTypeId = virtualPropertyTypeId;
- return true;
- }
- return false;
- }
- bool ScriptedEntityTweenerSubtask::IsVirtualPropertyCached()
- {
- return m_virtualProperty && !m_virtualPropertyTypeId.IsNull();
- }
- bool ScriptedEntityTweenerSubtask::GetValueFromAny(EntityAnimatedValue& value, const AZStd::any& anyValue)
- {
- if (!IsVirtualPropertyCached())
- {
- return false;
- }
- if (m_virtualPropertyTypeId == AZ::AzTypeInfo<float>::Uuid())
- {
- float floatVal;
- if (any_numeric_cast(&anyValue, floatVal))
- {
- value.SetValue(floatVal);
- }
- else
- {
- AZ_Warning("ScriptedEntityTweenerSubtask", false, "ScriptedEntityTweenerSubtask::GetValueFromAny - numeric cast to float failed [%s]", m_animParamData.m_virtualPropertyName.c_str());
- return false;
- }
- }
- else if (m_virtualPropertyTypeId == AZ::AzTypeInfo<AZ::Vector3>::Uuid() && anyValue.is<AZ::Vector3>())
- {
- value.SetValue(AZStd::any_cast<AZ::Vector3>(anyValue));
- }
- else if (m_virtualPropertyTypeId == AZ::AzTypeInfo<AZ::Color>::Uuid() && anyValue.is<AZ::Color>())
- {
- AZ::Color color = AZStd::any_cast<AZ::Color>(anyValue);
- value.SetValue(color.GetAsVector3());
- }
- else if (m_virtualPropertyTypeId == AZ::AzTypeInfo<AZ::Quaternion>::Uuid() && anyValue.is<AZ::Quaternion>())
- {
- value.SetValue(AZStd::any_cast<AZ::Quaternion>(anyValue));
- }
- else
- {
- AZ_Warning("ScriptedEntityTweenerSubtask", false, "ScriptedEntityTweenerSubtask::GetValueFromAny - Virtual property type unsupported [%s]", m_animParamData.m_virtualPropertyName.c_str());
- return false;
- }
- return true;
- }
- bool ScriptedEntityTweenerSubtask::GetValueAsAny(AZStd::any& anyValue, const EntityAnimatedValue& value)
- {
- if (!IsVirtualPropertyCached())
- {
- return false;
- }
- if (m_virtualPropertyTypeId == AZ::AzTypeInfo<float>::Uuid())
- {
- float floatVal;
- value.GetValue(floatVal);
- anyValue = floatVal;
- }
- else if (m_virtualPropertyTypeId == AZ::AzTypeInfo<AZ::Vector3>::Uuid())
- {
- AZ::Vector3 vectorValue;
- value.GetValue(vectorValue);
- anyValue = vectorValue;
- }
- else if (m_virtualPropertyTypeId == AZ::AzTypeInfo<AZ::Color>::Uuid())
- {
- AZ::Vector3 vectorValue;
- value.GetValue(vectorValue);
- anyValue = AZ::Color::CreateFromVector3(vectorValue);
- }
- else if (m_virtualPropertyTypeId == AZ::AzTypeInfo<AZ::Quaternion>::Uuid())
- {
- AZ::Quaternion quatValue;
- value.GetValue(quatValue);
- anyValue = quatValue;
- }
- else
- {
- AZ_Warning("ScriptedEntityTweenerSubtask", false, "ScriptedEntityTweenerSubtask::GetValueAsAny - Virtual property type unsupported [%s]", m_animParamData.m_virtualPropertyName.c_str());
- return false;
- }
- return true;
- }
- bool ScriptedEntityTweenerSubtask::GetVirtualValue(EntityAnimatedValue& animatedValue)
- {
- if (!IsVirtualPropertyCached())
- {
- return false;
- }
- if (m_virtualPropertyTypeId == AZ::AzTypeInfo<float>::Uuid())
- {
- float floatValue = 0.0f;
- SubtaskHelper::DoSafeGet(m_virtualProperty, m_entityId, floatValue);
- animatedValue.SetValue(floatValue);
- }
- else if (m_virtualPropertyTypeId == AZ::Vector3::TYPEINFO_Uuid())
- {
- AZ::Vector3 vector3Value(AZ::Vector3::CreateZero());
- SubtaskHelper::DoSafeGet(m_virtualProperty, m_entityId, vector3Value);
- animatedValue.SetValue(vector3Value);
- }
- else if (m_virtualPropertyTypeId == AZ::Color::TYPEINFO_Uuid())
- {
- AZ::Color colorValue(AZ::Color::CreateZero());
- SubtaskHelper::DoSafeGet(m_virtualProperty, m_entityId, colorValue);
- AZ::Vector3 vector3Value = colorValue.GetAsVector3();
- animatedValue.SetValue(vector3Value);
- }
- else if (m_virtualPropertyTypeId == AZ::Quaternion::TYPEINFO_Uuid())
- {
- AZ::Quaternion quaternionValue(AZ::Quaternion::CreateIdentity());
- SubtaskHelper::DoSafeGet(m_virtualProperty, m_entityId, quaternionValue);
- animatedValue.SetValue(quaternionValue);
- }
- else
- {
- AZ_Warning("ScriptedEntityTweenerSubtask", false, "ScriptedEntityTweenerSubtask::GetVirtualValue - Trying to get unsupported parameter type for [%s]", m_animParamData.m_virtualPropertyName.c_str());
- return false;
- }
- return true;
- }
- bool ScriptedEntityTweenerSubtask::SetVirtualValue(const EntityAnimatedValue& value)
- {
- if (!IsVirtualPropertyCached())
- {
- return false;
- }
- if (m_virtualPropertyTypeId == AZ::AzTypeInfo<float>::Uuid())
- {
- float floatValue;
- value.GetValue(floatValue);
- SubtaskHelper::DoSafeSet(m_virtualProperty, m_entityId, floatValue);
- }
- else if (m_virtualPropertyTypeId == AZ::Vector3::TYPEINFO_Uuid())
- {
- AZ::Vector3 vector3Value;
- value.GetValue(vector3Value);
- SubtaskHelper::DoSafeSet(m_virtualProperty, m_entityId, vector3Value);
- }
- else if (m_virtualPropertyTypeId == AZ::Color::TYPEINFO_Uuid())
- {
- AZ::Vector3 vector3Value;
- value.GetValue(vector3Value);
- AZ::Color colorValue(AZ::Color::CreateFromVector3(vector3Value));
- SubtaskHelper::DoSafeSet(m_virtualProperty, m_entityId, colorValue);
- }
- else if (m_virtualPropertyTypeId == AZ::Quaternion::TYPEINFO_Uuid())
- {
- AZ::Quaternion quaternionValue;
- value.GetValue(quaternionValue);
- SubtaskHelper::DoSafeSet(m_virtualProperty, m_entityId, quaternionValue);
- }
- else
- {
- AZ_Warning("ScriptedEntityTweenerSubtask", false, "ScriptedEntityTweenerSubtask::SetVirtualValue - Trying to set unsupported parameter type for [%s]", m_animParamData.m_virtualPropertyName.c_str());
- return false;
- }
- return true;
- }
- bool ScriptedEntityTweenerSubtask::GetVirtualPropertyValue(AZStd::any& returnVal, const AnimationParameterAddressData& animParamData)
- {
- // If this is called before initialization, the virtual property needs to be cached.
- // This method is available on the ScriptedEntityTweenerBus to retrieve a virtual property value on an entity
- // regardless of whether a task/subtask for that entity/virtual property has been created (added to an animation).
- // In that circumstance, a temproary task/subtask is created, but not initialized
- if (!IsVirtualPropertyCached())
- {
- CacheVirtualProperty(animParamData);
- }
- if (IsVirtualPropertyCached())
- {
- EntityAnimatedValue tempVal;
- if (GetVirtualValue(tempVal))
- {
- return GetValueAsAny(returnVal, tempVal);
- }
- }
- AZ_Warning("ScriptedEntityTweenerSubtask", false, "ScriptedEntityTweenerSubtask::GetVirtualPropertyValue - failed for [%s, %s]", m_animParamData.m_componentName.c_str(), m_animParamData.m_virtualPropertyName.c_str());
- return false;
- }
- }
|