// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#include "../BinaryAsset.h"
#include "Engine/Core/Collections/Dictionary.h"
#include "Engine/Animations/AnimationData.h"
#include "Engine/Content/AssetReference.h"
class SkinnedModel;
class AnimEvent;
///
/// 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);
///
/// Contains basic information about the animation asset contents.
///
API_STRUCT() struct FLAXENGINE_API 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;
///
/// The estimated memory usage (in bytes) of the animation (all tracks and keyframes size in memory).
///
API_FIELD() int32 MemoryUsage;
};
///
/// Contains instance.
///
struct FLAXENGINE_API AnimEventData
{
float Duration = 0.0f;
AnimEvent* Instance = nullptr;
#if USE_EDITOR
StringAnsi TypeName;
#endif
};
///
/// Contains instance.
///
struct FLAXENGINE_API NestedAnimData
{
float Time = 0.0f;
float Duration = 0.0f;
float Speed = 1.0f;
float StartTime = 0.0f;
bool Enabled = false;
bool Loop = false;
AssetReference Anim;
};
private:
#if USE_EDITOR
bool _registeredForScriptingReload = false;
void OnScriptsReloadStart();
#endif
public:
///
/// The animation data.
///
AnimationData Data;
///
/// The animation events (keyframes per named track).
///
Array>> Events;
///
/// The nested animations (animation per named track).
///
Array> NestedAnims;
public:
///
/// Gets the length of the animation (in seconds).
///
API_PROPERTY() float GetLength() const
{
return IsLoaded() ? Data.GetLength() : 0.0f;
}
///
/// Gets the duration of the animation (in frames).
///
API_PROPERTY() float GetDuration() const
{
return (float)Data.Duration;
}
///
/// Gets the amount of the animation frames per second.
///
API_PROPERTY() float GetFramesPerSecond() const
{
return (float)Data.FramesPerSecond;
}
///
/// Gets the animation clip info.
///
API_PROPERTY() InfoData GetInfo() const;
#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
public:
// [BinaryAsset]
uint64 GetMemoryUsage() const override;
void OnScriptingDispose() override;
protected:
// [BinaryAsset]
LoadResult load() override;
void unload(bool isReloading) override;
AssetChunksFlag getChunksToPreload() const override;
};