You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Gems/MotionMatching/Code/Source/MotionMatchingInstance.h

122 lines
5.1 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
*
*/
#pragma once
#include <AzCore/Math/Vector3.h>
#include <AzCore/Memory/Memory.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <EMotionFX/Source/EMotionFXConfig.h>
#include <Feature.h>
#include <TrajectoryHistory.h>
#include <TrajectoryQuery.h>
#include <MotionMatching/MotionMatchingBus.h>
namespace AZ
{
class ReflectContext;
}
namespace EMotionFX
{
class ActorInstance;
class Motion;
}
namespace EMotionFX::MotionMatching
{
class MotionMatchingData;
//! The instance is where everything comes together. It stores the trajectory history, the trajectory query along with the query vector, knows about the
//! last lowest cost frame frame index and stores the time of the animation that the instance is currently playing. It is responsible for motion extraction,
//! blending towards a new frame in the motion capture database in case the algorithm found a better matching frame and executes the actual search.
class EMFX_API MotionMatchingInstance
: public DebugDrawRequestBus::Handler
{
public:
AZ_RTTI(MotionMatchingInstance, "{1ED03AD8-0FB2-431B-AF01-02F7E930EB73}")
AZ_CLASS_ALLOCATOR_DECL
MotionMatchingInstance() = default;
virtual ~MotionMatchingInstance();
struct EMFX_API InitSettings
{
ActorInstance* m_actorInstance = nullptr;
MotionMatchingData* m_data = nullptr;
};
void Init(const InitSettings& settings);
// DebugDrawRequestBus::Handler overrides
void DebugDraw(AzFramework::DebugDisplayRequests& debugDisplay) override;
void Update(float timePassedInSeconds, const AZ::Vector3& targetPos, const AZ::Vector3& targetFacingDir, TrajectoryQuery::EMode mode, float pathRadius, float pathSpeed);
void PostUpdate(float timeDelta);
void Output(Pose& outputPose);
MotionInstance* GetMotionInstance() const { return m_motionInstance; }
ActorInstance* GetActorInstance() const { return m_actorInstance; }
MotionMatchingData* GetData() const { return m_data; }
size_t GetLowestCostFrameIndex() const { return m_lowestCostFrameIndex; }
void SetLowestCostSearchFrequency(float frequency) { m_lowestCostSearchFrequency = frequency; }
float GetNewMotionTime() const { return m_newMotionTime; }
//! Get the cached trajectory feature.
//! The trajectory feature is searched in the feature schema used in the current instance at init time.
FeatureTrajectory* GetTrajectoryFeature() const { return m_cachedTrajectoryFeature; }
const TrajectoryQuery& GetTrajectoryQuery() const { return m_trajectoryQuery; }
const TrajectoryHistory& GetTrajectoryHistory() const { return m_trajectoryHistory; }
const Transform& GetMotionExtractionDelta() const { return m_motionExtractionDelta; }
private:
MotionInstance* CreateMotionInstance() const;
void SamplePose(MotionInstance* motionInstance, Pose& outputPose);
void SamplePose(Motion* motion, Pose& outputPose, float sampleTime) const;
size_t FindLowestCostFrameIndex(const Feature::FrameCostContext& context);
MotionMatchingData* m_data = nullptr;
ActorInstance* m_actorInstance = nullptr;
Pose m_blendSourcePose;
Pose m_blendTargetPose;
Pose m_queryPose; //! Input query pose for the motion matching search.
MotionInstance* m_motionInstance = nullptr;
MotionInstance* m_prevMotionInstance = nullptr;
Transform m_motionExtractionDelta = Transform::CreateIdentity();
/// Buffers used for the broad-phase KD-tree search.
AZStd::vector<float> m_queryFeatureValues; //< The input query features to be compared to every entry/row in the feature matrix with the motion matching search.
AZStd::vector<size_t> m_nearestFrames; //< Stores the nearest matching frames / search result from the KD-tree.
FeatureTrajectory* m_cachedTrajectoryFeature = nullptr; //< Cached pointer to the trajectory feature in the feature schema.
TrajectoryQuery m_trajectoryQuery;
TrajectoryHistory m_trajectoryHistory;
static constexpr float m_trajectorySecsToTrack = 5.0f;
float m_timeSinceLastFrameSwitch = 0.0f;
float m_newMotionTime = 0.0f;
size_t m_lowestCostFrameIndex = InvalidIndex;
float m_lowestCostSearchFrequency = 5.0f; //< How often the lowest cost frame shall be searched per second.
bool m_blending = false;
float m_blendWeight = 1.0f;
float m_blendProgressTime = 0.0f; //< How long are we already blending? In seconds.
/// Buffers used for FindLowestCostFrameIndex().
AZStd::vector<float> m_tempCosts;
AZStd::vector<float> m_minCosts;
AZStd::vector<AzFramework::DebugDisplayRequests*> m_debugDisplays;
};
} // namespace EMotionFX::MotionMatching