From 6469ab5fde891327a6e0d179edb051f6c4992eeb Mon Sep 17 00:00:00 2001 From: SirLynix Date: Thu, 12 May 2022 18:15:20 +0200 Subject: [PATCH] Utility: Refactor some algorithms --- include/Nazara/Math/Quaternion.hpp | 1 + include/Nazara/Math/Quaternion.inl | 14 +++++++ include/Nazara/Utility/Algorithm.hpp | 8 +++- include/Nazara/Utility/Algorithm.inl | 53 +++++++++++++++++++++++++ include/Nazara/Utility/Node.hpp | 2 - src/Nazara/Utility/AlgorithmUtility.cpp | 28 ------------- src/Nazara/Utility/Node.cpp | 32 +++------------ 7 files changed, 80 insertions(+), 58 deletions(-) diff --git a/include/Nazara/Math/Quaternion.hpp b/include/Nazara/Math/Quaternion.hpp index a50a1bc27..e24662208 100644 --- a/include/Nazara/Math/Quaternion.hpp +++ b/include/Nazara/Math/Quaternion.hpp @@ -86,6 +86,7 @@ namespace Nz static Quaternion LookAt(const Vector3& forward, const Vector3& up); static Quaternion Normalize(const Quaternion& quat, T* length = nullptr); static Quaternion RotationBetween(const Vector3& from, const Vector3& to); + static Quaternion Mirror(Quaternion quat, const Vector3& axis); static Quaternion Slerp(const Quaternion& from, const Quaternion& to, T interpolation); static Quaternion Zero(); diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index 27f6d8d2a..de239bf5b 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -787,6 +787,20 @@ namespace Nz return quaternion; } + template + Quaternion Quaternion::Mirror(Quaternion quat, const Vector3& axis) + { + float x = std::copysign(T(1.0), axis.x); + float y = std::copysign(T(1.0), axis.y); + float z = std::copysign(T(1.0), axis.z); + + quat.x = y * z * quat.x; + quat.y = x * z * quat.y; + quat.z = x * y * quat.z; + + return quat; + } + /*! * \brief Interpolates spherically the quaternion to other one with a factor of interpolation * \return A new quaternion which is the interpolation of two quaternions diff --git a/include/Nazara/Utility/Algorithm.hpp b/include/Nazara/Utility/Algorithm.hpp index 5745b31f1..459e677c6 100644 --- a/include/Nazara/Utility/Algorithm.hpp +++ b/include/Nazara/Utility/Algorithm.hpp @@ -64,11 +64,17 @@ namespace Nz NAZARA_UTILITY_API void SkinPositionNormal(const SkinningData& data, UInt64 startVertex, UInt64 vertexCount); NAZARA_UTILITY_API void SkinPositionNormalTangent(const SkinningData& data, UInt64 startVertex, UInt64 vertexCount); - NAZARA_UTILITY_API void TransformVertices(VertexPointers vertexPointers, UInt64 vertexCount, const Matrix4f& matrix); + inline Vector3f TransformPositionTRS(const Vector3f& transformTranslation, const Quaternionf& transformRotation, const Vector3f& transformScale, const Vector3f& position); + inline Vector3f TransformNormalTRS(const Quaternionf& transformRotation, const Vector3f& transformScale, const Vector3f& normal); + inline Quaternionf TransformRotationTRS(const Quaternionf& transformRotation, const Vector3f& transformScale, const Quaternionf& rotation); + inline Vector3f TransformScaleTRS(const Vector3f& transformScale, const Vector3f& scale); + inline void TransformTRS(const Vector3f& transformTranslation, const Quaternionf& transformRotation, const Vector3f& transformScale, Vector3f& position, Quaternionf& rotation, Vector3f& scale); + inline void TransformVertices(VertexPointers vertexPointers, UInt64 vertexCount, const Matrix4f& matrix); template constexpr ComponentType ComponentTypeId(); template constexpr ComponentType GetComponentTypeOf(); } + #include #endif // NAZARA_UTILITY_ALGORITHM_HPP diff --git a/include/Nazara/Utility/Algorithm.inl b/include/Nazara/Utility/Algorithm.inl index 4804a9808..896b23d50 100644 --- a/include/Nazara/Utility/Algorithm.inl +++ b/include/Nazara/Utility/Algorithm.inl @@ -8,6 +8,59 @@ namespace Nz { + inline Vector3f TransformPositionTRS(const Vector3f& transformTranslation, const Quaternionf& transformRotation, const Vector3f& transformScale, const Vector3f& position) + { + return transformRotation * (transformScale * position) + transformTranslation; + } + + Vector3f TransformNormalTRS(const Quaternionf& transformRotation, const Vector3f& transformScale, const Vector3f& normal) + { + return Quaternionf::Mirror(transformRotation, transformScale) * normal; + } + + inline Quaternionf TransformRotationTRS(const Quaternionf& transformRotation, const Vector3f& transformScale, const Quaternionf& rotation) + { + return Quaternionf::Mirror(transformRotation, transformScale) * rotation; + } + + inline Vector3f TransformScaleTRS(const Vector3f& transformScale, const Vector3f& scale) + { + return transformScale * scale; + } + + inline void TransformTRS(const Vector3f& transformTranslation, const Quaternionf& transformRotation, const Vector3f& transformScale, Vector3f& position, Quaternionf& rotation, Vector3f& scale) + { + position = TransformPositionTRS(transformTranslation, transformRotation, transformScale, position); + rotation = TransformRotationTRS(transformRotation, transformScale, rotation); + scale = TransformScaleTRS(transformScale, scale); + } + + inline void TransformVertices(VertexPointers vertexPointers, UInt64 vertexCount, const Matrix4f& matrix) + { + if (vertexPointers.positionPtr) + { + for (UInt64 i = 0; i < vertexCount; ++i) + *vertexPointers.positionPtr++ = matrix.Transform(*vertexPointers.positionPtr); + } + + if (vertexPointers.normalPtr || vertexPointers.tangentPtr) + { + Vector3f scale = matrix.GetScale(); + + if (vertexPointers.normalPtr) + { + for (UInt64 i = 0; i < vertexCount; ++i) + *vertexPointers.normalPtr++ = matrix.Transform(*vertexPointers.normalPtr, 0.f) / scale; + } + + if (vertexPointers.tangentPtr) + { + for (UInt64 i = 0; i < vertexCount; ++i) + *vertexPointers.tangentPtr++ = matrix.Transform(*vertexPointers.tangentPtr, 0.f) / scale; + } + } + } + template constexpr ComponentType ComponentTypeId() { static_assert(AlwaysFalse::value, "This type cannot be used as a component."); diff --git a/include/Nazara/Utility/Node.hpp b/include/Nazara/Utility/Node.hpp index 9a380a07a..bbeeea820 100644 --- a/include/Nazara/Utility/Node.hpp +++ b/include/Nazara/Utility/Node.hpp @@ -108,8 +108,6 @@ namespace Nz virtual void UpdateDerived() const; virtual void UpdateTransformMatrix() const; - static Quaternionf ScaleQuaternion(const Vector3f& scale, Quaternionf quaternion); - mutable std::vector m_childs; mutable Matrix4f m_transformMatrix; mutable Quaternionf m_derivedRotation; diff --git a/src/Nazara/Utility/AlgorithmUtility.cpp b/src/Nazara/Utility/AlgorithmUtility.cpp index fc96a25f0..c76309014 100644 --- a/src/Nazara/Utility/AlgorithmUtility.cpp +++ b/src/Nazara/Utility/AlgorithmUtility.cpp @@ -1156,32 +1156,4 @@ namespace Nz outputVertex++; } } - - /*********************************Transform*********************************/ - - void TransformVertices(VertexPointers vertexPointers, UInt64 vertexCount, const Matrix4f& matrix) - { - if (vertexPointers.positionPtr) - { - for (UInt64 i = 0; i < vertexCount; ++i) - *vertexPointers.positionPtr++ = matrix.Transform(*vertexPointers.positionPtr); - } - - if (vertexPointers.normalPtr || vertexPointers.tangentPtr) - { - Vector3f scale = matrix.GetScale(); - - if (vertexPointers.normalPtr) - { - for (UInt64 i = 0; i < vertexCount; ++i) - *vertexPointers.normalPtr++ = matrix.Transform(*vertexPointers.normalPtr, 0.f) / scale; - } - - if (vertexPointers.tangentPtr) - { - for (UInt64 i = 0; i < vertexCount; ++i) - *vertexPointers.tangentPtr++ = matrix.Transform(*vertexPointers.tangentPtr, 0.f) / scale; - } - } - } } diff --git a/src/Nazara/Utility/Node.cpp b/src/Nazara/Utility/Node.cpp index 751d9e786..83519db66 100644 --- a/src/Nazara/Utility/Node.cpp +++ b/src/Nazara/Utility/Node.cpp @@ -4,6 +4,7 @@ #include #include +#include #include namespace Nz @@ -610,7 +611,7 @@ namespace Nz if (!m_derivedUpdated) UpdateDerived(); - return m_derivedPosition + (m_derivedScale * (ScaleQuaternion(m_derivedScale, m_derivedRotation) * localPosition)); + return TransformPositionTRS(m_derivedPosition, m_derivedRotation, m_derivedScale, localPosition); } Quaternionf Node::ToGlobalRotation(const Quaternionf& localRotation) const @@ -618,7 +619,7 @@ namespace Nz if (!m_derivedUpdated) UpdateDerived(); - return ScaleQuaternion(m_derivedScale, m_derivedRotation) * localRotation; + return TransformRotationTRS(m_derivedRotation, m_derivedScale, localRotation); } Vector3f Node::ToGlobalScale(const Vector3f& localScale) const @@ -626,7 +627,7 @@ namespace Nz if (!m_derivedUpdated) UpdateDerived(); - return m_derivedScale * localScale; + return TransformScaleTRS(m_derivedScale, localScale); } Vector3f Node::ToLocalPosition(const Vector3f& globalPosition) const @@ -762,7 +763,7 @@ namespace Nz { Quaternionf rotation = m_initialRotation * m_rotation; if (m_inheritScale) - rotation = ScaleQuaternion(m_parent->m_derivedScale, rotation); + rotation = Quaternionf::Mirror(rotation, m_parent->m_derivedScale); m_derivedRotation = m_parent->m_derivedRotation * rotation; m_derivedRotation.Normalize(); @@ -792,27 +793,4 @@ namespace Nz m_transformMatrix.MakeTransform(m_derivedPosition, m_derivedRotation, m_derivedScale); m_transformMatrixUpdated = true; } - - Quaternionf Node::ScaleQuaternion(const Vector3f& scale, Quaternionf quaternion) - { - if (std::signbit(scale.x)) - { - quaternion.z = -quaternion.z; - quaternion.y = -quaternion.y; - } - - if (std::signbit(scale.y)) - { - quaternion.x = -quaternion.x; - quaternion.z = -quaternion.z; - } - - if (std::signbit(scale.z)) - { - quaternion.x = -quaternion.x; - quaternion.y = -quaternion.y; - } - - return quaternion; - } }