3
0

CanApplyDefaultParameterValues.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <gtest/gtest.h>
  9. #include <gmock/gmock.h>
  10. #include <AzCore/Component/Entity.h>
  11. #include <AzCore/Component/EntityId.h>
  12. #include <AzCore/Script/ScriptProperty.h>
  13. #include <AzCore/std/smart_ptr/unique_ptr.h>
  14. #include <AzFramework/Components/TransformComponent.h>
  15. #include <MCore/Source/AttributeString.h>
  16. #include <MCore/Source/AttributeFloat.h>
  17. #include <MCore/Source/AttributeBool.h>
  18. #include <EMotionFX/Source/Parameter/BoolParameter.h>
  19. #include <EMotionFX/Source/Parameter/FloatSliderParameter.h>
  20. #include <EMotionFX/Source/Parameter/StringParameter.h>
  21. #include <EMotionFX/Source/MotionSet.h>
  22. #include <Integration/Assets/MotionSetAsset.h>
  23. #include <Integration/Components/ActorComponent.h>
  24. #include <Integration/Components/AnimGraphComponent.h>
  25. #include <Tests/SystemComponentFixture.h>
  26. #include <Tests/TestAssetCode/ActorAssetFactory.h>
  27. #include <Tests/TestAssetCode/ActorFactory.h>
  28. #include <Tests/TestAssetCode/AnimGraphAssetFactory.h>
  29. #include <Tests/TestAssetCode/AnimGraphFactory.h>
  30. #include <Tests/TestAssetCode/MotionSetAssetFactory.h>
  31. #include <Tests/TestAssetCode/SimpleActors.h>
  32. namespace EMotionFX
  33. {
  34. class AnimGraphComponentDefaultParameterValuesFixture
  35. : public SystemComponentFixture
  36. {
  37. // The AnimGraphComponent supports setting default values for parameters in the AnimGraph, overriding the default value specified in
  38. // the AnimGraph itself.
  39. // This template correlates value types with how they are stored in the different places. The underlying parameter uses a typed
  40. // MCore::Attribute, the Component uses a typed ScriptProperty, and the parameter itself is also typed. This correlates all the
  41. // types together.
  42. template <typename ValueType>
  43. struct ParameterTypeTraits;
  44. public:
  45. void SetUp() override
  46. {
  47. SystemComponentFixture::SetUp();
  48. m_app.RegisterComponentDescriptor(Integration::ActorComponent::CreateDescriptor());
  49. m_app.RegisterComponentDescriptor(Integration::AnimGraphComponent::CreateDescriptor());
  50. m_app.RegisterComponentDescriptor(AzFramework::TransformComponent::CreateDescriptor());
  51. }
  52. template<typename T, typename Matcher>
  53. void CanApplyDefaultParameterValues(T initialDefaultValue, T customDefaultValue, const Matcher& matcherFactory)
  54. {
  55. using ParameterType = typename ParameterTypeTraits<T>::ParameterType;
  56. using ScriptPropertyType = typename ParameterTypeTraits<T>::ScriptPropertyType;
  57. using AttributeType = typename ParameterTypeTraits<T>::AttributeType;
  58. const char* parameterName{"Parameter"};
  59. auto parameter = aznew ParameterType(parameterName);
  60. parameter->SetDefaultValue(initialDefaultValue);
  61. auto animGraphAsset = AnimGraphAssetFactory::Create(AZ::Data::AssetId("{B4EE9F32-84F7-4F89-B643-A2B9905242ED}"), AnimGraphFactory::Create<EmptyAnimGraph>());
  62. animGraphAsset->GetAnimGraph()->AddParameter(parameter);
  63. auto motionSetAsset = MotionSetAssetFactory::Create(AZ::Data::AssetId("{D4CB9179-2388-473D-9B04-D88BC7B9B990}"), aznew MotionSet());
  64. auto actorAsset = ActorAssetFactory::Create(AZ::Data::AssetId("{A0E136B5-636F-4E10-9D09-0BF40A774760}"), ActorFactory::CreateAndInit<SimpleJointChainActor>(1));
  65. auto entity = AZStd::make_unique<AZ::Entity>(AZ::EntityId(8934213));
  66. entity->CreateComponent<AzFramework::TransformComponent>();
  67. Integration::AnimGraphComponent::Configuration animGraphConfig{animGraphAsset, motionSetAsset, {}, false, {{aznew ScriptPropertyType(parameterName, customDefaultValue)}}};
  68. auto animGraphComponent = entity->CreateComponent<EMotionFX::Integration::AnimGraphComponent>(&animGraphConfig);
  69. Integration::ActorComponent::Configuration actorConfig{actorAsset};
  70. auto actorComponent = entity->CreateComponent<EMotionFX::Integration::ActorComponent>(&actorConfig);
  71. entity->Init();
  72. entity->Activate();
  73. actorComponent->SetActorAsset(actorAsset);
  74. const auto matchesInitialValue = AZStd::invoke(matcherFactory, initialDefaultValue);
  75. const auto matchesCustomValue = AZStd::invoke(matcherFactory, customDefaultValue);
  76. EXPECT_THAT(parameter->GetDefaultValue(), matchesInitialValue);
  77. EXPECT_THAT(static_cast<AttributeType*>(animGraphComponent->GetAnimGraphInstance()->FindParameter(parameterName))->GetValue(), matchesCustomValue);
  78. }
  79. };
  80. template<>
  81. struct AnimGraphComponentDefaultParameterValuesFixture::ParameterTypeTraits<float>
  82. {
  83. using ParameterType = FloatSliderParameter;
  84. using ScriptPropertyType = AZ::ScriptPropertyNumber;
  85. using AttributeType = MCore::AttributeFloat;
  86. };
  87. template<>
  88. struct AnimGraphComponentDefaultParameterValuesFixture::ParameterTypeTraits<const char*>
  89. {
  90. using ParameterType = StringParameter;
  91. using ScriptPropertyType = AZ::ScriptPropertyString;
  92. using AttributeType = MCore::AttributeString;
  93. };
  94. template<>
  95. struct AnimGraphComponentDefaultParameterValuesFixture::ParameterTypeTraits<bool>
  96. {
  97. using ParameterType = BoolParameter;
  98. using ScriptPropertyType = AZ::ScriptPropertyBoolean;
  99. using AttributeType = MCore::AttributeBool;
  100. };
  101. // To support changing the test's comparison function based on its type, a factory function to create a matcher from a value is passed
  102. // to the test function. These functions are overloaded, so a static_cast is necessary to choose the right one. And their return types
  103. // use gtest-internal types, so decltype is used to get the function's return type
  104. #define MatcherFnAddress(matcher, exampleValue, argType) static_cast<decltype(matcher(exampleValue)) (*)(argType)>(matcher)
  105. TEST_F(AnimGraphComponentDefaultParameterValuesFixture, CanApplyDefaultParameterValuesFloat)
  106. {
  107. CanApplyDefaultParameterValues<float>(5.0f, 10.0f, MatcherFnAddress(testing::FloatEq, 0.0f, float));
  108. }
  109. TEST_F(AnimGraphComponentDefaultParameterValuesFixture, CanApplyDefaultParameterValuesBool)
  110. {
  111. CanApplyDefaultParameterValues<bool>(false, true, MatcherFnAddress(testing::Eq, true, bool));
  112. }
  113. TEST_F(AnimGraphComponentDefaultParameterValuesFixture, CanApplyDefaultParameterValuesString)
  114. {
  115. CanApplyDefaultParameterValues<const char*>("defaultString", "customString", MatcherFnAddress(StrEq, "", const AZStd::string&));
  116. }
  117. } // namespace EMotionFX