Add **Nested Animations** for compositing animation clips
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
||||
#include "Engine/Animations/CurveSerialization.h"
|
||||
#include "Engine/Animations/AnimEvent.h"
|
||||
#include "Engine/Animations/SceneAnimations/SceneAnimation.h"
|
||||
#include "Engine/Scripting/Scripting.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#include "Engine/Serialization/MemoryReadStream.h"
|
||||
@@ -64,7 +65,11 @@ Animation::InfoData Animation::GetInfo() const
|
||||
info.ChannelsCount = 0;
|
||||
info.KeyframesCount = 0;
|
||||
}
|
||||
info.MemoryUsage += Events.Capacity() * sizeof(Pair<String, StepCurve<AnimEventData>>);
|
||||
info.MemoryUsage += NestedAnims.Capacity() * sizeof(Pair<String, NestedAnimData>);
|
||||
info.MemoryUsage += MappingCache.Capacity() * (sizeof(void*) + sizeof(NodeToChannel) + 1);
|
||||
for (auto& e : Events)
|
||||
info.MemoryUsage += e.Second.GetKeyframes().Capacity() * sizeof(StepCurve<AnimEventData>);
|
||||
for (auto& e : MappingCache)
|
||||
info.MemoryUsage += e.Value.Capacity() * sizeof(int32);
|
||||
return info;
|
||||
@@ -145,7 +150,7 @@ void Animation::LoadTimeline(BytesContainer& result) const
|
||||
const float fpsInv = 1.0f / fps;
|
||||
stream.WriteFloat(fps);
|
||||
stream.WriteInt32((int32)Data.Duration);
|
||||
int32 tracksCount = Data.Channels.Count() + Events.Count();
|
||||
int32 tracksCount = Data.Channels.Count() + NestedAnims.Count() + Events.Count();
|
||||
for (auto& channel : Data.Channels)
|
||||
tracksCount +=
|
||||
(channel.Position.GetKeyframes().HasItems() ? 1 : 0) +
|
||||
@@ -232,6 +237,29 @@ void Animation::LoadTimeline(BytesContainer& result) const
|
||||
trackIndex++;
|
||||
}
|
||||
}
|
||||
for (auto& e : NestedAnims)
|
||||
{
|
||||
auto& nestedAnim = e.Second;
|
||||
byte flags = 0;
|
||||
if (!nestedAnim.Enabled)
|
||||
flags |= (byte)SceneAnimation::Track::Flags::Mute;
|
||||
if (nestedAnim.Loop)
|
||||
flags |= (byte)SceneAnimation::Track::Flags::Loop;
|
||||
Guid id = nestedAnim.Anim.GetID();
|
||||
|
||||
// Nested Animation track
|
||||
stream.WriteByte(20); // Track Type
|
||||
stream.WriteByte(flags); // Track Flags
|
||||
stream.WriteInt32(-1); // Parent Index
|
||||
stream.WriteInt32(0); // Children Count
|
||||
stream.WriteString(e.First, -13); // Name
|
||||
stream.Write(&Color32::White); // Color
|
||||
stream.Write(&id);
|
||||
stream.WriteFloat(nestedAnim.Time);
|
||||
stream.WriteFloat(nestedAnim.Duration);
|
||||
stream.WriteFloat(nestedAnim.Speed);
|
||||
stream.WriteFloat(nestedAnim.StartTime);
|
||||
}
|
||||
for (auto& e : Events)
|
||||
{
|
||||
// Animation Event track
|
||||
@@ -290,6 +318,7 @@ bool Animation::SaveTimeline(BytesContainer& data)
|
||||
// Tracks
|
||||
Data.Channels.Clear();
|
||||
Events.Clear();
|
||||
NestedAnims.Clear();
|
||||
Dictionary<int32, int32> animationChannelTrackIndexToChannelIndex;
|
||||
animationChannelTrackIndexToChannelIndex.EnsureCapacity(tracksCount * 3);
|
||||
for (int32 trackIndex = 0; trackIndex < tracksCount; trackIndex++)
|
||||
@@ -392,6 +421,23 @@ bool Animation::SaveTimeline(BytesContainer& data)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 20:
|
||||
{
|
||||
// Nested Animation
|
||||
auto& nestedTrack = NestedAnims.AddOne();
|
||||
nestedTrack.First = name;
|
||||
auto& nestedAnim = nestedTrack.Second;
|
||||
Guid id;
|
||||
stream.Read(&id);
|
||||
stream.ReadFloat(&nestedAnim.Time);
|
||||
stream.ReadFloat(&nestedAnim.Duration);
|
||||
stream.ReadFloat(&nestedAnim.Speed);
|
||||
stream.ReadFloat(&nestedAnim.StartTime);
|
||||
nestedAnim.Anim = id;
|
||||
nestedAnim.Enabled = (trackFlags & (byte)SceneAnimation::Track::Flags::Mute) == 0;
|
||||
nestedAnim.Loop = (trackFlags & (byte)SceneAnimation::Track::Flags::Loop) != 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG(Error, "Unsupported track type {0} for animation.", trackType);
|
||||
return true;
|
||||
@@ -431,7 +477,7 @@ bool Animation::Save(const StringView& path)
|
||||
MemoryWriteStream stream(4096);
|
||||
|
||||
// Info
|
||||
stream.WriteInt32(101);
|
||||
stream.WriteInt32(102);
|
||||
stream.WriteDouble(Data.Duration);
|
||||
stream.WriteDouble(Data.FramesPerSecond);
|
||||
stream.WriteBool(Data.EnableRootMotion);
|
||||
@@ -464,6 +510,27 @@ bool Animation::Save(const StringView& path)
|
||||
}
|
||||
}
|
||||
|
||||
// Nested animations
|
||||
stream.WriteInt32(NestedAnims.Count());
|
||||
for (int32 i = 0; i < NestedAnims.Count(); i++)
|
||||
{
|
||||
auto& e = NestedAnims[i];
|
||||
stream.WriteString(e.First, 172);
|
||||
auto& nestedAnim = e.Second;
|
||||
Guid id = nestedAnim.Anim.GetID();
|
||||
byte flags = 0;
|
||||
if (nestedAnim.Enabled)
|
||||
flags |= 1;
|
||||
if (nestedAnim.Loop)
|
||||
flags |= 2;
|
||||
stream.WriteByte(flags);
|
||||
stream.Write(&id);
|
||||
stream.WriteFloat(nestedAnim.Time);
|
||||
stream.WriteFloat(nestedAnim.Duration);
|
||||
stream.WriteFloat(nestedAnim.Speed);
|
||||
stream.WriteFloat(nestedAnim.StartTime);
|
||||
}
|
||||
|
||||
// Set data to the chunk asset
|
||||
auto chunk0 = GetOrCreateChunk(0);
|
||||
ASSERT(chunk0 != nullptr);
|
||||
@@ -534,6 +601,7 @@ Asset::LoadResult Animation::load()
|
||||
{
|
||||
case 100:
|
||||
case 101:
|
||||
case 102:
|
||||
{
|
||||
stream.ReadInt32(&headerVersion);
|
||||
stream.ReadDouble(&Data.Duration);
|
||||
@@ -616,6 +684,31 @@ Asset::LoadResult Animation::load()
|
||||
}
|
||||
}
|
||||
|
||||
// Nested animations
|
||||
if (headerVersion >= 102)
|
||||
{
|
||||
int32 nestedAnimationsCount;
|
||||
stream.ReadInt32(&nestedAnimationsCount);
|
||||
NestedAnims.Resize(nestedAnimationsCount, false);
|
||||
for (int32 i = 0; i < nestedAnimationsCount; i++)
|
||||
{
|
||||
auto& e = NestedAnims[i];
|
||||
stream.ReadString(&e.First, 172);
|
||||
auto& nestedAnim = e.Second;
|
||||
byte flags;
|
||||
stream.ReadByte(&flags);
|
||||
nestedAnim.Enabled = flags & 1;
|
||||
nestedAnim.Loop = flags & 2;
|
||||
Guid id;
|
||||
stream.Read(&id);
|
||||
nestedAnim.Anim = id;
|
||||
stream.ReadFloat(&nestedAnim.Time);
|
||||
stream.ReadFloat(&nestedAnim.Duration);
|
||||
stream.ReadFloat(&nestedAnim.Speed);
|
||||
stream.ReadFloat(&nestedAnim.StartTime);
|
||||
}
|
||||
}
|
||||
|
||||
return LoadResult::Ok;
|
||||
}
|
||||
|
||||
@@ -639,6 +732,7 @@ void Animation::unload(bool isReloading)
|
||||
}
|
||||
}
|
||||
Events.Clear();
|
||||
NestedAnims.Clear();
|
||||
}
|
||||
|
||||
AssetChunksFlag Animation::getChunksToPreload() const
|
||||
|
||||
Reference in New Issue
Block a user