Merge pull request #1039 from aws-lumberyard-dev/transform-float-scale-3

refactor vector scale in Transform to float scale
This commit is contained in:
greerdv
2021-05-28 21:20:03 +01:00
committed by GitHub
38 changed files with 254 additions and 386 deletions
@@ -219,18 +219,11 @@ namespace AZ
//! Scale modifiers
//! @{
//! Set local scale of the transform.
//! @param scale The new scale to set.
virtual void SetLocalScale([[maybe_unused]] const AZ::Vector3& scale) {}
//! Get the scale value in local space.
//! @deprecated GetLocalScale is deprecated, and is left only to allow migration of legacy vector scale.
//! Get the legacy vector scale value in local space.
//! @return The scale value in local space.
virtual AZ::Vector3 GetLocalScale() { return AZ::Vector3(FLT_MAX); }
//! Get the scale value in world space.
//! @return The scale value in world space.
virtual AZ::Vector3 GetWorldScale() { return AZ::Vector3(FLT_MAX); }
//! Set the uniform scale value in local space.
virtual void SetLocalUniformScale([[maybe_unused]] float scale) {}
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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()
);
}
}
+40 -19
View File
@@ -130,8 +130,8 @@ namespace AZ
const Transform* transform = reinterpret_cast<const Transform*>(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<float, dataBufferSize> 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<void*>(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<Transform*>(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<Transform*>(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<Transform>()
->Version(1)
->Version(2)
->Serializer<TransformSerializer>();
}
@@ -250,7 +277,7 @@ namespace AZ
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
Attribute(Script::Attributes::Storage, Script::Attributes::StorageType::Value)->
Attribute(Script::Attributes::GenericConstructorOverride, &Internal::TransformDefaultConstructor)->
Constructor<const Vector3&, const Quaternion&, const Vector3&>()->
Constructor<const Vector3&, const Quaternion&, float>()->
Method("GetBasis", &Transform::GetBasis)->
Method("GetBasisX", &Transform::GetBasisX)->
Method("GetBasisY", &Transform::GetBasisY)->
@@ -283,15 +310,10 @@ namespace AZ
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
Method("GetRotation", &Transform::GetRotation)->
Method<void (Transform::*)(const Quaternion&)>("SetRotation", &Transform::SetRotation)->
Method("GetScale", &Transform::GetScale)->
Method("GetUniformScale", &Transform::GetUniformScale)->
Method("SetScale", &Transform::SetScale)->
Method("SetUniformScale", &Transform::SetUniformScale)->
Method("ExtractScale", &Transform::ExtractScale)->
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
Method("ExtractUniformScale", &Transform::ExtractUniformScale)->
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
Method("MultiplyByScale", &Transform::MultiplyByScale)->
Method("MultiplyByUniformScale", &Transform::MultiplyByUniformScale)->
Method("GetInverse", &Transform::GetInverse)->
Method("Invert", &Transform::Invert)->
@@ -310,7 +332,6 @@ namespace AZ
Method("CreateFromQuaternionAndTranslation", &Transform::CreateFromQuaternionAndTranslation)->
Method("CreateFromMatrix3x3", &Transform::CreateFromMatrix3x3)->
Method("CreateFromMatrix3x3AndTranslation", &Transform::CreateFromMatrix3x3AndTranslation)->
Method("CreateScale", &Transform::CreateScale)->
Method("CreateUniformScale", &Transform::CreateUniformScale)->
Method("CreateTranslation", &Transform::CreateTranslation)->
Method("ConstructFromValuesNumeric", &Internal::ConstructTransformFromValues);
@@ -321,7 +342,7 @@ namespace AZ
{
Transform result;
Matrix3x3 tmp = value;
result.m_scale = tmp.ExtractScale();
result.m_scale = tmp.ExtractScale().GetMaxElement();
result.m_rotation = Quaternion::CreateFromMatrix3x3(tmp);
result.m_translation = Vector3::CreateZero();
return result;
@@ -331,7 +352,7 @@ namespace AZ
{
Transform result;
Matrix3x3 tmp = value;
result.m_scale = tmp.ExtractScale();
result.m_scale = tmp.ExtractScale().GetMaxElement();
result.m_rotation = Quaternion::CreateFromMatrix3x3(tmp);
result.m_translation = p;
return result;
@@ -341,7 +362,7 @@ namespace AZ
{
Transform result;
Matrix3x4 tmp = value;
result.m_scale = tmp.ExtractScale();
result.m_scale = tmp.ExtractScale().GetMaxElement();
result.m_rotation = Quaternion::CreateFromMatrix3x4(tmp);
result.m_translation = value.GetTranslation();
return result;
+17 -16
View File
@@ -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;
@@ -45,7 +48,7 @@ namespace AZ
static constexpr float MaxTransformScale = 1e9f;
//! @}
//! The basic transformation class, represented using a quaternion rotation, vector scale and vector translation.
//! The basic transformation class, represented using a quaternion rotation, float scale and vector translation.
//! By design, cannot represent skew transformations.
class Transform
{
@@ -63,7 +66,7 @@ namespace AZ
Transform() = default;
//! Construct a transform from components.
Transform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale);
Transform(const Vector3& translation, const Quaternion& rotation, float scale);
//! Creates an identity transform.
static Transform CreateIdentity();
@@ -82,16 +85,20 @@ namespace AZ
static Transform CreateFromQuaternionAndTranslation(const class Quaternion& q, const Vector3& p);
//! Constructs from a Matrix3x3, translation is set to zero.
//! Note that Transform only allows uniform scale, so if the matrix has different scale values along its axes,
//! the largest matrix scale value will be used to uniformly scale the Transform.
static Transform CreateFromMatrix3x3(const class Matrix3x3& value);
//! Constructs from a Matrix3x3, translation is set to zero.
//! Constructs from a Matrix3x3 and translation Vector3.
//! Note that Transform only allows uniform scale, so if the matrix has different scale values along its axes,
//! the largest matrix scale value will be used to uniformly scale the Transform.
static Transform CreateFromMatrix3x3AndTranslation(const class Matrix3x3& value, const Vector3& p);
//! Constructs from a Matrix3x4.
//! Note that Transform only allows uniform scale, so if the matrix has different scale values along its axes,
//! the largest matrix scale value will be used to uniformly scale the Transform.
static Transform CreateFromMatrix3x4(const Matrix3x4& value);
//! Sets the transform to apply scale only, no rotation or translation.
static Transform CreateScale(const AZ::Vector3& scale);
//! Sets the transform to apply (uniform) scale only, no rotation or translation.
static Transform CreateUniformScale(const float scale);
@@ -122,18 +129,12 @@ namespace AZ
const Quaternion& GetRotation() const;
void SetRotation(const Quaternion& rotation);
Vector3 GetScale() const;
float GetUniformScale() const;
void SetScale(const Vector3& v);
void SetUniformScale(const float scale);
//! Sets the transform's scale to a unit value and returns the previous scale value.
Vector3 ExtractScale();
//! Sets the transform's scale to a unit value and returns the previous scale value.
float ExtractUniformScale();
void MultiplyByScale(const AZ::Vector3& scale);
void MultiplyByUniformScale(float scale);
Transform operator*(const Transform& rhs) const;
@@ -168,7 +169,7 @@ namespace AZ
private:
Quaternion m_rotation;
Vector3 m_scale;
float m_scale;
Vector3 m_translation;
};
+21 -58
View File
@@ -12,7 +12,7 @@
namespace AZ
{
AZ_MATH_INLINE Transform::Transform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale)
AZ_MATH_INLINE Transform::Transform(const Vector3& translation, const Quaternion& rotation, float scale)
: m_translation(translation)
, m_rotation(rotation)
, m_scale(scale)
@@ -25,7 +25,7 @@ namespace AZ
{
Transform result;
result.m_rotation = Quaternion::CreateIdentity();
result.m_scale = Vector3::CreateOne();
result.m_scale = 1.0f;
result.m_translation = Vector3::CreateZero();
return result;
}
@@ -49,7 +49,7 @@ namespace AZ
{
Transform result;
result.m_rotation = q;
result.m_scale = Vector3::CreateOne();
result.m_scale = 1.0f;
result.m_translation = Vector3::CreateZero();
return result;
}
@@ -58,26 +58,16 @@ namespace AZ
{
Transform result;
result.m_rotation = q;
result.m_scale = Vector3::CreateOne();
result.m_scale = 1.0f;
result.m_translation = p;
return result;
}
AZ_MATH_INLINE Transform Transform::CreateScale(const Vector3& scale)
{
AZ_WarningOnce("Transform", false, "CreateScale is deprecated, please use CreateUniformScale instead.");
Transform result;
result.m_rotation = Quaternion::CreateIdentity();
result.m_scale = scale;
result.m_translation = Vector3::CreateZero();
return result;
}
AZ_MATH_INLINE Transform Transform::CreateUniformScale(float scale)
{
Transform result;
result.m_rotation = Quaternion::CreateIdentity();
result.m_scale = Vector3(scale);
result.m_scale = scale;
result.m_translation = Vector3::CreateZero();
return result;
}
@@ -86,7 +76,7 @@ namespace AZ
{
Transform result;
result.m_rotation = Quaternion::CreateIdentity();
result.m_scale = Vector3::CreateOne();
result.m_scale = 1.0f;
result.m_translation = translation;
return result;
}
@@ -114,17 +104,17 @@ namespace AZ
AZ_MATH_INLINE Vector3 Transform::GetBasisX() const
{
return m_rotation.TransformVector(Vector3::CreateAxisX(m_scale.GetX()));
return m_rotation.TransformVector(Vector3::CreateAxisX(m_scale));
}
AZ_MATH_INLINE Vector3 Transform::GetBasisY() const
{
return m_rotation.TransformVector(Vector3::CreateAxisY(m_scale.GetY()));
return m_rotation.TransformVector(Vector3::CreateAxisY(m_scale));
}
AZ_MATH_INLINE Vector3 Transform::GetBasisZ() const
{
return m_rotation.TransformVector(Vector3::CreateAxisZ(m_scale.GetZ()));
return m_rotation.TransformVector(Vector3::CreateAxisZ(m_scale));
}
AZ_MATH_INLINE void Transform::GetBasisAndTranslation(Vector3* basisX, Vector3* basisY, Vector3* basisZ, Vector3* pos) const
@@ -160,49 +150,23 @@ namespace AZ
m_rotation = rotation;
}
AZ_MATH_INLINE Vector3 Transform::GetScale() const
{
AZ_WarningOnce("Transform", false, "GetScale is deprecated, please use GetUniformScale instead.");
return m_scale;
}
AZ_MATH_INLINE float Transform::GetUniformScale() const
{
return m_scale.GetMaxElement();
}
AZ_MATH_INLINE void Transform::SetScale(const Vector3& scale)
{
AZ_WarningOnce("Transform", false, "SetScale is deprecated, please use SetUniformScale instead.");
m_scale = scale;
return m_scale;
}
AZ_MATH_INLINE void Transform::SetUniformScale(const float scale)
{
m_scale = Vector3(scale);
}
AZ_MATH_INLINE Vector3 Transform::ExtractScale()
{
AZ_WarningOnce("Transform", false, "ExtractScale is deprecated, please use ExtractUniformScale instead.");
const Vector3 scale = m_scale;
m_scale = Vector3::CreateOne();
return scale;
m_scale = scale;
}
AZ_MATH_INLINE float Transform::ExtractUniformScale()
{
const float scale = m_scale.GetMaxElement();
m_scale = Vector3::CreateOne();
const float scale = m_scale;
m_scale = 1.0f;
return scale;
}
AZ_MATH_INLINE void Transform::MultiplyByScale(const Vector3& scale)
{
AZ_WarningOnce("Transform", false, "MultiplyByScale is deprecated, please use MultiplyByUniformScale instead.");
m_scale *= scale;
}
AZ_MATH_INLINE void Transform::MultiplyByUniformScale(float scale)
{
m_scale *= scale;
@@ -240,10 +204,9 @@ namespace AZ
AZ_MATH_INLINE Transform Transform::GetInverse() const
{
// note - need to be careful about how to calculate inverse when there is non-uniform scale
Transform out;
out.m_rotation = m_rotation.GetConjugate();
out.m_scale = m_scale.GetReciprocal();
out.m_scale = 1.0f / m_scale;
out.m_translation = -out.m_scale * (out.m_rotation.TransformVector(m_translation));
return out;
}
@@ -255,27 +218,27 @@ namespace AZ
AZ_MATH_INLINE bool Transform::IsOrthogonal(float tolerance) const
{
return m_scale.IsClose(Vector3::CreateOne(), tolerance);
return AZ::IsClose(m_scale, 1.0f, tolerance);
}
AZ_MATH_INLINE Transform Transform::GetOrthogonalized() const
{
Transform result;
result.m_rotation = m_rotation;
result.m_scale = Vector3::CreateOne();
result.m_scale = 1.0f;
result.m_translation = m_translation;
return result;
}
AZ_MATH_INLINE void Transform::Orthogonalize()
{
m_scale = Vector3::CreateOne();
m_scale = 1.0f;
}
AZ_MATH_INLINE bool Transform::IsClose(const Transform& rhs, float tolerance) const
{
return m_rotation.IsClose(rhs.m_rotation, tolerance)
&& m_scale.IsClose(rhs.m_scale, tolerance)
&& AZ::IsClose(m_scale, rhs.m_scale, tolerance)
&& m_translation.IsClose(rhs.m_translation, tolerance);
}
@@ -304,21 +267,21 @@ namespace AZ
AZ_MATH_INLINE void Transform::SetFromEulerDegrees(const Vector3& eulerDegrees)
{
m_translation = Vector3::CreateZero();
m_scale = Vector3::CreateOne();
m_scale = 1.0f;
m_rotation.SetFromEulerDegrees(eulerDegrees);
}
AZ_MATH_INLINE void Transform::SetFromEulerRadians(const Vector3& eulerRadians)
{
m_translation = Vector3::CreateZero();
m_scale = Vector3::CreateOne();
m_scale = 1.0f;
m_rotation.SetFromEulerRadians(eulerRadians);
}
AZ_MATH_INLINE bool Transform::IsFinite() const
{
return m_rotation.IsFinite()
&& m_scale.IsFinite()
&& AZ::IsFiniteFloat(m_scale)
&& m_translation.IsFinite();
}
@@ -67,7 +67,7 @@ namespace AZ
result.Combine(loadResult);
transformInstance->SetScale(AZ::Vector3(scale));
transformInstance->SetUniformScale(scale);
}
return context.Report(
@@ -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)
@@ -44,7 +44,7 @@ namespace JsonSerializationTests
AZStd::shared_ptr<AZ::Transform> CreateFullySetInstance() override
{
return AZStd::make_shared<AZ::Transform>(
AZ::Vector3(1.0f, 2.0f, 3.0f), AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f), AZ::Vector3(9.0f));
AZ::Vector3(1.0f, 2.0f, 3.0f), AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f), 9.0f);
}
AZStd::string_view GetJsonForFullySetInstance() override
@@ -95,7 +95,7 @@ namespace JsonSerializationTests
AZ::Transform expectedTransform(
AZ::Vector3(2.25f, 3.5f, 4.75f),
AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f),
AZ::Vector3(5.5f));
5.5f);
rapidjson::Document json;
json.Parse(R"({ "Translation": [ 2.25, 3.5, 4.75 ], "Rotation": [ 0.25, 0.5, 0.75, 1.0 ], "Scale": 5.5 })");
@@ -406,21 +406,10 @@ namespace AzFramework
return m_localTM.GetRotation();
}
void TransformComponent::SetLocalScale(const AZ::Vector3& scale)
{
AZ::Transform newLocalTM = m_localTM;
newLocalTM.SetScale(scale);
SetLocalTM(newLocalTM);
}
AZ::Vector3 TransformComponent::GetLocalScale()
{
return m_localTM.GetScale();
}
AZ::Vector3 TransformComponent::GetWorldScale()
{
return m_worldTM.GetScale();
AZ_WarningOnce("TransformComponent", false, "GetLocalScale is deprecated, please use GetLocalUniformScale instead");
return AZ::Vector3(m_localTM.GetUniformScale());
}
void TransformComponent::SetLocalUniformScale(float scale)
@@ -756,11 +745,11 @@ namespace AzFramework
->Event("GetLocalRotationQuaternion", &AZ::TransformBus::Events::GetLocalRotationQuaternion)
->Attribute("Rotation", AZ::Edit::Attributes::PropertyRotation)
->VirtualProperty("Rotation", "GetLocalRotationQuaternion", "SetLocalRotationQuaternion")
->Event("SetLocalScale", &AZ::TransformBus::Events::SetLocalScale)
->Event("GetLocalScale", &AZ::TransformBus::Events::GetLocalScale)
->Attribute("Scale", AZ::Edit::Attributes::PropertyScale)
->VirtualProperty("Scale", "GetLocalScale", "SetLocalScale")
->Event("GetWorldScale", &AZ::TransformBus::Events::GetWorldScale)
->Event("SetLocalUniformScale", &AZ::TransformBus::Events::SetLocalUniformScale)
->Event("GetLocalUniformScale", &AZ::TransformBus::Events::GetLocalUniformScale)
->VirtualProperty("Uniform Scale", "GetLocalUniformScale", "SetLocalUniformScale")
->Event("GetChildren", &AZ::TransformBus::Events::GetChildren)
->Event("GetAllDescendants", &AZ::TransformBus::Events::GetAllDescendants)
->Event("GetEntityAndAllDescendants", &AZ::TransformBus::Events::GetEntityAndAllDescendants)
@@ -128,9 +128,7 @@ namespace AzFramework
AZ::Quaternion GetLocalRotationQuaternion() override;
// Scale Modifiers
void SetLocalScale(const AZ::Vector3& scale) override;
AZ::Vector3 GetLocalScale() override;
AZ::Vector3 GetWorldScale() override;
void SetLocalUniformScale(float scale) override;
float GetLocalUniformScale() override;
@@ -39,7 +39,7 @@ namespace AzToolsFramework
AZ::Transform result;
result.SetRotation(m_space.GetRotation() * localTransform.GetRotation());
result.SetTranslation(m_space.TransformPoint(m_nonUniformScale * localTransform.GetTranslation()));
result.SetScale(m_space.GetScale() * localTransform.GetUniformScale());
result.SetUniformScale(m_space.GetUniformScale() * localTransform.GetUniformScale());
return result;
}
@@ -28,7 +28,7 @@ namespace AzToolsFramework
AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity();
AZ::TransformBus::EventResult(worldFromLocal, m_entityComponentIdPair.GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
worldFromLocal.ExtractScale();
worldFromLocal.ExtractUniformScale();
m_manipulators = AZStd::make_unique<ScaleManipulators>(worldFromLocal);
m_manipulators->Register(g_mainManipulatorManagerId);
m_manipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
@@ -32,7 +32,6 @@
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/ToolsComponents/TransformComponentBus.h>
#include <AzToolsFramework/ToolsComponents/TransformScalePropertyHandler.h>
#include <AzToolsFramework/ToolsComponents/EditorInspectorComponentBus.h>
#include <AzToolsFramework/ToolsComponents/EditorPendingCompositionBus.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
@@ -50,10 +49,10 @@ namespace AzToolsFramework
{
const AZ::u32 ParentEntityCRC = AZ_CRC("Parent Entity", 0x5b1b276c);
// Decompose a transform into euler angles in degrees, scale (along basis, any shear will be dropped), and translation.
void DecomposeTransform(const AZ::Transform& transform, AZ::Vector3& translation, AZ::Vector3& rotation, AZ::Vector3& scale)
// Decompose a transform into euler angles in degrees, uniform scale, and translation.
void DecomposeTransform(const AZ::Transform& transform, AZ::Vector3& translation, AZ::Vector3& rotation, float& scale)
{
scale = transform.GetScale();
scale = transform.GetUniformScale();
translation = transform.GetTranslation();
rotation = transform.GetRotation().GetEulerDegrees();
}
@@ -120,7 +119,7 @@ namespace AzToolsFramework
// Decompose the old slice-relative transform and set it as a our editor transform,
// since the entity is now our parent.
EditorTransform editorTransform;
DecomposeTransform(sliceRelTransform, editorTransform.m_translate, editorTransform.m_rotate, editorTransform.m_scale);
DecomposeTransform(sliceRelTransform, editorTransform.m_translate, editorTransform.m_rotate, editorTransform.m_uniformScale);
editorTransformElement.Convert<EditorTransform>(context);
editorTransformElement.SetData(context, editorTransform);
}
@@ -170,6 +169,23 @@ namespace AzToolsFramework
return true;
}
bool EditorTransformDataConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
{
if (classElement.GetVersion() < 3)
{
// version 3 replaces vector scale with uniform scale but does not yet delete the legacy scale data
// in order to allow for migration
AZ::Vector3 vectorScale;
if (classElement.FindSubElementAndGetData<AZ::Vector3>(AZ_CRC_CE("Scale"), vectorScale))
{
const float uniformScale = vectorScale.GetMaxElement();
classElement.AddElementWithData(context, "UniformScale", uniformScale);
}
}
return true;
}
} // namespace Internal
TransformComponent::TransformComponent()
@@ -357,7 +373,7 @@ namespace AzToolsFramework
AZ::Transform TransformComponent::GetLocalScaleTM() const
{
return AZ::Transform::CreateUniformScale(m_editorTransform.m_scale.GetMaxElement());
return AZ::Transform::CreateUniformScale(m_editorTransform.m_uniformScale);
}
const AZ::Transform& TransformComponent::GetLocalTM()
@@ -374,12 +390,13 @@ namespace AzToolsFramework
// given a local transform, update local transform.
void TransformComponent::SetLocalTM(const AZ::Transform& finalTx)
{
AZ::Vector3 tx, rot, scale;
Internal::DecomposeTransform(finalTx, tx, rot, scale);
AZ::Vector3 tx, rot;
float uniformScale;
Internal::DecomposeTransform(finalTx, tx, rot, uniformScale);
m_editorTransform.m_translate = tx;
m_editorTransform.m_rotate = rot;
m_editorTransform.m_scale = scale;
m_editorTransform.m_uniformScale = uniformScale;
TransformChanged();
}
@@ -599,31 +616,21 @@ namespace AzToolsFramework
return result;
}
void TransformComponent::SetLocalScale(const AZ::Vector3& scale)
{
m_editorTransform.m_scale = scale;
TransformChanged();
}
AZ::Vector3 TransformComponent::GetLocalScale()
{
return m_editorTransform.m_scale;
}
AZ::Vector3 TransformComponent::GetWorldScale()
{
return GetWorldTM().GetScale();
AZ_WarningOnce("TransformComponent", false, "GetLocalScale is deprecated, please use GetLocalUniformScale instead");
return m_editorTransform.m_legacyScale;
}
void TransformComponent::SetLocalUniformScale(float scale)
{
m_editorTransform.m_scale = AZ::Vector3(scale);
m_editorTransform.m_uniformScale = scale;
TransformChanged();
}
float TransformComponent::GetLocalUniformScale()
{
return m_editorTransform.m_scale.GetMaxElement();
return m_editorTransform.m_uniformScale;
}
float TransformComponent::GetWorldUniformScale()
@@ -1141,9 +1148,10 @@ namespace AzToolsFramework
serializeContext->Class<EditorTransform>()->
Field("Translate", &EditorTransform::m_translate)->
Field("Rotate", &EditorTransform::m_rotate)->
Field("Scale", &EditorTransform::m_scale)->
Field("Scale", &EditorTransform::m_legacyScale)->
Field("Locked", &EditorTransform::m_locked)->
Version(2);
Field("UniformScale", &EditorTransform::m_uniformScale)->
Version(3, &Internal::EditorTransformDataConverter);
serializeContext->Class<Components::TransformComponent, EditorComponentBase>()->
Field("Parent Entity", &TransformComponent::m_parentEntityId)->
@@ -1202,7 +1210,7 @@ namespace AzToolsFramework
Attribute(AZ::Edit::Attributes::Suffix, " deg")->
Attribute(AZ::Edit::Attributes::ReadOnly, &EditorTransform::m_locked)->
Attribute(AZ::Edit::Attributes::SliceFlags, AZ::Edit::SliceFlags::NotPushableOnSliceRoot)->
DataElement(TransformScaleHandler, &EditorTransform::m_scale, "Scale", "Local Scale")->
DataElement(AZ::Edit::UIHandlers::Default, &EditorTransform::m_uniformScale, "Uniform Scale", "Local Uniform Scale")->
Attribute(AZ::Edit::Attributes::Step, 0.1f)->
Attribute(AZ::Edit::Attributes::ReadOnly, &EditorTransform::m_locked)
;
@@ -1230,7 +1238,8 @@ namespace AzToolsFramework
{
AzToolsFramework::ScopedUndoBatch undo("Reset transform values");
m_editorTransform.m_translate = AZ::Vector3::CreateZero();
m_editorTransform.m_scale = AZ::Vector3::CreateOne();
m_editorTransform.m_legacyScale = AZ::Vector3::CreateOne();
m_editorTransform.m_uniformScale = 1.0f;
m_editorTransform.m_rotate = AZ::Vector3::CreateZero();
OnTransformChanged();
SetDirty();
@@ -115,9 +115,7 @@ namespace AzToolsFramework
AZ::Quaternion GetLocalRotationQuaternion() override;
// Scale Modifiers
void SetLocalScale(const AZ::Vector3& scale) override;
AZ::Vector3 GetLocalScale() override;
AZ::Vector3 GetWorldScale() override;
void SetLocalUniformScale(float scale) override;
float GetLocalUniformScale() override;
@@ -30,7 +30,8 @@ namespace AzToolsFramework
EditorTransform()
{
m_translate = AZ::Vector3::CreateZero();
m_scale = AZ::Vector3::CreateOne();
m_legacyScale = AZ::Vector3::CreateOne();
m_uniformScale = 1.0f;
m_rotate = AZ::Vector3::CreateZero();
m_locked = false;
}
@@ -40,9 +41,10 @@ namespace AzToolsFramework
return EditorTransform();
}
AZ::Vector3 m_translate; //! Translation in engine units (meters)
AZ::Vector3 m_scale;
AZ::Vector3 m_rotate; //! Rotation in degrees
AZ::Vector3 m_translate; //!< Translation in engine units (meters)
AZ::Vector3 m_legacyScale; //!< Legacy vector scale value, retained only for migration.
float m_uniformScale; //!< Single scale value applied uniformly.
AZ::Vector3 m_rotate; //!< Rotation in degrees
bool m_locked;
};
@@ -1,82 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AzToolsFramework_precompiled.h"
#include <ToolsComponents/TransformScalePropertyHandler.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Math/Vector3.h>
namespace AzToolsFramework
{
void RegisterTransformScaleHandler()
{
PropertyTypeRegistrationMessages::Bus::Broadcast(&PropertyTypeRegistrationMessages::RegisterPropertyType, aznew Components::TransformScalePropertyHandler());
}
namespace Components
{
AZ::u32 TransformScalePropertyHandler::GetHandlerName(void) const
{
return TransformScaleHandler;
}
QWidget* TransformScalePropertyHandler::CreateGUI(QWidget* parent)
{
AzQtComponents::DoubleSpinBox* newCtrl = new AzQtComponents::DoubleSpinBox(parent);
connect(newCtrl, QOverload<double>::of(&AzQtComponents::DoubleSpinBox::valueChanged), newCtrl, [newCtrl]()
{
AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(&AzToolsFramework::PropertyEditorGUIMessages::RequestWrite, newCtrl);
});
newCtrl->setMinimum(AZ::MinTransformScale);
newCtrl->setMaximum(AZ::MaxTransformScale);
return newCtrl;
}
void TransformScalePropertyHandler::ConsumeAttribute(AzQtComponents::DoubleSpinBox* GUI, AZ::u32 attrib,
AzToolsFramework::PropertyAttributeReader* attrValue, [[maybe_unused]] const char* debugName)
{
if (attrib == AZ::Edit::Attributes::Suffix)
{
AZStd::string label;
if (attrValue->Read<AZStd::string>(label))
{
GUI->setSuffix(label.c_str());
}
}
}
void TransformScalePropertyHandler::WriteGUIValuesIntoProperty([[maybe_unused]] size_t index, AzQtComponents::DoubleSpinBox* GUI,
AZ::Vector3& instance, [[maybe_unused]] AzToolsFramework::InstanceDataNode* node)
{
const float value = aznumeric_cast<float>(GUI->value());
const float currentMaxElement = instance.GetMaxElement();
if (currentMaxElement != 0.0f)
{
instance *= value / currentMaxElement;
}
else
{
instance = AZ::Vector3(value);
}
}
bool TransformScalePropertyHandler::ReadValuesIntoGUI([[maybe_unused]] size_t index, AzQtComponents::DoubleSpinBox* GUI,
const AZ::Vector3& instance, [[maybe_unused]] AzToolsFramework::InstanceDataNode* node)
{
QSignalBlocker signalBlocker(GUI);
GUI->setValue(instance.GetMaxElement());
return true;
}
} // namespace Components
} // namespace AzToolsFramework
@@ -1,56 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include <AzQtComponents/Components/Widgets/SpinBox.h>
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
#include <AzCore/Math/Vector3.h>
#endif
namespace AzToolsFramework
{
namespace Components
{
static const AZ::Crc32 TransformScaleHandler = AZ_CRC_CE("TransformScale");
//! Handler to allow the scale field inside the Transform Component to be represented as a single value in
//! the editor, but stored internally as a Vector3.
//! The purpose for this is to prevent any new entities being created with non-uniform scale on the Transform
//! Component, but preserve the data required for migrating any existing entities to use the Non-Uniform Scale
//! Component, until all migration work is completed.
//! The value shown in the editor will be the maximum value from the scale vector, and changing the value in
//! the editor will update the vector so that its maximum value matches the newly edited value, but its
//! components retain their existing proportion.
//! For example, if the current vector scale is (2, 3, 4), the value in the editor will appear as 4. If the value
//! in the editor is updated to 2, then the vector scale will update to (1, 1.5, 2), keeping the same proportion
//! between the x, y and z components.
class TransformScalePropertyHandler
: public QObject
, public AzToolsFramework::PropertyHandler<AZ::Vector3, AzQtComponents::DoubleSpinBox>
{
Q_OBJECT //AUTOMOC
public:
AZ_CLASS_ALLOCATOR(TransformScalePropertyHandler, AZ::SystemAllocator, 0);
AZ::u32 GetHandlerName(void) const override;
QWidget* CreateGUI(QWidget* parent) override;
void ConsumeAttribute(AzQtComponents::DoubleSpinBox* GUI, AZ::u32 attrib,
AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) override;
void WriteGUIValuesIntoProperty(size_t index, AzQtComponents::DoubleSpinBox* GUI,
AZ::Vector3& instance, AzToolsFramework::InstanceDataNode* node) override;
bool ReadValuesIntoGUI(size_t index, AzQtComponents::DoubleSpinBox* GUI,
const AZ::Vector3& instance, AzToolsFramework::InstanceDataNode* node) override;
};
} // namespace Components
} // namespace AzToolsFramework
@@ -16,7 +16,6 @@
#include <AzToolsFramework/ToolsComponents/EditorEntityIdContainer.h>
#include <AzToolsFramework/UI/PropertyEditor/PropertyAudioCtrlTypes.h>
#include <AzToolsFramework/UI/PropertyEditor/GenericComboBoxCtrl.h>
#include <AzToolsFramework/ToolsComponents/TransformScalePropertyHandler.h>
namespace AzToolsFramework
{
@@ -38,7 +37,6 @@ namespace AzToolsFramework
void RegisterButtonPropertyHandlers();
void RegisterMultiLineEditHandler();
void RegisterCrcHandler();
void RegisterTransformScaleHandler();
void ReflectPropertyEditor(AZ::ReflectContext* context);
namespace Components
@@ -192,7 +190,6 @@ namespace AzToolsFramework
RegisterVectorHandlers();
RegisterButtonPropertyHandlers();
RegisterMultiLineEditHandler();
RegisterTransformScaleHandler();
// GenericComboBoxHandlers
RegisterGenericComboBoxHandler<AZ::Crc32>();
@@ -293,8 +293,6 @@ set(FILES
ToolsComponents/TransformComponent.h
ToolsComponents/TransformComponent.cpp
ToolsComponents/TransformComponentBus.h
ToolsComponents/TransformScalePropertyHandler.cpp
ToolsComponents/TransformScalePropertyHandler.h
ToolsComponents/ScriptEditorComponent.cpp
ToolsComponents/ScriptEditorComponent.h
ToolsComponents/ToolsAssetCatalogComponent.cpp
@@ -141,7 +141,7 @@ namespace UnitTest
// Set the new entity's transform to non zero values
// This helps validate in comparison tests that the transform values of created entities persist during slice operations
entityTransform->SetLocalScale(AZ::Vector3(5, 5, 5));
entityTransform->SetLocalUniformScale(5);
entityTransform->SetLocalRotation(AZ::Vector3RadToDeg(AZ::Vector3(90, 90, 90)));
entityTransform->SetLocalTranslation(AZ::Vector3(100, 100, 100));