// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Content/BinaryAsset.h" #include "Engine/Content/AssetReference.h" #include "Engine/Core/Math/Color32.h" #include "Engine/Animations/Curve.h" #include "Engine/Serialization/MemoryWriteStream.h" /// /// Scene animation timeline for animating objects and playing cut-scenes. /// API_CLASS(NoSpawn) class FLAXENGINE_API SceneAnimation final : public BinaryAsset { DECLARE_BINARY_ASSET_HEADER(SceneAnimation, 1); public: /// /// The animation timeline track data. /// struct Track { enum class Types { //Emitter = 0, Folder = 1, PostProcessMaterial = 2, NestedSceneAnimation = 3, ScreenFade = 4, Audio = 5, AudioVolume = 6, Actor = 7, Script = 8, KeyframesProperty = 9, CurveProperty = 10, StringProperty = 11, ObjectReferenceProperty = 12, StructProperty = 13, ObjectProperty = 14, Event = 15, CameraCut = 16, //AnimationChannel = 17, //AnimationChannelData = 18, //AnimationEvent = 19, }; enum class Flags { None = 0, Mute = 1, Loop = 2, PrefabObject = 4, }; /// /// The type of the track. /// Types Type; /// /// The flags of the track. /// Flags Flag; /// /// The parent track index or -1 for root tracks. /// int32 ParentIndex; /// /// The amount of child tracks (stored in the sequence after this track). /// int32 ChildrenCount; /// /// The name of the track. /// String Name; /// /// True if track is disabled, otherwise false (cached on load based on the flags and parent flags). /// bool Disabled; /// /// The track color. /// Color32 Color; /// /// The referenced asset. /// AssetReference Asset; /// /// The track state index. /// int32 TrackStateIndex; /// /// The track data (from the asset storage). /// void* Data; /// /// The track dependent data (from the shared runtime allocation). /// void* RuntimeData; Track() { } template FORCE_INLINE const T* GetData() const { return static_cast(Data); } template FORCE_INLINE T* GetRuntimeData() { return static_cast(RuntimeData); } template FORCE_INLINE const T* GetRuntimeData() const { return static_cast(RuntimeData); } }; struct Media { int32 StartFrame; int32 DurationFrames; }; struct PostProcessMaterialTrack { struct Data { Guid AssetID; }; struct Runtime { int32 Count; Media* Media; }; }; struct NestedSceneAnimationTrack { struct Data { Guid AssetID; int32 StartFrame; int32 DurationFrames; }; struct Runtime { }; }; struct ScreenFadeTrack { struct GradientStop { int32 Frame; Color Value; }; struct Data { int32 StartFrame; int32 DurationFrames; int32 GradientStopsCount; }; struct Runtime { GradientStop* GradientStops; }; }; struct AudioTrack { struct Media { int32 StartFrame; int32 DurationFrames; float Offset; }; struct Data { Guid AssetID; }; struct Runtime { int32 VolumeTrackIndex; int32 Count; Media* Media; }; }; struct AudioVolumeTrack { typedef CurveBase> CurveType; struct Data { int32 KeyframesCount; }; struct Runtime { int32 KeyframesCount; BezierCurveKeyframe* Keyframes; }; }; struct ObjectTrack { struct Data { Guid ID; }; struct Runtime { }; }; struct ActorTrack : ObjectTrack { struct Data : ObjectTrack::Data { }; struct Runtime : ObjectTrack::Runtime { }; }; struct ScriptTrack : ObjectTrack { struct Data : ObjectTrack::Data { }; struct Runtime : ObjectTrack::Runtime { }; }; struct PropertyTrack { struct Data { int32 ValueSize; int32 PropertyNameLength; int32 PropertyTypeNameLength; }; struct Runtime { int32 ValueSize; char* PropertyName; char* PropertyTypeName; }; }; struct KeyframesPropertyTrack : PropertyTrack { struct Data : PropertyTrack::Data { int32 KeyframesCount; }; struct Runtime : PropertyTrack::Runtime { int32 KeyframesCount; /// /// The keyframes array (items count is KeyframesCount). Each keyframe is represented by pair of time (of type float) and the value data (of size ValueSize). /// void* Keyframes; int32 KeyframesSize; }; }; struct CurvePropertyTrack : PropertyTrack { enum class DataTypes { Unknown, Float, Double, Float2, Float3, Float4, Double2, Double3, Double4, Quaternion, Color, Color32, }; struct Data : PropertyTrack::Data { int32 KeyframesCount; }; struct Runtime : PropertyTrack::Runtime { DataTypes DataType; DataTypes ValueType; int32 KeyframesCount; /// /// The keyframes array (items count is KeyframesCount). Each keyframe is represented by: time (of type float), value data (of size ValueSize) and two values for bezier tangents. /// void* Keyframes; }; }; struct StringPropertyTrack : PropertyTrack { struct Data : PropertyTrack::Data { int32 KeyframesCount; }; struct Runtime : PropertyTrack::Runtime { int32 KeyframesCount; // ..followed by the keyframes times and the values arrays (separate) }; }; typedef KeyframesPropertyTrack ObjectReferencePropertyTrack; typedef PropertyTrack StructPropertyTrack; typedef PropertyTrack ObjectPropertyTrack; struct EventTrack { enum { MaxParams = 8, }; struct Data { }; struct Runtime { /// /// The total amount of the event parameters. /// int32 EventParamsCount; /// /// The event invocations count. /// int32 EventsCount; /// /// The total size of the event parameters data in bytes). /// int32 EventParamsSize; /// /// The name of the event (just a member name). /// char* EventName; /// /// The name of the event parameter type (per parameter). /// char* EventParamTypes[MaxParams]; /// /// The size (in bytes) of the event parameter type data (per parameter). /// int32 EventParamSizes[MaxParams]; /// /// The events data begin. /// const byte* DataBegin; }; }; struct CameraCutTrack : ObjectTrack { struct Data : ObjectTrack::Data { }; struct Runtime : ObjectTrack::Runtime { int32 Count; Media* Media; }; }; private: BytesContainer _data; MemoryWriteStream _runtimeData; public: /// /// The frames amount per second of the timeline animation. /// API_FIELD(ReadOnly) float FramesPerSecond; /// /// The animation duration (in frames). /// API_FIELD(ReadOnly) int32 DurationFrames; /// /// The tracks on the system timeline. /// Array Tracks; /// /// The amount of per-track state information required to allocate for this animation (including nested tracks). /// int32 TrackStatesCount; public: /// /// Gets the animation duration (in seconds). /// API_PROPERTY() float GetDuration() const; public: /// /// Gets the serialized timeline data. /// /// The output timeline data container. Empty if failed to load. API_FUNCTION() const BytesContainer& LoadTimeline(); #if USE_EDITOR /// /// Saves the serialized timeline data to the asset. /// /// It cannot be used by virtual assets. /// The timeline data container. /// true failed to save data; otherwise, false. API_FUNCTION() bool SaveTimeline(const BytesContainer& data); #endif public: // [BinaryAsset] #if USE_EDITOR void GetReferences(Array& output) const override; #endif protected: // [SceneAnimationBase] LoadResult load() override; void unload(bool isReloading) override; AssetChunksFlag getChunksToPreload() const override; }; DECLARE_ENUM_OPERATORS(SceneAnimation::Track::Flags);