/* * 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. * */ #pragma once #include "SystemComponentFixture.h" #include <EMotionFX/Source/MotionSet.h> #include <AzCore/Debug/TraceMessageBus.h> #include <AzCore/Outcome/Outcome.h> #include <AzCore/std/smart_ptr/unique_ptr.h> #include <AzCore/std/string/string.h> #include <MCore/Source/Attribute.h> #include <Tests/TestAssetCode/AnimGraphFactory.h> namespace EMotionFX { class Actor; class ActorInstance; class AnimGraph; class AnimGraphStateMachine; class AnimGraphStateTransition; class AnimGraphInstance; class AnimGraphTimeCondition; class Transform; class AnimGraphFixture : public SystemComponentFixture , public AZ::Debug::TraceMessageBus::Handler { public: void SetUp() override; void TearDown() override; // Derived classes should override and construct the rest of the graph at this point. // They should call this base ConstructGraph to get the anim graph and root state machine created. virtual void ConstructGraph(); virtual void ConstructActor(); AZStd::string SerializeAnimGraph() const; // Evaluates the graph void Evaluate(); const Transform& GetOutputTransform(uint32 nodeIndex = 0); void AddValueParameter(const AZ::TypeId& typeId, const AZStd::string& name); template <class ParamType, class InputType> void ParamSetValue(const AZStd::string& paramName, const InputType& value) { const AZ::Outcome<size_t> parameterIndex = m_animGraphInstance->FindParameterIndex(paramName); const AZ::u32 paramIndex = static_cast<AZ::u32>(parameterIndex.GetValue()); MCore::Attribute* param = m_animGraphInstance->GetParameterValue(paramIndex); ParamType* typeParam = static_cast<ParamType*>(param); typeParam->SetValue(value); } // Helper functions for state machine construction (Works on m_rootStateMachine). AnimGraphStateTransition* AddTransition(AnimGraphNode* source, AnimGraphNode* target, float time); AnimGraphTimeCondition* AddTimeCondition(AnimGraphStateTransition* transition, float countDownTime); AnimGraphStateTransition* AddTransitionWithTimeCondition(AnimGraphNode* source, AnimGraphNode* target, float blendTime, float countDownTime); // Helper function for motion set construction (Works on m_motionSet). MotionSet::MotionEntry* AddMotionEntry(const AZStd::string& motionId, float motionMaxTime); // TraceMessageBus - Intercepting to prevent dialog popup in AnimGraphReferenceNodeWithNoContentsTest. virtual bool OnError(const char* /*window*/, const char* /*message*/) override { return true; } using SimulateFrameCallback = std::function<void(AnimGraphInstance*, /*time*/ float, /*timeDelta*/ float, /*frame*/ int)>; using SimulateCallback = std::function<void(AnimGraphInstance*)>; /** * Simulation helper with callbacks before and after starting the simulation as well as * callbakcs before and after the anim graph update. * Example: expectedFps = 60, fpsVariance = 10 -> actual framerate = [55, 65] * @param[in] simulationTime Simulation time in seconds. * @param[in] expectedFps is the targeted frame rate * @param[in] fpsVariance is the range in which the instabilities happen. */ void Simulate(float simulationTime, float expectedFps, float fpsVariance, SimulateCallback preCallback, SimulateCallback postCallback, SimulateFrameCallback preUpdateCallback, SimulateFrameCallback postUpdateCallback); protected: AZStd::unique_ptr<Actor> m_actor; ActorInstance* m_actorInstance = nullptr; AZStd::unique_ptr<AnimGraph> m_animGraph; AnimGraphStateMachine* m_rootStateMachine = nullptr; AnimGraphInstance* m_animGraphInstance = nullptr; MotionSet* m_motionSet = nullptr; }; }