/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace EMotionFX { class AnimGraphComponentNotificationTestBus : Integration::AnimGraphComponentNotificationBus::Handler { public: AnimGraphComponentNotificationTestBus(AZ::EntityId entityId) { Integration::AnimGraphComponentNotificationBus::Handler::BusConnect(entityId); } ~AnimGraphComponentNotificationTestBus() { Integration::AnimGraphComponentNotificationBus::Handler::BusDisconnect(); } MOCK_METHOD1(OnAnimGraphInstanceCreated, void(EMotionFX::AnimGraphInstance*)); MOCK_METHOD1(OnAnimGraphInstanceDestroyed, void(EMotionFX::AnimGraphInstance*)); MOCK_METHOD4(OnAnimGraphFloatParameterChanged, void(EMotionFX::AnimGraphInstance*, AZ::u32, float, float)); MOCK_METHOD4(OnAnimGraphBoolParameterChanged, void(EMotionFX::AnimGraphInstance*, AZ::u32, bool, bool)); MOCK_METHOD4(OnAnimGraphStringParameterChanged, void(EMotionFX::AnimGraphInstance*, AZ::u32, const char*, const char*)); MOCK_METHOD4(OnAnimGraphVector2ParameterChanged, void(EMotionFX::AnimGraphInstance*, AZ::u32, const AZ::Vector2&, const AZ::Vector2&)); MOCK_METHOD4(OnAnimGraphVector3ParameterChanged, void(EMotionFX::AnimGraphInstance*, AZ::u32, const AZ::Vector3&, const AZ::Vector3&)); MOCK_METHOD4(OnAnimGraphRotationParameterChanged, void(EMotionFX::AnimGraphInstance*, AZ::u32, const AZ::Quaternion&, const AZ::Quaternion&)); }; class AnimGraphComponentBusTests : public EntityComponentFixture { public: void SetUp() override { EntityComponentFixture::SetUp(); m_entity = AZStd::make_unique(); m_entityId = AZ::EntityId(740216387); m_entity->SetId(m_entityId); auto transformComponent = m_entity->CreateComponent(); auto actorComponent = m_entity->CreateComponent(); m_animGraphComponent = m_entity->CreateComponent(); m_entity->Init(); // Anim graph asset. AZ::Data::AssetId animGraphAssetId("{37629818-5166-4B96-83F5-5818B6A1F449}"); m_animGraphComponent->SetAnimGraphAssetId(animGraphAssetId); AZ::Data::Asset animGraphAsset = AZ::Data::AssetManager::Instance().CreateAsset(animGraphAssetId); AZStd::unique_ptr motionNodeAnimGraph = AnimGraphFactory::Create(); m_animGraph = motionNodeAnimGraph.get(); motionNodeAnimGraph.release(); animGraphAsset.GetAs()->SetData(m_animGraph); EXPECT_EQ(animGraphAsset.IsReady(), true) << "Anim graph asset is not ready yet."; m_animGraphComponent->OnAssetReady(animGraphAsset); // Motion set asset. AZ::Data::AssetId motionSetAssetId("{224BFF5F-D0AD-4216-9CEF-42F419CC6265}"); m_animGraphComponent->SetMotionSetAssetId(motionSetAssetId); AZ::Data::Asset motionSetAsset = AZ::Data::AssetManager::Instance().CreateAsset(motionSetAssetId); motionSetAsset.GetAs()->SetData(new MotionSet()); EXPECT_EQ(motionSetAsset.IsReady(), true) << "Motion set asset is not ready yet."; m_animGraphComponent->OnAssetReady(motionSetAsset); // Actor asset. AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}"); AZStd::unique_ptr actor = ActorFactory::CreateAndInit(); AZ::Data::Asset actorAsset = TestActorAssets::GetAssetFromActor(actorAssetId, AZStd::move(actor)); actorComponent->OnAssetReady(actorAsset); } void ActivateEntity() { m_entity->Activate(); m_animGraphInstance = m_animGraphComponent->GetAnimGraphInstance(); EXPECT_NE(m_animGraphInstance, nullptr) << "Expecting valid anim graph instance."; } void PrepareParameterTest(ValueParameter* parameter) { ActivateEntity(); m_animGraphInstance = m_animGraphComponent->GetAnimGraphInstance(); EXPECT_NE(m_animGraphInstance, nullptr) << "Expecting valid anim graph instance."; m_parameterName = "Test Parameter"; parameter->SetName(m_parameterName.c_str()); m_animGraph->AddParameter(parameter); m_animGraphInstance->AddMissingParameterValues(); // FindParameterIndex() test Integration::AnimGraphComponentRequestBus::EventResult(m_parameterIndex, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::FindParameterIndex, m_parameterName.c_str()); EXPECT_EQ(m_parameterIndex, 0) << "Expected the index for the first parameter."; // FindParameterName() test const char* foundParameterName = nullptr; Integration::AnimGraphComponentRequestBus::EventResult(foundParameterName, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::FindParameterName, m_parameterIndex); EXPECT_STREQ(foundParameterName, m_parameterName.c_str()) << "Expected the index for the first parameter."; } AZ::EntityId m_entityId; AZStd::unique_ptr m_entity; TwoMotionNodeAnimGraph* m_animGraph = nullptr; Integration::AnimGraphComponent* m_animGraphComponent = nullptr; AnimGraphInstance* m_animGraphInstance = nullptr; AZ::u32 m_parameterIndex = InvalidIndex32; std::string m_parameterName; }; TEST_F(AnimGraphComponentBusTests, GetAnimGraphInstance) { ActivateEntity(); AnimGraphInstance* animgrGraphInstance = nullptr; Integration::AnimGraphComponentRequestBus::EventResult(animgrGraphInstance, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetAnimGraphInstance); EXPECT_NE(animgrGraphInstance, nullptr) << "Expecting valid anim graph instance."; EXPECT_EQ(animgrGraphInstance, m_animGraphInstance) << "Expecting the anim graph instance from our anim graph component."; } TEST_F(AnimGraphComponentBusTests, FloatParameter) { AnimGraphComponentNotificationTestBus testBus(m_entityId); EXPECT_CALL(testBus, OnAnimGraphInstanceCreated(testing::_)); PrepareParameterTest(aznew FloatSliderParameter()); EXPECT_CALL(testBus, OnAnimGraphFloatParameterChanged(m_animGraphInstance, m_parameterIndex, testing::_, 3.0f)); // SetParameterFloat/GetParameterFloat() test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterFloat, m_parameterIndex, 3.0f); float newValue = 0.0f; Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetParameterFloat, m_parameterIndex); EXPECT_EQ(newValue, 3.0f) << "Expected a parameter value of 3.0."; EXPECT_CALL(testBus, OnAnimGraphFloatParameterChanged(m_animGraphInstance, m_parameterIndex, 3.0f, 4.0f)); // SetNamedParameterFloat/GetNamedParameterFloat() test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetNamedParameterFloat, m_parameterName.c_str(), 4.0f); Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetNamedParameterFloat, m_parameterName.c_str()); EXPECT_EQ(newValue, 4.0f) << "Expected a parameter value of 3.0."; // SetParameterFloat invalid index test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterFloat, 100, 3.0f); } TEST_F(AnimGraphComponentBusTests, BoolParameter) { AnimGraphComponentNotificationTestBus testBus(m_entityId); EXPECT_CALL(testBus, OnAnimGraphInstanceCreated(testing::_)); PrepareParameterTest(aznew BoolParameter()); EXPECT_CALL(testBus, OnAnimGraphBoolParameterChanged(m_animGraphInstance, m_parameterIndex, testing::_, true)); // SetParameterBool/GetParameterBool() test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterBool, m_parameterIndex, true); bool newValue = false; Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetParameterBool, m_parameterIndex); EXPECT_EQ(newValue, true) << "Expected true as parameter value."; EXPECT_CALL(testBus, OnAnimGraphBoolParameterChanged(m_animGraphInstance, m_parameterIndex, true, false)); // SetNamedParameterBool/GetNamedParameterBool() test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetNamedParameterBool, m_parameterName.c_str(), false); Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetNamedParameterBool, m_parameterName.c_str()); EXPECT_EQ(newValue, false) << "Expected false as parameter value."; // SetParameterBool invalid index test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterBool, 100, true); } TEST_F(AnimGraphComponentBusTests, StringParameter) { AnimGraphComponentNotificationTestBus testBus(m_entityId); EXPECT_CALL(testBus, OnAnimGraphInstanceCreated(testing::_)); PrepareParameterTest(aznew StringParameter()); EXPECT_CALL(testBus, OnAnimGraphStringParameterChanged(m_animGraphInstance, m_parameterIndex, testing::_, testing::_)); // SetParameterString/GetParameterString() test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterString, m_parameterIndex, "Test String"); AZStd::string newValue; Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetParameterString, m_parameterIndex); EXPECT_STREQ(newValue.c_str(), "Test String") << "Expected the test string parameter."; EXPECT_CALL(testBus, OnAnimGraphStringParameterChanged(m_animGraphInstance, m_parameterIndex, testing::_, testing::_)); // SetNamedParameterString/GetNamedParameterString() test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetNamedParameterString, m_parameterName.c_str(), "Yet Another String"); Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetNamedParameterString, m_parameterName.c_str()); EXPECT_STREQ(newValue.c_str(), "Yet Another String") << "Expected yet another string."; // SetParameterString invalid index test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterString, 100, "Test String"); } TEST_F(AnimGraphComponentBusTests, Vector2Parameter) { AnimGraphComponentNotificationTestBus testBus(m_entityId); EXPECT_CALL(testBus, OnAnimGraphInstanceCreated(testing::_)); PrepareParameterTest(aznew Vector2Parameter()); EXPECT_CALL(testBus, OnAnimGraphVector2ParameterChanged(m_animGraphInstance, m_parameterIndex, testing::_, AZ::Vector2(1.0f, 2.0f))); // SetParameterVector2/GetParameterVector2() test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterVector2, m_parameterIndex, AZ::Vector2(1.0f, 2.0f)); AZ::Vector2 newValue; Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetParameterVector2, m_parameterIndex); EXPECT_EQ(newValue, AZ::Vector2(1.0f, 2.0f)); EXPECT_CALL(testBus, OnAnimGraphVector2ParameterChanged(m_animGraphInstance, m_parameterIndex, AZ::Vector2(1.0f, 2.0f), AZ::Vector2(3.0f, 4.0f))); // SetNamedParameterVector2/GetNamedParameterVector2() test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetNamedParameterVector2, m_parameterName.c_str(), AZ::Vector2(3.0f, 4.0f)); Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetNamedParameterVector2, m_parameterName.c_str()); EXPECT_EQ(newValue, AZ::Vector2(3.0f, 4.0f)); // SetParameterVector2 invalid index test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterVector2, 100, AZ::Vector2(1.0f, 2.0f)); } TEST_F(AnimGraphComponentBusTests, Vector3Parameter) { AnimGraphComponentNotificationTestBus testBus(m_entityId); EXPECT_CALL(testBus, OnAnimGraphInstanceCreated(testing::_)); PrepareParameterTest(aznew Vector3Parameter()); EXPECT_CALL(testBus, OnAnimGraphVector3ParameterChanged(m_animGraphInstance, m_parameterIndex, testing::_, AZ::Vector3(1.0f, 2.0f, 3.0f))); // SetParameterVector3/GetParameterVector3() test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterVector3, m_parameterIndex, AZ::Vector3(1.0f, 2.0f, 3.0f)); AZ::Vector3 newValue; Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetParameterVector3, m_parameterIndex); EXPECT_EQ(newValue, AZ::Vector3(1.0f, 2.0f, 3.0f)); EXPECT_CALL(testBus, OnAnimGraphVector3ParameterChanged(m_animGraphInstance, m_parameterIndex, AZ::Vector3(1.0f, 2.0f, 3.0f), AZ::Vector3(4.0f, 5.0f, 6.0f))); // SetNamedParameterVector3/GetNamedParameterVector3() test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetNamedParameterVector3, m_parameterName.c_str(), AZ::Vector3(4.0f, 5.0f, 6.0f)); Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetNamedParameterVector3, m_parameterName.c_str()); EXPECT_EQ(newValue, AZ::Vector3(4.0f, 5.0f, 6.0f)); // SetParameterVector3 invalid index test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterVector3, 100, AZ::Vector3(1.0f, 2.0f, 3.0f)); } TEST_F(AnimGraphComponentBusTests, RotationParameterEuler) { AnimGraphComponentNotificationTestBus testBus(m_entityId); EXPECT_CALL(testBus, OnAnimGraphInstanceCreated(testing::_)); PrepareParameterTest(aznew RotationParameter()); EXPECT_CALL(testBus, OnAnimGraphRotationParameterChanged(m_animGraphInstance, m_parameterIndex, testing::_, testing::_)); // SetParameterRotationEuler/GetParameterRotationEuler() test AZ::Vector3 expectedEuler(AZ::DegToRad(30.0f), AZ::DegToRad(20.0f), 0.0f); Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterRotationEuler, m_parameterIndex, expectedEuler); AZ::Vector3 newValue; Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetParameterRotationEuler, m_parameterIndex); EXPECT_TRUE(newValue.IsClose(expectedEuler, 0.001f)); EXPECT_CALL(testBus, OnAnimGraphRotationParameterChanged(m_animGraphInstance, m_parameterIndex, testing::_, testing::_)); // SetNamedParameterRotationEuler/GetNamedParameterRotationEuler() test expectedEuler = AZ::Vector3(AZ::DegToRad(45.0f), 0.0f, AZ::DegToRad(30.0f)); Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetNamedParameterRotationEuler, m_parameterName.c_str(), expectedEuler); Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetNamedParameterRotationEuler, m_parameterName.c_str()); EXPECT_TRUE(newValue.IsClose(expectedEuler, 0.001f)); // SetParameterRotationEuler invalid index test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterRotationEuler, 100, expectedEuler); } TEST_F(AnimGraphComponentBusTests, RotationParameter) { AZ::Vector3 expected(AZ::DegToRad(30.0f), AZ::DegToRad(20.0f), 0.0f); AZ::Quaternion expectedQuat = MCore::AzEulerAnglesToAzQuat(expected); AnimGraphComponentNotificationTestBus testBus(m_entityId); EXPECT_CALL(testBus, OnAnimGraphInstanceCreated(testing::_)); PrepareParameterTest(aznew RotationParameter()); EXPECT_CALL(testBus, OnAnimGraphRotationParameterChanged(m_animGraphInstance, m_parameterIndex, testing::_, expectedQuat)); // SetParameterRotation/GetParameterRotation() test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterRotation, m_parameterIndex, expectedQuat); AZ::Quaternion newValue; Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetParameterRotation, m_parameterIndex); EXPECT_TRUE(newValue.IsClose(expectedQuat, 0.001f)); expected = AZ::Vector3(AZ::DegToRad(45.0f), 0.0f, AZ::DegToRad(30.0f)); expectedQuat = MCore::AzEulerAnglesToAzQuat(expected); EXPECT_CALL(testBus, OnAnimGraphRotationParameterChanged(m_animGraphInstance, m_parameterIndex, testing::_, expectedQuat)); // SetNamedParameterRotation/GetNamedParameterRotation() test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetNamedParameterRotation, m_parameterName.c_str(), expectedQuat); Integration::AnimGraphComponentRequestBus::EventResult(newValue, m_entityId, &Integration::AnimGraphComponentRequestBus::Events::GetNamedParameterRotation, m_parameterName.c_str()); EXPECT_TRUE(newValue.IsClose(expectedQuat, 0.001f)); // SetParameterRotation invalid index test Integration::AnimGraphComponentRequestBus::Event(m_entityId, &Integration::AnimGraphComponentRequestBus::Events::SetParameterRotation, 100, expectedQuat); } TEST_F(AnimGraphComponentBusTests, OnAnimGraphInstanceDestroyed) { AnimGraphComponentNotificationTestBus testBus(m_entityId); EXPECT_CALL(testBus, OnAnimGraphInstanceCreated(testing::_)); ActivateEntity(); EXPECT_CALL(testBus, OnAnimGraphInstanceDestroyed(m_animGraphInstance)); m_entity->Deactivate(); } } // end namespace EMotionFX