From 0577c0f0dda8db34796ca88edff29f71ee6164d2 Mon Sep 17 00:00:00 2001 From: greerdv Date: Fri, 28 May 2021 15:24:02 +0100 Subject: [PATCH] update transform serialization to handle migration to uniform scale --- Code/Framework/AzCore/AzCore/Math/Aabb.cpp | 2 +- Code/Framework/AzCore/AzCore/Math/Obb.cpp | 2 +- .../AzCore/AzCore/Math/Transform.cpp | 45 +++++++++++++++---- Code/Framework/AzCore/AzCore/Math/Transform.h | 9 ++-- .../AzCore/Math/TransformSerializer.cpp | 2 +- .../AZTestShared/Math/MathTestHelpers.cpp | 2 +- 6 files changed, 46 insertions(+), 16 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Math/Aabb.cpp b/Code/Framework/AzCore/AzCore/Math/Aabb.cpp index 3f7cb4ecf5..367594be63 100644 --- a/Code/Framework/AzCore/AzCore/Math/Aabb.cpp +++ b/Code/Framework/AzCore/AzCore/Math/Aabb.cpp @@ -227,7 +227,7 @@ namespace AZ // the min and max of each part and sum them to get the min and max co-ordinate of the transformed box. For a given new axis, // the coefficients for what proportion of each original axis is rotated onto that new axis are the same as the components we // would get by performing the inverse rotation on the new axis, so we need to take the conjugate to get the inverse rotation. - axisCoeffs = transform.GetScale() * (transform.GetRotation().GetConjugate().TransformVector(axis)); + axisCoeffs = transform.GetUniformScale() * (transform.GetRotation().GetConjugate().TransformVector(axis)); a = axisCoeffs * m_min; b = axisCoeffs * m_max; diff --git a/Code/Framework/AzCore/AzCore/Math/Obb.cpp b/Code/Framework/AzCore/AzCore/Math/Obb.cpp index eb511669d0..9226ddd28f 100644 --- a/Code/Framework/AzCore/AzCore/Math/Obb.cpp +++ b/Code/Framework/AzCore/AzCore/Math/Obb.cpp @@ -154,7 +154,7 @@ namespace AZ return Obb::CreateFromPositionRotationAndHalfLengths( transform.TransformPoint(obb.GetPosition()), transform.GetRotation() * obb.GetRotation(), - transform.GetScale() * obb.GetHalfLengths() + transform.GetUniformScale() * obb.GetHalfLengths() ); } } diff --git a/Code/Framework/AzCore/AzCore/Math/Transform.cpp b/Code/Framework/AzCore/AzCore/Math/Transform.cpp index 12f8e426cd..0ae3e9c0ef 100644 --- a/Code/Framework/AzCore/AzCore/Math/Transform.cpp +++ b/Code/Framework/AzCore/AzCore/Math/Transform.cpp @@ -130,8 +130,8 @@ namespace AZ const Transform* transform = reinterpret_cast(classPtr); float data[NumFloats]; transform->GetRotation().StoreToFloat4(data); - transform->GetScale().StoreToFloat3(&data[4]); - transform->GetTranslation().StoreToFloat3(&data[7]); + data[4] = transform->GetUniformScale(); + transform->GetTranslation().StoreToFloat3(&data[5]); for (int i = 0; i < NumFloats; i++) { @@ -159,8 +159,8 @@ namespace AZ size_t TransformSerializer::TextToData(const char* text, unsigned int textVersion, IO::GenericStream& stream, bool isDataBigEndian) { - const size_t dataBufferSize = AZStd::max(NumFloatsVersion0, NumFloats); - const size_t numElements = textVersion < 1 ? NumFloatsVersion0 : NumFloats; + const size_t dataBufferSize = AZStd::max(AZStd::max(NumFloatsVersion1, NumFloatsVersion0), NumFloats); + const size_t numElements = textVersion < 1 ? NumFloatsVersion0 : (textVersion == 1 ? NumFloatsVersion1 : NumFloats); size_t nextNumberIndex = 0; AZStd::array data; @@ -201,7 +201,34 @@ namespace AZ return true; } - // otherwise load as a separate rotation, scale and translation + // version 1 had a quaternion rotation, vector3 scale and vector3 translation + else if (version == 1) + { + float data[NumFloatsVersion1]; + if (stream.GetLength() < sizeof(data)) + { + return false; + } + + stream.Read(sizeof(data), reinterpret_cast(data)); + + for (unsigned int i = 0; i < AZ_ARRAY_SIZE(data); ++i) + { + AZ_SERIALIZE_SWAP_ENDIAN(data[i], isDataBigEndian); + } + + Quaternion rotation = Quaternion::CreateFromFloat4(data); + Vector3 vectorScale = Vector3::CreateFromFloat3(&data[4]); + Vector3 translation = Vector3::CreateFromFloat3(&data[7]); + + float uniformScale = vectorScale.GetMaxElement(); + + *reinterpret_cast(classPtr) = + Transform::CreateFromQuaternionAndTranslation(rotation, translation) * Transform::CreateUniformScale(uniformScale); + return true; + } + + // otherwise load as a quaternion rotation, float scale and vector3 translation float data[NumFloats]; if (stream.GetLength() < sizeof(data)) { @@ -216,11 +243,11 @@ namespace AZ } Quaternion rotation = Quaternion::CreateFromFloat4(data); - Vector3 scale = Vector3::CreateFromFloat3(&data[4]); - Vector3 translation = Vector3::CreateFromFloat3(&data[7]); + float scale = data[4]; + Vector3 translation = Vector3::CreateFromFloat3(&data[5]); *reinterpret_cast(classPtr) = - Transform::CreateFromQuaternionAndTranslation(rotation, translation) * Transform::CreateScale(scale); + Transform::CreateFromQuaternionAndTranslation(rotation, translation) * Transform::CreateUniformScale(scale); return true; } @@ -237,7 +264,7 @@ namespace AZ if (serializeContext) { serializeContext->Class() - ->Version(1) + ->Version(2) ->Serializer(); } diff --git a/Code/Framework/AzCore/AzCore/Math/Transform.h b/Code/Framework/AzCore/AzCore/Math/Transform.h index e8c4325c7a..974a0180e8 100644 --- a/Code/Framework/AzCore/AzCore/Math/Transform.h +++ b/Code/Framework/AzCore/AzCore/Math/Transform.h @@ -25,10 +25,13 @@ namespace AZ : public SerializeContext::IDataSerializer { public: - // number of floats in the serialized representation, 4 for rotation, 3 for scale and 3 for translation - static constexpr int NumFloats = 10; + // number of floats in the serialized representation, 4 for rotation, 1 for scale and 3 for translation + static constexpr int NumFloats = 8; - // number of floats in the old format, which stored a 3x4 matrix + // number of floats in version 1, which used 4 for rotation, 3 for scale and 3 for translation + static constexpr int NumFloatsVersion1 = 10; + + // number of floats in version 0, which stored a 3x4 matrix static constexpr int NumFloatsVersion0 = 12; size_t Save(const void* classPtr, IO::GenericStream& stream, bool isDataBigEndian) override; diff --git a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp index 86bc1c36ea..36c40265af 100644 --- a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp @@ -67,7 +67,7 @@ namespace AZ result.Combine(loadResult); - transformInstance->SetScale(AZ::Vector3(scale)); + transformInstance->SetUniformScale(scale); } return context.Report( diff --git a/Code/Framework/AzCore/Tests/AZTestShared/Math/MathTestHelpers.cpp b/Code/Framework/AzCore/Tests/AZTestShared/Math/MathTestHelpers.cpp index 42b77f6976..f9616702f1 100644 --- a/Code/Framework/AzCore/Tests/AZTestShared/Math/MathTestHelpers.cpp +++ b/Code/Framework/AzCore/Tests/AZTestShared/Math/MathTestHelpers.cpp @@ -68,7 +68,7 @@ namespace AZ return os << "translation: " << transform.GetTranslation() << " rotation: " << transform.GetRotation() - << " scale: " << transform.GetScale(); + << " scale: " << transform.GetUniformScale(); } std::ostream& operator<<(std::ostream& os, const Color& color)