// Copyright (c) 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" /// /// Single node animation data container. /// struct NodeAnimationData { public: /// /// The target node name. /// String NodeName; /// /// The position channel animation. /// LinearCurve Position; /// /// The rotation channel animation. /// LinearCurve Rotation; /// /// The scale channel animation. /// LinearCurve Scale; public: /// /// Initializes a new instance of the class. /// NodeAnimationData() : Position(Float3::Zero) , Rotation(Quaternion::Identity) , Scale(Float3::One) { } public: /// /// Evaluates the animation transformation at the specified time (only for the curves with non-empty data). /// /// The time to evaluate the curves at. /// The interpolated value from the curve at provided time. /// If true the curve will loop when it goes past the end or beginning. Otherwise the curve value will be clamped. void Evaluate(float time, Transform* result, bool loop = true) const; /// /// Evaluates the animation transformation at the specified time. /// /// The time to evaluate the curves at. /// The interpolated value from the curve at provided time. /// If true the curve will loop when it goes past the end or beginning. Otherwise the curve value will be clamped. void EvaluateAll(float time, Transform* result, bool loop = true) const; /// /// Gets the total amount of keyframes in the animation curves. /// int32 GetKeyframesCount() const; uint64 GetMemoryUsage() const; }; /// /// Single track with events. /// struct EventAnimationData { float Duration = 0.0f; StringAnsi TypeName; StringAnsi JsonData; }; /// /// Root Motion modes that can be applied by the animation. Used as flags for selective behavior. /// 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); /// /// Skeleton nodes animation data container. Includes metadata about animation sampling, duration and node animations curves. /// struct AnimationData { /// /// The duration of the animation (in frames). /// double Duration = 0.0; /// /// The amount of the animation frames per second. /// double FramesPerSecond = 0.0; /// /// Enables root motion extraction support from this animation. /// AnimationRootMotionFlags RootMotionFlags = AnimationRootMotionFlags::None; /// /// The animation name. /// String Name; /// /// The custom node name to be used as a root motion source. If not specified the actual root node will be used. /// String RootNodeName; /// /// The per-skeleton node animation channels. /// Array Channels; /// /// The animation event tracks. /// Array>> Events; public: /// /// Gets the length of the animation (in seconds). /// FORCE_INLINE float GetLength() const { #if BUILD_DEBUG ASSERT(FramesPerSecond > ZeroTolerance); #endif return static_cast(Duration / FramesPerSecond); } uint64 GetMemoryUsage() const; /// /// Gets the total amount of keyframes in the all animation channels. /// int32 GetKeyframesCount() const; NodeAnimationData* GetChannel(const StringView& name); /// /// Swaps the contents of object with the other object without copy operation. Performs fast internal data exchange. /// /// The other object. void Swap(AnimationData& other); /// /// Releases data. /// void Release(); };