From 17699ce1b12e8fe872d1230992672ecdd5e84573 Mon Sep 17 00:00:00 2001 From: Harrand Date: Sun, 20 Oct 2024 23:59:31 +0100 Subject: [PATCH] [core.trs] added trs library, note that rotations are not yet implemented coz quaternions dont exist yet --- CMakeLists.txt | 1 + include/tz/core/matrix.hpp | 6 +++- include/tz/core/trs.hpp | 25 ++++++++++++++ include/tz/core/vector.hpp | 8 ++--- src/tz/core/trs.cpp | 67 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 include/tz/core/trs.hpp create mode 100644 src/tz/core/trs.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c7e72fd664..4fc4ee41d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,7 @@ topaz_add_library( src/tz/core/job.cpp src/tz/core/vector.cpp src/tz/core/matrix.cpp + src/tz/core/trs.cpp src/tz/gpu/rhi_vulkan.cpp src/tz/os/impl_win32.cpp ) diff --git a/include/tz/core/matrix.hpp b/include/tz/core/matrix.hpp index ede91ff334..86d6456ae7 100644 --- a/include/tz/core/matrix.hpp +++ b/include/tz/core/matrix.hpp @@ -48,13 +48,17 @@ namespace tz // matrix-scalar matrix& operator+=(T scalar); + matrix operator+(T scalar) const{auto cpy = *this; return cpy += scalar;} matrix& operator-=(T scalar); + matrix operator-(T scalar) const{auto cpy = *this; return cpy -= scalar;} matrix& operator*=(T scalar); + matrix operator*(T scalar) const{auto cpy = *this; return cpy *= scalar;} matrix& operator/=(T scalar); + matrix operator/(T scalar) const{auto cpy = *this; return cpy /= scalar;} // matrix-matrix matrix& operator*=(const matrix& rhs); - matrix operator*(const matrix& rhs){auto cpy = *this; return cpy *= rhs;} + matrix operator*(const matrix& rhs) const{auto cpy = *this; return cpy *= rhs;} bool operator==(const matrix& rhs) const = default; diff --git a/include/tz/core/trs.hpp b/include/tz/core/trs.hpp new file mode 100644 index 0000000000..73f80d8da8 --- /dev/null +++ b/include/tz/core/trs.hpp @@ -0,0 +1,25 @@ +#ifndef TOPAZ_CORE_TRS_HPP +#define TOPAZ_CORE_TRS_HPP +#include "tz/core/vector.hpp" +#include "tz/core/matrix.hpp" + +namespace tz +{ + struct trs + { + tz::v3f translate = tz::v3f::zero(); + // tz::quat rotate = tz::quat::iden(); + tz::v3f scale = tz::v3f::filled(1.0f); + + trs lerp(const trs& rhs, float factor) const; + m4u matrix() const; + static trs from_matrix(m4f mat); + + trs inverse() const; + trs combine(const trs& rhs); + + bool operator==(const trs& rhs) const = default; + }; +} + +#endif // TOPAZ_CORE_TRS_HPP \ No newline at end of file diff --git a/include/tz/core/vector.hpp b/include/tz/core/vector.hpp index f91a006422..8b3823aa11 100644 --- a/include/tz/core/vector.hpp +++ b/include/tz/core/vector.hpp @@ -63,10 +63,10 @@ namespace tz vector& operator*=(const vector& rhs); vector& operator/=(const vector& rhs); - vector operator+(const vector& rhs){auto cpy = *this; return cpy += rhs;} - vector operator-(const vector& rhs){auto cpy = *this; return cpy -= rhs;} - vector operator*(const vector& rhs){auto cpy = *this; return cpy *= rhs;} - vector operator/(const vector& rhs){auto cpy = *this; return cpy /= rhs;} + vector operator+(const vector& rhs) const{auto cpy = *this; return cpy += rhs;} + vector operator-(const vector& rhs) const{auto cpy = *this; return cpy -= rhs;} + vector operator*(const vector& rhs) const{auto cpy = *this; return cpy *= rhs;} + vector operator/(const vector& rhs) const{auto cpy = *this; return cpy /= rhs;} bool operator==(const vector& rhs) const = default; private: diff --git a/src/tz/core/trs.cpp b/src/tz/core/trs.cpp new file mode 100644 index 0000000000..0df4d994cf --- /dev/null +++ b/src/tz/core/trs.cpp @@ -0,0 +1,67 @@ +#include "tz/core/trs.hpp" +#include "tz/topaz.hpp" + +namespace tz +{ + trs trs::lerp(const trs& rhs, float factor) const + { + trs ret; + ret.translate = this->translate + (rhs.translate - this->translate) * factor; + //ret.rotate = this->rotate.slerp(rhs.rotate, factor); + ret.scale = this->scale + ((rhs.scale - this->scale) * factor); + return ret; + } + + tz::m4u trs::matrix() const + { + tz_error("trs -> matrix is NYI"); + return {}; + } + + trs trs::from_matrix(tz::m4f mat) + { + // decompose matrix -> trs using:https://github.com/KhronosGroup/glTF-Validator/issues/33 + //If M[3] != 0.0 || M[7] != 0.0 || M[11] != 0.0 || M[15] != 1.0, + // matrix is indecomposable, exit. + + /* + 0 4 8 12 + 1 5 9 13 + 2 6 10 14 + 3 7 11 15 + */ + trs ret; + ret.translate = {mat(3, 0), mat(3, 1), mat(3, 2)}; + ret.scale[0] = std::sqrt(mat(0, 0) * mat(0, 0) + mat(1, 0) * mat(1, 0) + mat(2, 0) * mat(2, 0)); + ret.scale[1] = std::sqrt(mat(0, 1) * mat(0, 1) + mat(1, 1) * mat(1, 1) + mat(2, 1) * mat(2, 1)); + ret.scale[2] = std::sqrt(mat(0, 2) * mat(0, 2) + mat(1, 2) * mat(1, 2) + mat(2, 2) * mat(2, 2)); + + float isx = 1.0f / ret.scale[0]; + float isy = 1.0f / ret.scale[1]; + float isz = 1.0f / ret.scale[2]; + + // remove scaling from matrix + mat(0, 0) *= isx; mat(1, 0) *= isx; mat(1, 0) *= isx; + mat(0, 1) *= isy; mat(1, 1) *= isy; mat(2, 1) *= isy; + mat(0, 2) *= isz; mat(1, 2) *= isz; mat(2, 2) *= isz; + + // Construct the quaternion. This algo is copied from here: + // https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/christian.htm. + /* + ret.rotate[3] = std::max(0.0f, 1.0f + mat(0, 0) + mat(1, 1) + mat(2, 2)); + ret.rotate[0] = std::max(0.0f, 1.0f + mat(0, 0) - mat(1, 1) - mat(2, 2)); + ret.rotate[1] = std::max(0.0f, 1.0f - mat(0, 0) + mat(1, 1) - mat(2, 2)); + ret.rotate[2] = std::max(0.0f, 1.0f - mat(0, 0) - mat(1, 1) - mat(2, 2)); + for(std::size_t i = 0; i < 4; i++) + { + ret.rotate[i] = std::sqrt(ret.rotate[i] * 0.5f); + } + ret.rotate[0] = std::copysignf(ret.rotate[0], mat(1, 2) - mat(2, 1)); + ret.rotate[1] = std::copysignf(ret.rotate[1], mat(2, 0) - mat(0, 2)); + ret.rotate[2] = std::copysignf(ret.rotate[2], mat(0, 1) - mat(1, 0)); + */ + return ret; + } + + +} \ No newline at end of file