// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Curve.h" #include "Engine/Core/Types/DataContainer.h" #include "Engine/Serialization/ReadStream.h" #include "Engine/Serialization/WriteStream.h" #include "Engine/Serialization/Serialization.h" // @formatter:off namespace Serialization { // StepCurveKeyframe template inline bool ShouldSerialize(const StepCurveKeyframe& v, const void* otherObj) { if (!otherObj) return true; const auto other = (const StepCurveKeyframe*)otherObj; return !(v == *other); } template inline void Serialize(ISerializable::SerializeStream& stream, const StepCurveKeyframe& v, const void* otherObj) { stream.StartObject(); stream.JKEY("Time"); Serialize(stream, v.Time, nullptr); stream.JKEY("Value"); Serialize(stream, v.Value, nullptr); stream.EndObject(); } template inline void Deserialize(ISerializable::DeserializeStream& stream, StepCurveKeyframe& v, ISerializeModifier* modifier) { DESERIALIZE_MEMBER(Time, v.Time); DESERIALIZE_MEMBER(Value, v.Value); } // LinearCurveKeyframe template inline bool ShouldSerialize(const LinearCurveKeyframe& v, const void* otherObj) { if (!otherObj) return true; const auto other = (const LinearCurveKeyframe*)otherObj; return !(v == *other); } template inline void Serialize(ISerializable::SerializeStream& stream, const LinearCurveKeyframe& v, const void* otherObj) { stream.StartObject(); stream.JKEY("Time"); Serialize(stream, v.Time, nullptr); stream.JKEY("Value"); Serialize(stream, v.Value, nullptr); stream.EndObject(); } template inline void Deserialize(ISerializable::DeserializeStream& stream, LinearCurveKeyframe& v, ISerializeModifier* modifier) { DESERIALIZE_MEMBER(Time, v.Time); DESERIALIZE_MEMBER(Value, v.Value); } // HermiteCurveKeyframe template inline bool ShouldSerialize(const HermiteCurveKeyframe& v, const void* otherObj) { if (!otherObj) return true; const auto other = (const HermiteCurveKeyframe*)otherObj; return !(v == *other); } template inline void Serialize(ISerializable::SerializeStream& stream, const HermiteCurveKeyframe& v, const void* otherObj) { stream.StartObject(); stream.JKEY("Time"); Serialize(stream, v.Time, nullptr); stream.JKEY("Value"); Serialize(stream, v.Value, nullptr); stream.JKEY("TangentIn"); Serialize(stream, v.TangentIn, nullptr); stream.JKEY("TangentOut"); Serialize(stream, v.TangentOut, nullptr); stream.EndObject(); } template inline void Deserialize(ISerializable::DeserializeStream& stream, HermiteCurveKeyframe& v, ISerializeModifier* modifier) { DESERIALIZE_MEMBER(Time, v.Time); DESERIALIZE_MEMBER(Value, v.Value); DESERIALIZE_MEMBER(TangentIn, v.TangentIn); DESERIALIZE_MEMBER(TangentOut, v.TangentOut); } // BezierCurveKeyframe template inline bool ShouldSerialize(const BezierCurveKeyframe& v, const void* otherObj) { if (!otherObj) return true; const auto other = (const BezierCurveKeyframe*)otherObj; return !(v == *other); } template inline void Serialize(ISerializable::SerializeStream& stream, const BezierCurveKeyframe& v, const void* otherObj) { stream.StartObject(); stream.JKEY("Time"); Serialize(stream, v.Time, nullptr); stream.JKEY("Value"); Serialize(stream, v.Value, nullptr); stream.JKEY("TangentIn"); Serialize(stream, v.TangentIn, nullptr); stream.JKEY("TangentOut"); Serialize(stream, v.TangentOut, nullptr); stream.EndObject(); } template inline void Deserialize(ISerializable::DeserializeStream& stream, BezierCurveKeyframe& v, ISerializeModifier* modifier) { DESERIALIZE_MEMBER(Time, v.Time); DESERIALIZE_MEMBER(Value, v.Value); DESERIALIZE_MEMBER(TangentIn, v.TangentIn); DESERIALIZE_MEMBER(TangentOut, v.TangentOut); } // Curve template inline bool ShouldSerialize(const Curve& v, const void* otherObj) { if (!otherObj) return true; const auto other = (const Curve*)otherObj; return !(v == *other); } template inline void Serialize(ISerializable::SerializeStream& stream, const Curve& v, const void* otherObj) { stream.StartObject(); stream.JKEY("Keyframes"); stream.StartArray(); for (auto& k : v.GetKeyframes()) Serialize(stream, k, nullptr); stream.EndArray(); stream.EndObject(); } template inline void Deserialize(ISerializable::DeserializeStream& stream, Curve& v, ISerializeModifier* modifier) { if (!stream.IsObject()) return; const auto mKeyframes = SERIALIZE_FIND_MEMBER(stream, "Keyframes"); if (mKeyframes != stream.MemberEnd()) { const auto& keyframesArray = mKeyframes->value.GetArray(); auto& keyframes = v.GetKeyframes(); keyframes.Resize(keyframesArray.Size()); for (rapidjson::SizeType i = 0; i < keyframesArray.Size(); i++) 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()); static_assert(TIsPODType::Value, "Raw bytes serialization only for raw POD types."); 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); static_assert(TIsPODType::Value, "Raw bytes serialization only for raw POD types."); stream.ReadBytes(keyframes.Get(), keyframes.Count() * sizeof(KeyFrame)); return false; } } // @formatter:on