// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "../BinaryAsset.h"
#include "Engine/Core/Collections/Dictionary.h"
#include "Engine/Animations/AnimationData.h"
class SkinnedModel;
///
/// Asset that contains an animation spline represented by a set of keyframes, each representing an endpoint of a linear curve.
///
API_CLASS(NoSpawn) class FLAXENGINE_API Animation : public BinaryAsset
{
DECLARE_BINARY_ASSET_HEADER(Animation, 1);
public:
///
/// Contains basic information about the animation asset contents.
///
API_STRUCT() struct InfoData
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(InfoData);
///
/// Length of the animation in seconds.
///
API_FIELD() float Length;
///
/// Amount of animation frames (some curve tracks may use less keyframes).
///
API_FIELD() int32 FramesCount;
///
/// Amount of animation channel tracks.
///
API_FIELD() int32 ChannelsCount;
///
/// The total amount of keyframes in the animation tracks.
///
API_FIELD() int32 KeyframesCount;
};
public:
///
/// The animation data.
///
AnimationData Data;
///
/// Contains the mapping for every skeleton node to the animation data channels.
/// Can be used for a simple lookup or to check if a given node is animated (unused nodes are using -1 index).
///
typedef Array NodeToChannel;
///
/// The skeleton nodes to animation channel indices mapping cache. Use it as read-only. It's being maintained internally by the asset.
///
Dictionary MappingCache;
public:
///
/// Gets the length of the animation (in seconds).
///
/// The length in seconds.
API_PROPERTY() float GetLength() const
{
return IsLoaded() ? Data.GetLength() : 0.0f;
}
///
/// Gets the duration of the animation (in frames).
///
/// The duration in frames.
API_PROPERTY() float GetDuration() const
{
return (float)Data.Duration;
}
///
/// Gets the amount of the animation frames per second.
///
/// The frames per second.
API_PROPERTY() float GetFramesPerSecond() const
{
return (float)Data.FramesPerSecond;
}
///
/// Gets the animation clip info.
///
/// The animation info.
API_PROPERTY() InfoData GetInfo() const;
///
/// Clears the skeleton mapping cache.
///
void ClearCache();
///
/// Clears the skeleton mapping cache.
///
/// The target skinned model to get mapping to its skeleton.
/// The cached node-to-channel mapping for the fast animation sampling for the skinned model skeleton nodes.
const NodeToChannel* GetMapping(SkinnedModel* obj);
#if USE_EDITOR
///
/// Gets the animation as serialized timeline data. Used to show it in Editor.
///
/// The output timeline data container. Empty if failed to load.
API_FUNCTION() void LoadTimeline(API_PARAM(Out) BytesContainer& result) const;
///
/// Saves the serialized timeline data to the asset as animation.
///
/// The cannot be used by virtual assets.
/// The timeline data container.
/// true failed to save data; otherwise, false.
API_FUNCTION() bool SaveTimeline(BytesContainer& data);
///
/// Saves the animation data to the asset. Supported only in Editor.
///
/// The cannot be used by virtual assets.
/// true failed to save data; otherwise, false.
bool Save(const StringView& path = StringView::Empty);
#endif
private:
void OnSkinnedModelUnloaded(Asset* obj);
protected:
// [BinaryAsset]
LoadResult load() override;
void unload(bool isReloading) override;
AssetChunksFlag getChunksToPreload() const override;
};