diff --git a/Source/Engine/Animations/Curve.h b/Source/Engine/Animations/Curve.h index 24dcd87a8..be5c268ef 100644 --- a/Source/Engine/Animations/Curve.h +++ b/Source/Engine/Animations/Curve.h @@ -4,9 +4,7 @@ #include "AnimationUtils.h" #include "Engine/Core/Collections/Array.h" -#include "Engine/Core/Types/DataContainer.h" -#include "Engine/Serialization/ReadStream.h" -#include "Engine/Serialization/WriteStream.h" +#include "Engine/Core/Types/Span.h" // @formatter:off @@ -289,7 +287,7 @@ class CurveBase { public: - typedef DataContainer KeyFrameData; + typedef Span KeyFrameData; protected: @@ -641,7 +639,7 @@ public: /// If true the curve will loop when it goes past the end or beginning. Otherwise the curve value will be clamped. void Evaluate(T& result, float time, bool loop = true) const { - typename Base::KeyFrameData data(_keyframes); + typename Base::KeyFrameData data(_keyframes.Get(), _keyframes.Count()); Base::Evaluate(data, result, time, loop); } @@ -653,7 +651,7 @@ public: /// If true the curve will loop when it goes past the end or beginning. Otherwise the curve value will be clamped. void EvaluateFirstDerivative(T& result, float time, bool loop = true) const { - typename Base::KeyFrameData data(_keyframes); + typename Base::KeyFrameData data(_keyframes.Get(), _keyframes.Count()); Base::EvaluateFirstDerivative(data, result, time, loop); } @@ -665,7 +663,7 @@ public: /// If true the curve will loop when it goes past the end or beginning. Otherwise the curve value will be clamped. void EvaluateKey(KeyFrame& result, float time, bool loop = true) const { - typename Base::KeyFrameData data(_keyframes); + typename Base::KeyFrameData data(_keyframes.Get(), _keyframes.Count()); Base::EvaluateKey(data, result, time, loop); } @@ -686,7 +684,7 @@ public: return; } - typename Base::KeyFrameData data(_keyframes); + typename Base::KeyFrameData data(_keyframes.Get(), _keyframes.Count()); KeyFrame startValue, endValue; Base::EvaluateKey(data, startValue, start, false); Base::EvaluateKey(data, endValue, end, false); @@ -749,57 +747,6 @@ public: _keyframes[i].Time = _keyframes[i].Time * timeScale + timeOffset;; } -public: - - /// - /// Serializes the curve data to the stream. - /// - /// The output stream. - void Serialize(WriteStream& stream) const - { - // Version - if (_keyframes.IsEmpty()) - { - stream.WriteInt32(0); - return; - } - stream.WriteInt32(1); - - // TODO: support compression (serialize compression mode) - - // Raw keyframes data - stream.WriteInt32(_keyframes.Count()); - stream.WriteBytes(_keyframes.Get(), _keyframes.Count() * sizeof(KeyFrame)); - } - - /// - /// Deserializes the curve data from the stream. - /// - /// The input stream. - bool Deserialize(ReadStream& stream) - { - // Cleanup - _keyframes.Resize(0); - - // Version - int32 version; - stream.ReadInt32(&version); - if (version == 0) - return false; - if (version != 1) - { - return true; - } - - // Raw keyframes data - int32 keyframesCount; - stream.ReadInt32(&keyframesCount); - _keyframes.Resize(keyframesCount, false); - stream.ReadBytes(_keyframes.Get(), _keyframes.Count() * sizeof(KeyFrame)); - - return false; - } - public: FORCE_INLINE KeyFrame& operator[](int32 index) diff --git a/Source/Engine/Animations/CurveSerialization.h b/Source/Engine/Animations/CurveSerialization.h index 06f7788ea..4af89ceca 100644 --- a/Source/Engine/Animations/CurveSerialization.h +++ b/Source/Engine/Animations/CurveSerialization.h @@ -3,7 +3,9 @@ #pragma once #include "Curve.h" -#include "Engine/Core/Collections/Array.h" +#include "Engine/Core/Types/DataContainer.h" +#include "Engine/Serialization/ReadStream.h" +#include "Engine/Serialization/WriteStream.h" #include "Engine/Serialization/Serialization.h" // @formatter:off @@ -166,6 +168,51 @@ namespace Serialization Deserialize(keyframesArray[i], keyframes[i], modifier); } } + + template + inline void Serialize(WriteStream& stream, const Curve& v) + { + auto& keyframes = v.GetKeyframes(); + + // Version + if (keyframes.IsEmpty()) + { + stream.WriteInt32(0); + return; + } + stream.WriteInt32(1); + + // TODO: support compression (serialize compression mode) + + // Raw keyframes data + stream.WriteInt32(keyframes.Count()); + stream.WriteBytes(keyframes.Get(), keyframes.Count() * sizeof(KeyFrame)); + } + + template + inline bool Deserialize(ReadStream& stream, Curve& v) + { + auto& keyframes = v.GetKeyframes(); + keyframes.Resize(0); + + // Version + int32 version; + stream.ReadInt32(&version); + if (version == 0) + return false; + if (version != 1) + { + return true; + } + + // Raw keyframes data + int32 keyframesCount; + stream.ReadInt32(&keyframesCount); + keyframes.Resize(keyframesCount, false); + stream.ReadBytes(keyframes.Get(), keyframes.Count() * sizeof(KeyFrame)); + + return false; + } } // @formatter:on diff --git a/Source/Engine/Content/Assets/Animation.cpp b/Source/Engine/Content/Assets/Animation.cpp index c6927530e..963ddaceb 100644 --- a/Source/Engine/Content/Assets/Animation.cpp +++ b/Source/Engine/Content/Assets/Animation.cpp @@ -5,6 +5,7 @@ #include "Engine/Core/Log.h" #include "Engine/Profiler/ProfilerCPU.h" #include "Engine/Content/Factories/BinaryAssetFactory.h" +#include "Engine/Animations/CurveSerialization.h" #include "Engine/Serialization/MemoryReadStream.h" #if USE_EDITOR #include "Engine/Serialization/MemoryWriteStream.h" @@ -358,9 +359,9 @@ bool Animation::Save(const StringView& path) { auto& anim = Data.Channels[i]; stream.WriteString(anim.NodeName, 172); - anim.Position.Serialize(stream); - anim.Rotation.Serialize(stream); - anim.Scale.Serialize(stream); + Serialization::Serialize(stream, anim.Position); + Serialization::Serialize(stream, anim.Rotation); + Serialization::Serialize(stream, anim.Scale); } // Set data to the chunk asset @@ -442,9 +443,9 @@ Asset::LoadResult Animation::load() auto& anim = Data.Channels[i]; stream.ReadString(&anim.NodeName, 172); - bool failed = anim.Position.Deserialize(stream); - failed |= anim.Rotation.Deserialize(stream); - failed |= anim.Scale.Deserialize(stream); + bool failed = Serialization::Deserialize(stream, anim.Position); + failed |= Serialization::Deserialize(stream, anim.Rotation); + failed |= Serialization::Deserialize(stream, anim.Scale); if (failed) { diff --git a/Source/Engine/Graphics/Models/ModelData.cpp b/Source/Engine/Graphics/Models/ModelData.cpp index 56981e65d..71b511b4f 100644 --- a/Source/Engine/Graphics/Models/ModelData.cpp +++ b/Source/Engine/Graphics/Models/ModelData.cpp @@ -2,6 +2,7 @@ #include "ModelData.h" #include "Engine/Core/Log.h" +#include "Engine/Animations/CurveSerialization.h" #include "Engine/Serialization/WriteStream.h" #include "Engine/Debug/Exceptions/ArgumentNullException.h" #include "Engine/Debug/Exceptions/ArgumentOutOfRangeException.h" @@ -753,7 +754,7 @@ bool ModelData::Pack2SkinnedModelHeader(WriteStream* stream) const stream->Write(&sphere); // TODO: calculate Sphere and Box at once - make it faster using SSE - + // Blend Shapes const int32 blendShapes = mesh.BlendShapes.Count(); stream->WriteUint16(blendShapes); @@ -830,9 +831,9 @@ bool ModelData::Pack2AnimationHeader(WriteStream* stream) const auto& anim = Animation.Channels[i]; stream->WriteString(anim.NodeName, 172); - anim.Position.Serialize(*stream); - anim.Rotation.Serialize(*stream); - anim.Scale.Serialize(*stream); + Serialization::Serialize(*stream, anim.Position); + Serialization::Serialize(*stream, anim.Rotation); + Serialization::Serialize(*stream, anim.Scale); } return false;