175 lines
5.2 KiB
C++
175 lines
5.2 KiB
C++
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "Engine/Core/Types/String.h"
|
|
#include "Engine/Core/Types/Pair.h"
|
|
#include "Engine/Core/Math/Transform.h"
|
|
#include "Engine/Animations/Curve.h"
|
|
|
|
/// <summary>
|
|
/// Single node animation data container.
|
|
/// </summary>
|
|
struct NodeAnimationData
|
|
{
|
|
public:
|
|
/// <summary>
|
|
/// The target node name.
|
|
/// </summary>
|
|
String NodeName;
|
|
|
|
/// <summary>
|
|
/// The position channel animation.
|
|
/// </summary>
|
|
LinearCurve<Float3> Position;
|
|
|
|
/// <summary>
|
|
/// The rotation channel animation.
|
|
/// </summary>
|
|
LinearCurve<Quaternion> Rotation;
|
|
|
|
/// <summary>
|
|
/// The scale channel animation.
|
|
/// </summary>
|
|
LinearCurve<Float3> Scale;
|
|
|
|
public:
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="NodeAnimationData"/> class.
|
|
/// </summary>
|
|
NodeAnimationData()
|
|
: Position(Float3::Zero)
|
|
, Rotation(Quaternion::Identity)
|
|
, Scale(Float3::One)
|
|
{
|
|
}
|
|
|
|
public:
|
|
/// <summary>
|
|
/// Evaluates the animation transformation at the specified time (only for the curves with non-empty data).
|
|
/// </summary>
|
|
/// <param name="time">The time to evaluate the curves at.</param>
|
|
/// <param name="result">The interpolated value from the curve at provided time.</param>
|
|
/// <param name="loop">If true the curve will loop when it goes past the end or beginning. Otherwise the curve value will be clamped.</param>
|
|
void Evaluate(float time, Transform* result, bool loop = true) const;
|
|
|
|
/// <summary>
|
|
/// Evaluates the animation transformation at the specified time.
|
|
/// </summary>
|
|
/// <param name="time">The time to evaluate the curves at.</param>
|
|
/// <param name="result">The interpolated value from the curve at provided time.</param>
|
|
/// <param name="loop">If true the curve will loop when it goes past the end or beginning. Otherwise the curve value will be clamped.</param>
|
|
void EvaluateAll(float time, Transform* result, bool loop = true) const;
|
|
|
|
/// <summary>
|
|
/// Gets the total amount of keyframes in the animation curves.
|
|
/// </summary>
|
|
int32 GetKeyframesCount() const;
|
|
|
|
uint64 GetMemoryUsage() const;
|
|
};
|
|
|
|
/// <summary>
|
|
/// Single track with events.
|
|
/// </summary>
|
|
struct EventAnimationData
|
|
{
|
|
float Duration = 0.0f;
|
|
StringAnsi TypeName;
|
|
StringAnsi JsonData;
|
|
};
|
|
|
|
/// <summary>
|
|
/// Root Motion modes that can be applied by the animation. Used as flags for selective behavior.
|
|
/// </summary>
|
|
API_ENUM(Attributes="Flags") enum class AnimationRootMotionFlags : byte
|
|
{
|
|
// No root motion.
|
|
None = 0,
|
|
// Root node position along XZ plane. Applies horizontal movement. Good for stationary animations (eg. idle).
|
|
RootPositionXZ = 1 << 0,
|
|
// Root node position along Y axis (up). Applies vertical movement. Good for all 'grounded' animations unless jumping is handled from code.
|
|
RootPositionY = 1 << 1,
|
|
// Root node rotation. Applies orientation changes. Good for animations that have baked-in root rotation (eg. turn animations).
|
|
RootRotation = 1 << 2,
|
|
// Root node position.
|
|
RootPosition = RootPositionXZ | RootPositionY,
|
|
// Root node position and rotation.
|
|
RootTransform = RootPosition | RootRotation,
|
|
};
|
|
|
|
DECLARE_ENUM_OPERATORS(AnimationRootMotionFlags);
|
|
|
|
/// <summary>
|
|
/// Skeleton nodes animation data container. Includes metadata about animation sampling, duration and node animations curves.
|
|
/// </summary>
|
|
struct AnimationData
|
|
{
|
|
/// <summary>
|
|
/// The duration of the animation (in frames).
|
|
/// </summary>
|
|
double Duration = 0.0;
|
|
|
|
/// <summary>
|
|
/// The amount of the animation frames per second.
|
|
/// </summary>
|
|
double FramesPerSecond = 0.0;
|
|
|
|
/// <summary>
|
|
/// Enables root motion extraction support from this animation.
|
|
/// </summary>
|
|
AnimationRootMotionFlags RootMotionFlags = AnimationRootMotionFlags::None;
|
|
|
|
/// <summary>
|
|
/// The animation name.
|
|
/// </summary>
|
|
String Name;
|
|
|
|
/// <summary>
|
|
/// The custom node name to be used as a root motion source. If not specified the actual root node will be used.
|
|
/// </summary>
|
|
String RootNodeName;
|
|
|
|
/// <summary>
|
|
/// The per-skeleton node animation channels.
|
|
/// </summary>
|
|
Array<NodeAnimationData> Channels;
|
|
|
|
/// <summary>
|
|
/// The animation event tracks.
|
|
/// </summary>
|
|
Array<Pair<String, StepCurve<EventAnimationData>>> Events;
|
|
|
|
public:
|
|
/// <summary>
|
|
/// Gets the length of the animation (in seconds).
|
|
/// </summary>
|
|
FORCE_INLINE float GetLength() const
|
|
{
|
|
#if BUILD_DEBUG
|
|
ASSERT(FramesPerSecond > ZeroTolerance);
|
|
#endif
|
|
return static_cast<float>(Duration / FramesPerSecond);
|
|
}
|
|
|
|
uint64 GetMemoryUsage() const;
|
|
|
|
/// <summary>
|
|
/// Gets the total amount of keyframes in the all animation channels.
|
|
/// </summary>
|
|
int32 GetKeyframesCount() const;
|
|
|
|
NodeAnimationData* GetChannel(const StringView& name);
|
|
|
|
/// <summary>
|
|
/// Swaps the contents of object with the other object without copy operation. Performs fast internal data exchange.
|
|
/// </summary>
|
|
/// <param name="other">The other object.</param>
|
|
void Swap(AnimationData& other);
|
|
|
|
/// <summary>
|
|
/// Releases data.
|
|
/// </summary>
|
|
void Release();
|
|
};
|