From 56fd47f30a4fe0c4a89bedcb633d7729f992ce17 Mon Sep 17 00:00:00 2001 From: NevilClavain Date: Mon, 31 Jul 2023 21:18:53 +0200 Subject: [PATCH] for issue #80 --- drawspacecore_project/CMakeLists.txt | 5 +- src/matrix.cpp | 157 +++++++++++++++++++++++++ src/matrix.h | 170 ++------------------------- src/quaternion.cpp | 110 ++++++++++++++++- src/quaternion.h | 105 +---------------- 5 files changed, 281 insertions(+), 266 deletions(-) diff --git a/drawspacecore_project/CMakeLists.txt b/drawspacecore_project/CMakeLists.txt index 3393a5e3..d73a6c05 100644 --- a/drawspacecore_project/CMakeLists.txt +++ b/drawspacecore_project/CMakeLists.txt @@ -45,13 +45,14 @@ ${CMAKE_SOURCE_DIR}/src/ds_types.h ${CMAKE_SOURCE_DIR}/src/exceptions.h ${CMAKE_SOURCE_DIR}/src/primitives.h ${CMAKE_SOURCE_DIR}/src/singleton.h -${CMAKE_SOURCE_DIR}/src/maths.h ) source_group(maths FILES ${CMAKE_SOURCE_DIR}/src/maths.h ${CMAKE_SOURCE_DIR}/src/quaternion.h ${CMAKE_SOURCE_DIR}/src/quaternion.cpp +${CMAKE_SOURCE_DIR}/src/matrix.cpp +${CMAKE_SOURCE_DIR}/src/matrix.h ) source_group(aspect FILES @@ -219,8 +220,6 @@ ${CMAKE_SOURCE_DIR}/src/filesystem.cpp ${CMAKE_SOURCE_DIR}/src/filesystem.h ${CMAKE_SOURCE_DIR}/src/jsonparser.cpp ${CMAKE_SOURCE_DIR}/src/jsonparser.h -${CMAKE_SOURCE_DIR}/src/matrix.cpp -${CMAKE_SOURCE_DIR}/src/matrix.h ${CMAKE_SOURCE_DIR}/src/md5.h ${CMAKE_SOURCE_DIR}/src/memalloc.cpp ${CMAKE_SOURCE_DIR}/src/memalloc.h diff --git a/src/matrix.cpp b/src/matrix.cpp index bb9965f1..fb8341e2 100644 --- a/src/matrix.cpp +++ b/src/matrix.cpp @@ -31,6 +31,163 @@ Matrix::Matrix( void ) zero(); } +void Matrix::zero(void) +{ + m_matrix[0][0] = 0.0; + m_matrix[0][1] = 0.0; + m_matrix[0][2] = 0.0; + m_matrix[0][3] = 0.0; + + m_matrix[1][0] = 0.0; + m_matrix[1][1] = 0.0; + m_matrix[1][2] = 0.0; + m_matrix[1][3] = 0.0; + + m_matrix[2][0] = 0.0; + m_matrix[2][1] = 0.0; + m_matrix[2][2] = 0.0; + m_matrix[2][3] = 0.0; + + m_matrix[3][0] = 0.0; + m_matrix[3][1] = 0.0; + m_matrix[3][2] = 0.0; + m_matrix[3][3] = 0.0; + + m_configinfos.type = ConfigurationType::CONFIG_ZERO; + + m_configinfos.values[0] = 0.0; + m_configinfos.values[1] = 0.0; + m_configinfos.values[2] = 0.0; + m_configinfos.values[3] = 0.0; +} + +void Matrix::identity(void) +{ + zero(); + m_matrix[0][0] = 1.0; + m_matrix[1][1] = 1.0; + m_matrix[2][2] = 1.0; + m_matrix[3][3] = 1.0; + + m_configinfos.type = ConfigurationType::CONFIG_IDENTITY; + + m_configinfos.values[0] = 0.0; + m_configinfos.values[1] = 0.0; + m_configinfos.values[2] = 0.0; + m_configinfos.values[3] = 0.0; +} + +void Matrix::translation(dsreal p_x, dsreal p_y, dsreal p_z) +{ + identity(); + m_matrix[3][0] = p_x; + m_matrix[3][1] = p_y; + m_matrix[3][2] = p_z; + + m_configinfos.type = ConfigurationType::CONFIG_TRANSLATION; + m_configinfos.values[0] = p_x; + m_configinfos.values[1] = p_y; + m_configinfos.values[2] = p_z; + m_configinfos.values[3] = 0.0; + +} + +void Matrix::translation(const Utils::Vector& p_pos) +{ + identity(); + m_matrix[3][0] = p_pos[0]; + m_matrix[3][1] = p_pos[1]; + m_matrix[3][2] = p_pos[2]; + + m_configinfos.type = ConfigurationType::CONFIG_TRANSLATION; + m_configinfos.values[0] = p_pos[0]; + m_configinfos.values[1] = p_pos[1]; + m_configinfos.values[2] = p_pos[2]; + m_configinfos.values[3] = 0.0; + +} + +void Matrix::perspective(dsreal p_w, dsreal p_h, dsreal p_zn, dsreal p_zf) +{ + zero(); + m_matrix[0][0] = 2.0f * p_zn / p_w; + m_matrix[1][1] = 2.0f * p_zn / p_h; + m_matrix[2][2] = p_zf / (p_zf - p_zn); + m_matrix[3][2] = -p_zn * m_matrix[2][2]; + m_matrix[2][3] = 1.0f; + + m_configinfos.type = ConfigurationType::CONFIG_UNDETERMINED; +} + + +void Matrix::transpose(void) +{ + dsreal msave[4][4]; + + memcpy(&msave, m_matrix, 16 * sizeof(dsreal)); + + m_matrix[0][1] = msave[1][0]; + m_matrix[0][2] = msave[2][0]; + m_matrix[0][3] = msave[3][0]; + + m_matrix[1][0] = msave[0][1]; + + m_matrix[1][2] = msave[2][1]; + m_matrix[1][3] = msave[3][1]; + + m_matrix[2][0] = msave[0][2]; + m_matrix[2][1] = msave[1][2]; + + m_matrix[2][3] = msave[3][2]; + + m_matrix[3][0] = msave[0][3]; + m_matrix[3][1] = msave[1][3]; + m_matrix[3][2] = msave[2][3]; + + m_configinfos.type = ConfigurationType::CONFIG_UNDETERMINED; +} + +void Matrix::scale(dsreal p_sx, dsreal p_sy, dsreal p_sz) +{ + zero(); + m_matrix[0][0] = p_sx; + m_matrix[1][1] = p_sy; + m_matrix[2][2] = p_sz; + m_matrix[3][3] = 1.0; + + m_configinfos.type = ConfigurationType::CONFIG_SCALING; + m_configinfos.values[0] = p_sx; + m_configinfos.values[1] = p_sy; + m_configinfos.values[2] = p_sz; + m_configinfos.values[3] = 0.0; + +} + +void Matrix::scale(const Utils::Vector& p_pos) +{ + zero(); + m_matrix[0][0] = p_pos[0]; + m_matrix[1][1] = p_pos[1]; + m_matrix[2][2] = p_pos[2]; + m_matrix[3][3] = 1.0; + + m_configinfos.type = ConfigurationType::CONFIG_SCALING; + m_configinfos.values[0] = p_pos[0]; + m_configinfos.values[1] = p_pos[1]; + m_configinfos.values[2] = p_pos[2]; + m_configinfos.values[3] = 0.0; + +} + + +void Matrix::clearTranslation(void) +{ + m_matrix[3][0] = 0.0; + m_matrix[3][1] = 0.0; + m_matrix[3][2] = 0.0; + + m_configinfos.type = ConfigurationType::CONFIG_UNDETERMINED; +} void Matrix::inverse( void ) { diff --git a/src/matrix.h b/src/matrix.h index a982f6e3..141650a8 100644 --- a/src/matrix.h +++ b/src/matrix.h @@ -46,47 +46,17 @@ namespace DrawSpace }; - typedef struct + struct ConfigurationInfo { ConfigurationType type; Utils::Vector values; - - } ConfigurationInfo; + }; Matrix( void ); ~Matrix( void ) = default; - void zero( void ) - { - m_matrix[0][0] = 0.0; - m_matrix[0][1] = 0.0; - m_matrix[0][2] = 0.0; - m_matrix[0][3] = 0.0; - - m_matrix[1][0] = 0.0; - m_matrix[1][1] = 0.0; - m_matrix[1][2] = 0.0; - m_matrix[1][3] = 0.0; - - m_matrix[2][0] = 0.0; - m_matrix[2][1] = 0.0; - m_matrix[2][2] = 0.0; - m_matrix[2][3] = 0.0; - - m_matrix[3][0] = 0.0; - m_matrix[3][1] = 0.0; - m_matrix[3][2] = 0.0; - m_matrix[3][3] = 0.0; - - m_configinfos.type = ConfigurationType::CONFIG_ZERO; - - m_configinfos.values[0] = 0.0; - m_configinfos.values[1] = 0.0; - m_configinfos.values[2] = 0.0; - m_configinfos.values[3] = 0.0; - - } + void zero(void); dsreal operator()( int p_row, int p_col ) const { @@ -99,133 +69,15 @@ namespace DrawSpace return m_matrix[p_row][p_col]; }; - void identity( void ) - { - zero(); - m_matrix[0][0] = 1.0; - m_matrix[1][1] = 1.0; - m_matrix[2][2] = 1.0; - m_matrix[3][3] = 1.0; - - m_configinfos.type = ConfigurationType::CONFIG_IDENTITY; - - m_configinfos.values[0] = 0.0; - m_configinfos.values[1] = 0.0; - m_configinfos.values[2] = 0.0; - m_configinfos.values[3] = 0.0; - - } - - void translation( dsreal p_x, dsreal p_y, dsreal p_z ) - { - identity(); - m_matrix[3][0] = p_x; - m_matrix[3][1] = p_y; - m_matrix[3][2] = p_z; - - m_configinfos.type = ConfigurationType::CONFIG_TRANSLATION; - m_configinfos.values[0] = p_x; - m_configinfos.values[1] = p_y; - m_configinfos.values[2] = p_z; - m_configinfos.values[3] = 0.0; - - } - - void translation( const Utils::Vector& p_pos ) - { - identity(); - m_matrix[3][0] = p_pos[0]; - m_matrix[3][1] = p_pos[1]; - m_matrix[3][2] = p_pos[2]; - - m_configinfos.type = ConfigurationType::CONFIG_TRANSLATION; - m_configinfos.values[0] = p_pos[0]; - m_configinfos.values[1] = p_pos[1]; - m_configinfos.values[2] = p_pos[2]; - m_configinfos.values[3] = 0.0; - - } - - void transpose( void ) - { - dsreal msave[4][4]; - - memcpy( &msave, m_matrix, 16 * sizeof( dsreal ) ); + void identity(void); + void translation(dsreal p_x, dsreal p_y, dsreal p_z); + void translation(const Utils::Vector& p_pos); + void transpose(void); + void perspective(dsreal p_w, dsreal p_h, dsreal p_zn, dsreal p_zf); - m_matrix[0][1] = msave[1][0]; - m_matrix[0][2] = msave[2][0]; - m_matrix[0][3] = msave[3][0]; - - m_matrix[1][0] = msave[0][1]; - - m_matrix[1][2] = msave[2][1]; - m_matrix[1][3] = msave[3][1]; - - m_matrix[2][0] = msave[0][2]; - m_matrix[2][1] = msave[1][2]; - - m_matrix[2][3] = msave[3][2]; - - m_matrix[3][0] = msave[0][3]; - m_matrix[3][1] = msave[1][3]; - m_matrix[3][2] = msave[2][3]; - - m_configinfos.type = ConfigurationType::CONFIG_UNDETERMINED; - } - - void perspective( dsreal p_w, dsreal p_h, dsreal p_zn, dsreal p_zf ) - { - zero(); - m_matrix[0][0] = 2.0f * p_zn / p_w; - m_matrix[1][1] = 2.0f * p_zn / p_h; - m_matrix[2][2] = p_zf / ( p_zf - p_zn ); - m_matrix[3][2] = - p_zn * m_matrix[2][2]; - m_matrix[2][3] = 1.0f; - - m_configinfos.type = ConfigurationType::CONFIG_UNDETERMINED; - } - - void scale( dsreal p_sx, dsreal p_sy, dsreal p_sz ) - { - zero(); - m_matrix[0][0] = p_sx; - m_matrix[1][1] = p_sy; - m_matrix[2][2] = p_sz; - m_matrix[3][3] = 1.0; - - m_configinfos.type = ConfigurationType::CONFIG_SCALING; - m_configinfos.values[0] = p_sx; - m_configinfos.values[1] = p_sy; - m_configinfos.values[2] = p_sz; - m_configinfos.values[3] = 0.0; - - } - - void scale( const Utils::Vector& p_pos ) - { - zero(); - m_matrix[0][0] = p_pos[0]; - m_matrix[1][1] = p_pos[1]; - m_matrix[2][2] = p_pos[2]; - m_matrix[3][3] = 1.0; - - m_configinfos.type = ConfigurationType::CONFIG_SCALING; - m_configinfos.values[0] = p_pos[0]; - m_configinfos.values[1] = p_pos[1]; - m_configinfos.values[2] = p_pos[2]; - m_configinfos.values[3] = 0.0; - - } - - - void clearTranslation( void ) - { - m_matrix[3][0] = 0.0; - m_matrix[3][1] = 0.0; - m_matrix[3][2] = 0.0; - - m_configinfos.type = ConfigurationType::CONFIG_UNDETERMINED; - } + void scale(dsreal p_sx, dsreal p_sy, dsreal p_sz); + void scale(const Utils::Vector& p_pos); + void clearTranslation(void); void rotation( const Utils::Vector& p_axis, dsreal p_angle ); void inverse( void ); diff --git a/src/quaternion.cpp b/src/quaternion.cpp index 307a7369..7e182165 100644 --- a/src/quaternion.cpp +++ b/src/quaternion.cpp @@ -39,19 +39,119 @@ Quaternion::Quaternion(dsreal p_x, dsreal p_y, dsreal p_z, dsreal p_w) m_quat[3] = p_w; } +void Quaternion::zero(void) +{ + m_quat[0] = m_quat[1] = m_quat[2] = m_quat[3] = 0.0; +}; + +void Quaternion::identity(void) +{ + m_quat[0] = 0.0; + m_quat[1] = 0.0; + m_quat[2] = 0.0; + m_quat[3] = 1.0; +}; + +// https://stackoverflow.com/questions/12435671/quaternion-lookat-function + +void Quaternion::lookAt(const Vector& p_source, const Vector& p_dest) +{ + Vector forwardVector(p_dest[0] - p_source[0], + p_dest[1] - p_source[1], + p_dest[2] - p_source[2], + 0.0); + + forwardVector.Normalize(); + Vector forward(0.0, 0.0, -1.0, 0.0); + + const auto dot{ forward * forwardVector }; + + if (Maths::abs(dot - (-1.0)) < 0.000001) + { + m_quat[0] = 0.0; + m_quat[1] = 1.0; + m_quat[2] = 0.0; + m_quat[3] = Maths::pi; + } + else if (Maths::abs(dot - (1.0)) < 0.000001) + { + identity(); + } + else + { + const auto rotAngle{ std::acos(dot) }; + auto rotAxis{ ProdVec(forward, forwardVector) }; + rotAxis.Normalize(); + + rotationAxis(rotAxis, rotAngle); + } +} + +void Quaternion::rotationAxis(Vector& p_axis, dsreal p_angle) +{ + p_axis.Normalize(); + + const auto sin_a{ std::sin(p_angle / 2.0) }; + + m_quat[0] = p_axis[0] * sin_a; + m_quat[1] = p_axis[1] * sin_a; + m_quat[2] = p_axis[2] * sin_a; + m_quat[3] = std::cos(p_angle / 2.0); +}; + +void Quaternion::rotationMatFrom(Matrix& p_mat) const +{ + const auto xx{ m_quat[0] * m_quat[0] }; + const auto xy{ m_quat[0] * m_quat[1] }; + const auto xz{ m_quat[0] * m_quat[2] }; + const auto xw{ m_quat[0] * m_quat[3] }; + const auto yy{ m_quat[1] * m_quat[1] }; + const auto yz{ m_quat[1] * m_quat[2] }; + const auto yw{ m_quat[1] * m_quat[3] }; + const auto zz{ m_quat[2] * m_quat[2] }; + const auto zw{ m_quat[2] * m_quat[3] }; + + p_mat(0, 0) = 1 - 2 * (yy + zz); + p_mat(1, 0) = 2 * (xy - zw); + p_mat(2, 0) = 2 * (xz + yw); + p_mat(0, 1) = 2 * (xy + zw); + p_mat(1, 1) = 1 - 2 * (xx + zz); + p_mat(2, 1) = 2 * (yz - xw); + p_mat(0, 2) = 2 * (xz - yw); + p_mat(1, 2) = 2 * (yz + xw); + p_mat(2, 2) = 1 - 2 * (xx + yy); + p_mat(3, 0) = p_mat(3, 1) = p_mat(3, 2) = p_mat(0, 3) = p_mat(1, 3) = p_mat(2, 3) = 0; + p_mat(3, 3) = 1; +}; + +void Quaternion::normalize(void) +{ + const auto a{ m_quat[0] }; + const auto b{ m_quat[1] }; + const auto c{ m_quat[2] }; + const auto d{ m_quat[3] }; + + const auto n{ std::sqrt(a * a + b * b + c * c + d * d) }; + + m_quat[0] = a / n; + m_quat[1] = b / n; + m_quat[2] = c / n; + m_quat[3] = d / n; +} + Quaternion Quaternion::lerp(const Quaternion& p_q1, const Quaternion& p_q2, dsreal p_blend) { - Quaternion q1 = p_q1; - Quaternion q2 = p_q2; + auto q1{ p_q1 }; + auto q2 = p_q2; Quaternion result; q1.normalize(); q2.normalize(); - dsreal dot_product = p_q1[0] * p_q2[0] + p_q1[1] * p_q2[1] + p_q1[2] * p_q2[2] + p_q1[3] * p_q2[3]; - dsreal one_minus_blend = 1.0 - p_blend; + const auto dot_product{ p_q1[0] * p_q2[0] + p_q1[1] * p_q2[1] + p_q1[2] * p_q2[2] + p_q1[3] * p_q2[3] }; + const auto one_minus_blend{ 1.0 - p_blend }; - dsreal sign = dot_product < 0.0 ? -1.0 : 1.0; + const auto sign{ dot_product < 0.0 ? -1.0 : 1.0 }; result[0] = p_q1[0] * one_minus_blend + p_blend * sign * p_q2[0]; result[1] = p_q1[1] * one_minus_blend + p_blend * sign * p_q2[1]; diff --git a/src/quaternion.h b/src/quaternion.h index 8bcb7fc1..25096fea 100644 --- a/src/quaternion.h +++ b/src/quaternion.h @@ -50,105 +50,12 @@ namespace DrawSpace return m_quat[p_index]; }; - void zero( void ) - { - m_quat[0] = m_quat[1] = m_quat[2] = m_quat[3] = 0.0; - }; - - void identity( void ) - { - m_quat[0] = 0.0; - m_quat[1] = 0.0; - m_quat[2] = 0.0; - m_quat[3] = 1.0; - }; - - // https://stackoverflow.com/questions/12435671/quaternion-lookat-function - - void lookAt(const Vector& p_source, const Vector& p_dest) - { - Vector forwardVector(p_dest[0] - p_source[0], - p_dest[1] - p_source[1], - p_dest[2] - p_source[2], - 0.0); - - forwardVector.Normalize(); - Vector forward(0.0, 0.0, -1.0, 0.0); - - const auto dot{ forward * forwardVector }; - - if (Maths::abs(dot - (-1.0)) < 0.000001) - { - m_quat[0] = 0.0; - m_quat[1] = 1.0; - m_quat[2] = 0.0; - m_quat[3] = Maths::pi; - } - else if (Maths::abs(dot - (1.0)) < 0.000001) - { - identity(); - } - else - { - const auto rotAngle{ std::acos(dot) }; - auto rotAxis{ ProdVec(forward, forwardVector) }; - rotAxis.Normalize(); - - rotationAxis(rotAxis, rotAngle); - } - } - - void rotationAxis( Vector& p_axis, dsreal p_angle ) - { - p_axis.Normalize(); - - const auto sin_a{ std::sin(p_angle / 2.0) }; - - m_quat[0] = p_axis[0] * sin_a; - m_quat[1] = p_axis[1] * sin_a; - m_quat[2] = p_axis[2] * sin_a; - m_quat[3] = std::cos( p_angle / 2.0 ); - }; - - void rotationMatFrom( Matrix& p_mat ) const - { - const auto xx{ m_quat[0] * m_quat[0] }; - const auto xy{ m_quat[0] * m_quat[1] }; - const auto xz{ m_quat[0] * m_quat[2] }; - const auto xw{ m_quat[0] * m_quat[3] }; - const auto yy{ m_quat[1] * m_quat[1] }; - const auto yz{ m_quat[1] * m_quat[2] }; - const auto yw{ m_quat[1] * m_quat[3] }; - const auto zz{ m_quat[2] * m_quat[2] }; - const auto zw{ m_quat[2] * m_quat[3] }; - - p_mat( 0, 0 ) = 1 - 2 * ( yy + zz ); - p_mat( 1, 0 ) = 2 * ( xy - zw ); - p_mat( 2, 0 ) = 2 * ( xz + yw ); - p_mat( 0, 1 ) = 2 * ( xy + zw ); - p_mat( 1, 1 ) = 1 - 2 * ( xx + zz ); - p_mat( 2, 1 ) = 2 * ( yz - xw ); - p_mat( 0, 2 ) = 2 * ( xz - yw ); - p_mat( 1, 2 ) = 2 * ( yz + xw ); - p_mat( 2, 2 ) = 1 - 2 * ( xx + yy ); - p_mat( 3, 0 ) = p_mat( 3, 1 ) = p_mat( 3, 2 ) = p_mat( 0, 3 ) = p_mat( 1, 3 ) = p_mat( 2, 3 ) = 0; - p_mat( 3, 3 ) = 1; - }; - - void normalize(void) - { - const auto a{ m_quat[0] }; - const auto b{ m_quat[1] }; - const auto c{ m_quat[2] }; - const auto d{ m_quat[3] }; - - const auto n{ std::sqrt(a * a + b * b + c * c + d * d) }; - - m_quat[0] = a / n; - m_quat[1] = b / n; - m_quat[2] = c / n; - m_quat[3] = d / n; - } + void zero(void); + void identity(void); + void lookAt(const Vector& p_source, const Vector& p_dest); + void rotationAxis(Vector& p_axis, dsreal p_angle); + void rotationMatFrom(Matrix& p_mat) const; + void normalize(void); static Quaternion lerp(const Quaternion& p_q1, const Quaternion& p_q2, dsreal p_blend);