From 830b63cf887f3c9804b78bf04d75d1761ffba582 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Tue, 22 Jan 2019 09:06:22 +0100 Subject: [PATCH] still not there yet --- TODO.md | 4 + src/core/CMakeLists.txt | 15 +- src/core/include/pw/core/matrix.hpp | 130 ++++---- src/core/include/pw/core/matrixbase.hpp | 10 + src/core/include/pw/core/quaternion.hpp | 379 ++++++++++++---------- src/core/include/pw/core/serialize.hpp | 8 +- src/core/include/pw/core/size.hpp | 2 - src/core/include/pw/core/vector.hpp | 59 ++-- src/core/tests/CMakeLists.txt | 30 +- src/core/tests/pwcore_test_axisangle.cpp | 7 +- src/core/tests/pwcore_test_matrix.cpp | 41 +-- src/core/tests/pwcore_test_quaternion.cpp | 6 +- src/core/tests/pwcore_test_vector.cpp | 34 +- 13 files changed, 369 insertions(+), 356 deletions(-) diff --git a/TODO.md b/TODO.md index 19a9da6..9b6f83b 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,7 @@ # core * rewrite matrix and associated code +* rename rect to rectangle # scripting @@ -8,5 +9,8 @@ * refactor script into something like a runtime - script +# scene + +* add_child and add_component should have guards - use std::lock_guard diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index cafc464..a06fc56 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -19,24 +19,28 @@ set(hdrs include/pw/core/image.hpp ) +set(misc + ${CMAKE_SOURCE_DIR}/README.md + ${CMAKE_SOURCE_DIR}/LICENSE + ${CMAKE_SOURCE_DIR}/TODO.md + ) + set(srcs # src/buffer.cpp src/image.cpp src/debug.cpp - src/mesh.cpp +# src/mesh.cpp src/core.cpp src/serialize.cpp src/timer.cpp src/image.cpp - ${CMAKE_SOURCE_DIR}/README.md - ${CMAKE_SOURCE_DIR}/LICENSE - ${CMAKE_SOURCE_DIR}/TODO.md ) add_library(pwcore STATIC ${hdrs} ${srcs} + ${misc} ) target_include_directories( @@ -47,8 +51,5 @@ target_include_directories( target_link_libraries(pwcore) - - -#add_subdirectory(src) add_subdirectory(tests) diff --git a/src/core/include/pw/core/matrix.hpp b/src/core/include/pw/core/matrix.hpp index 029397a..e532f95 100644 --- a/src/core/include/pw/core/matrix.hpp +++ b/src/core/include/pw/core/matrix.hpp @@ -24,48 +24,39 @@ #define PW_CORE_MATRIX_HPP #include -#include #include +#include #include namespace pw { -template -struct matrixtraits_ + +template +struct matrix_ : matrixbase_> { - //! rows - inline std::size_t rows() const { return R; } - - //! return number of columns - inline std::size_t cols() const { return C; } -}; - -template -struct matrix_ : matrixbase_>,matrixtraits_ -{ - T data[R*C]; -// typedef matrixbase_> Base; - using matrixbase_>::matrixbase_; - using matrixtraits_::rows; - using matrixtraits_::cols; + using matrixbase_>::matrixbase_; + static const std::size_t rows = R; + static const std::size_t cols = C; + + typedef matrix_ col_type; + typedef matrix_<1,C,T> row_type; matrix_(const matrix_& other) { *this = other; } - explicit matrix_(std::initializer_list args) { typename std::initializer_list::iterator it = args.begin(); for (;it != args.end();it++) data[it-args.begin()] = *it; } - matrix_& operator = (const matrix_& other) + matrix_& operator = (const matrix_& other) { for (size_t i = 0; i < other.size();i++) (*this)[i] = other[i]; return *this; @@ -100,16 +91,16 @@ struct matrix_ : matrixbase_>,matrixtraits_ //! set identity inline matrix_& set_identity() { - for (unsigned int r = 0;r < rows(); r++) - for (unsigned int c = 0; c < cols(); c++) + for (std::size_t r = 0;r < rows; r++) + for (std::size_t c = 0; c < cols; c++) (*this)(r,c) = (c == r) ? T(1) : T(0); return *this; } template - matrix_ slice(std::size_t r,std::size_t c) const + auto slice(std::size_t r,std::size_t c) const { - matrix_ s; + matrix_ s; for (std::size_t ri = 0;ri < Rs;ri++) for (std::size_t ci = 0;ci < Cs;ci++) s(ri,ci) = (*this)(ri+r,ci+c); @@ -117,7 +108,7 @@ struct matrix_ : matrixbase_>,matrixtraits_ } template - matrix_& set_slice(const matrix_& s,std::size_t r,std::size_t c) + matrix_& set_slice(const matrix_& s,std::size_t r,std::size_t c) { for (std::size_t ri = 0;ri < Rs;ri++) for (std::size_t ci = 0;ci < Cs;ci++) @@ -127,9 +118,9 @@ struct matrix_ : matrixbase_>,matrixtraits_ template - matrix_ minor(std::size_t r0,std::size_t c0) const + auto minor(std::size_t r0,std::size_t c0) const { - matrix_ m; + matrix_ m; size_t r = 0; for (size_t ri = 0; ri < R; ri++) { size_t c = 0; @@ -155,17 +146,17 @@ struct matrix_ : matrixbase_>,matrixtraits_ return det; } - matrix_ transposed() const { - matrix_ res; - for (size_t r = this->rows();r-->0;) - for (size_t c = this->cols();c-->0;) + auto transposed() const { + matrix_ res; + for (size_t r = rows;r-->0;) + for (size_t c = cols;c-->0;) res(c,r) = (*this)(r,c); return res; } - matrix_ inverse() const { + auto inverse() const { T invDet = T(1) / this->determinant(); - matrix_ inv; + matrix_ inv; for (int j = 0; j < C; j++) for (int i = 0; i < R; i++) { @@ -199,16 +190,21 @@ struct matrix_ : matrixbase_>,matrixtraits_ return res; } + row_type row(size_t row_) const { + row_type r; for (size_t i = 0; i < cols; i++) r[i] = (*this)(row_,i); return r; + } + + }; template <> inline -float matrix_::determinant() const +float matrix_<1,1,float>::determinant() const { return (*this)(0,0); } template <> inline -double matrix_::determinant() const +double matrix_<1,1,double>::determinant() const { return (*this)(0,0); } @@ -216,11 +212,11 @@ double matrix_::determinant() const template -auto operator * (const matrix_& A, - const matrix_& B +auto operator * (const matrix_& A, + const matrix_& B ) { - matrix_ result; result.zero(); // zero the output + matrix_ result; result.zero(); // zero the output for (size_t r = 0; r < R; r++) for (size_t c = 0; c < Cb; c++) for (size_t iI = 0; iI < R; iI++) @@ -234,49 +230,49 @@ auto operator * (const matrix_& A, // -template using matrix2x2_ = matrix_; -template using matrix3x3_ = matrix_; -template using matrix4x4_ = matrix_; +template using matrix2x2_ = matrix_<2, 2, T>; +//template using matrix3x3_ = matrix_; +//template using matrix4x4_ = matrix_; -using matrix2x2f = matrix_; -using matrix2x2d = matrix_; -using matrix2x2 = matrix_; +using matrix2x2f = matrix_<2, 2,float>; +using matrix2x2d = matrix_<2, 2,double>; +using matrix2x2 = matrix_<2, 2,real_t>; -using matrix3x3f = matrix_; -using matrix3x3d = matrix_; -using matrix3x3 = matrix_; +//using matrix3x3f = matrix_; +//using matrix3x3d = matrix_; +//using matrix3x3 = matrix_; -using matrix4x4f = matrix_; -using matrix4x4d = matrix_; -using matrix4x4 = matrix_; +//using matrix4x4f = matrix_; +//using matrix4x4d = matrix_; +//using matrix4x4 = matrix_; // // // -template -struct matrix_tools { +//template +//struct matrix_tools { - inline static - matrix4x4_ projection_from_frustum(T Left,T Right,T Bottom,T Top,T zNear,T zFar) - { - matrix4x4_ frustum; +// inline static +// matrix4x4_ projection_from_frustum(T Left,T Right,T Bottom,T Top,T zNear,T zFar) +// { +// matrix4x4_ frustum; - frustum.fill(0); +// frustum.fill(0); - frustum(0,0) = T(2) * zNear/(Right-Left); - frustum(1,1) = T(2) * zNear/(Top-Bottom); +// frustum(0,0) = T(2) * zNear/(Right-Left); +// frustum(1,1) = T(2) * zNear/(Top-Bottom); - frustum(0,2) = (Right+Left)/(Right-Left); //A - frustum(1,2) = (Top+Bottom)/(Top-Bottom); //B - frustum(2,2) = - (zFar+zNear)/(zFar-zNear); //C - frustum(3,2) = -(T(2) * zFar*zNear)/(zFar-zNear); //D +// frustum(0,2) = (Right+Left)/(Right-Left); //A +// frustum(1,2) = (Top+Bottom)/(Top-Bottom); //B +// frustum(2,2) = - (zFar+zNear)/(zFar-zNear); //C +// frustum(3,2) = -(T(2) * zFar*zNear)/(zFar-zNear); //D - frustum(2,3) = -T(1); +// frustum(2,3) = -T(1); - return frustum; - } -}; +// return frustum; +// } +//}; } diff --git a/src/core/include/pw/core/matrixbase.hpp b/src/core/include/pw/core/matrixbase.hpp index 3db78fe..e6c3260 100644 --- a/src/core/include/pw/core/matrixbase.hpp +++ b/src/core/include/pw/core/matrixbase.hpp @@ -87,6 +87,16 @@ struct matrixbase_ { return derived().data[i]; } + static T dot(const Derived &a,const Derived &b) { + Derived r; for (size_t i = 0;i < a.size();i++) r[i] = a[i] * b[i]; + return std::accumulate(std::begin(r), std::end(r), T(0)); + } + + static const Derived lerp(const Derived &a,const Derived &b,const T& t) { + return a + (b - a) * t; + } + + // inline Derived& operator *= (const T& b) { for (auto & e : *this) e *= b; return derived(); } // inline Derived& operator /= (const T& b) { for (auto & e : *this) e /= b; return derived(); } // inline Derived& operator += (const T& b) { for (auto & e : *this) e += b; return derived(); } diff --git a/src/core/include/pw/core/quaternion.hpp b/src/core/include/pw/core/quaternion.hpp index 2fe840b..0689a2d 100644 --- a/src/core/include/pw/core/quaternion.hpp +++ b/src/core/include/pw/core/quaternion.hpp @@ -24,6 +24,7 @@ #define PW_CORE_QUATERNION_HPP #include +#include namespace pw { @@ -33,79 +34,99 @@ namespace pw { template struct quaternion_ : vector4_ { - typedef vector4_ Base; + typedef vector4_ Base; - using Base::Base; - using Base::x; - using Base::y; - using Base::z; - using Base::w; - // using Base::lerp; - // using Base::operator*; - using Base::operator/; + using Base::Base; + using Base::x; + using Base::y; + using Base::z; + using Base::w; + using Base::lerp; + using Base::operator*; + using Base::operator/; - inline const quaternion_ operator * (const quaternion_& rhs) const { - return quaternion_( - rhs.w()*x() + rhs.x()*w() + rhs.y()*z() - rhs.z()*y(), - rhs.w()*y() - rhs.x()*z() + rhs.y()*w() + rhs.z()*x(), - rhs.w()*z() + rhs.x()*y() - rhs.y()*x() + rhs.z()*w(), - rhs.w()*w() - rhs.x()*x() - rhs.y()*y() - rhs.z()*z() - ); - } + inline const quaternion_ operator * (const quaternion_& rhs) const { + return quaternion_( + rhs.w()*x() + rhs.x()*w() + rhs.y()*z() - rhs.z()*y(), + rhs.w()*y() - rhs.x()*z() + rhs.y()*w() + rhs.z()*x(), + rhs.w()*z() + rhs.x()*y() - rhs.y()*x() + rhs.z()*w(), + rhs.w()*w() - rhs.x()*x() - rhs.y()*y() - rhs.z()*z() + ); + } - //! conjugate - inline quaternion_ conjugate() const { return quaternion_( { -x(),-y(),-z(),w() } ); } + inline const quaternion_ operator / (const T& rhs) const { + return quaternion_( { x() / rhs, y() / rhs, z() / rhs, w() / rhs, } ); + } - //! compute inverse - inline quaternion_ inverse() const { - return conjugate() / this->norm(); - } + //! conjugate + inline quaternion_ conjugate() const { return quaternion_( { -x(),-y(),-z(),w() } ); } - const matrix4x4_ to_matrix() const { + //! compute inverse + inline quaternion_ inverse() const { + return conjugate() / this->norm(); + } - matrix4x4_ m; m.set_identity(); + const matrix4x4_ to_matrix() const { - T xx = x() * x(); - T xy = x() * y(); - T xz = x() * z(); - T xw = x() * w(); + matrix4x4_ m; m.set_identity(); - T yy = y() * y(); - T yz = y() * z(); - T yw = y() * w(); + T xx = x() * x(); + T xy = x() * y(); + T xz = x() * z(); + T xw = x() * w(); - T zz = z() * z(); - T zw = z() * w(); + T yy = y() * y(); + T yz = y() * z(); + T yw = y() * w(); - m(0,0) = 1 - 2 * ( yy + zz ); - m(0,1) = 2 * ( xy - zw ); - m(0,2) = 2 * ( xz + yw ); + T zz = z() * z(); + T zw = z() * w(); - m(1,0) = 2 * ( xy + zw ); - m(1,1) = 1 - 2 * ( xx + zz ); - m(1,2) = 2 * ( yz - xw ); + m(0,0) = 1 - 2 * ( yy + zz ); + m(0,1) = 2 * ( xy - zw ); + m(0,2) = 2 * ( xz + yw ); - m(2,0) = 2 * ( xz - yw ); - m(2,1) = 2 * ( yz + xw ); - m(2,2) = 1 - 2 * ( xx + yy ); + m(1,0) = 2 * ( xy + zw ); + m(1,1) = 1 - 2 * ( xx + zz ); + m(1,2) = 2 * ( yz - xw ); - return m; - } + m(2,0) = 2 * ( xz - yw ); + m(2,1) = 2 * ( yz + xw ); + m(2,2) = 1 - 2 * ( xx + yy ); - static quaternion_ from_matrix(const matrix_ &m) { - using std::sqrt; - const T wtemp = sqrt(T(1) + m(0,0) + m(1,1) + m(2,2)) / T(2); - const T w4 = T(4.0) * wtemp; - return quaternion_( - (m(2,1) - m(1,2)) / w4, - (m(0,2) - m(2,0)) / w4, - (m(1,0) - m(0,1)) / w4, - wtemp); - } + return m; + } - static const quaternion_ normalized_lerp(const quaternion_ &a,const quaternion_ &b,const T &t) { - return quaternion_(lerp(a,b,t).normalized()); - } + static quaternion_ from_matrix(const matrix_ &m) { + using std::sqrt; + const T wtemp = sqrt(T(1) + m(0,0) + m(1,1) + m(2,2)) / T(2); + const T w4 = T(4.0) * wtemp; + return quaternion_( + (m(2,1) - m(1,2)) / w4, + (m(0,2) - m(2,0)) / w4, + (m(1,0) - m(0,1)) / w4, + wtemp); + } + + static const quaternion_ normalized_lerp(const quaternion_ &a,const quaternion_ &b,const T &t) { + return quaternion_(lerp(a,b,t).normalized()); + } + + static const quaternion_ from_axisangle(const axisangle_ &aa) { + + using std::sin; + using std::cos; + + const T sinHalfAngle( sin(aa.angle() * T(0.5) )); + + return quaternion_( { aa.axis().x() * sinHalfAngle, // x + aa.axis().y() * sinHalfAngle, // y + aa.axis().z() * sinHalfAngle, // z + cos(aa.angle() * T(0.5)) // w + } + ); + + } }; // @@ -129,129 +150,129 @@ typedef quaternion_ quaterniond; template class quaternion_ { - static const T _sqrt90; + static const T _sqrt90; public: - typedef vector4_ coefficient_type; - typedef T value_type; + typedef vector4_ coefficient_type; + typedef T value_type; - quaternion_() { *this = identity(); } + quaternion_() { *this = identity(); } - quaternion_(const T& x,const T& y,const T& z,const T& w) - : _q(coefficient_type(x,y,z,w)) {} + quaternion_(const T& x,const T& y,const T& z,const T& w) + : _q(coefficient_type(x,y,z,w)) {} - quaternion_(const coefficient_type& vec) { *this = vec; } + quaternion_(const coefficient_type& vec) { *this = vec; } - inline quaternion_& operator = (const coefficient_type& vec) { _q = vec; return *this; } + inline quaternion_& operator = (const coefficient_type& vec) { _q = vec; return *this; } - inline void set(const T& x,const T& y,const T& z,const T& w) { - _q.set(x,y,z,w); - } + inline void set(const T& x,const T& y,const T& z,const T& w) { + _q.set(x,y,z,w); + } - inline void set_x(const T& v) { x() = v; } - inline void set_y(const T& v) { y() = v; } - inline void set_z(const T& v) { z() = v; } - inline void set_w(const T& v) { w() = v; } + inline void set_x(const T& v) { x() = v; } + inline void set_y(const T& v) { y() = v; } + inline void set_z(const T& v) { z() = v; } + inline void set_w(const T& v) { w() = v; } - inline const coefficient_type& as_vector() const { return _q; } + inline const coefficient_type& as_vector() const { return _q; } - inline T& x() { return _q.x(); } - inline T& y() { return _q.x(); } - inline T& z() { return _q.z(); } - inline T& w() { return _q.w(); } + inline T& x() { return _q.x(); } + inline T& y() { return _q.x(); } + inline T& z() { return _q.z(); } + inline T& w() { return _q.w(); } - inline const T& x() const { return _q.z(); } - inline const T& y() const { return _q.y(); } - inline const T& z() const { return _q.z(); } - inline const T& w() const { return _q.w(); } + inline const T& x() const { return _q.z(); } + inline const T& y() const { return _q.y(); } + inline const T& z() const { return _q.z(); } + inline const T& w() const { return _q.w(); } - //! multiplication - inline const quaternion_ operator * (const quaternion_& rhs) const { - return quaternion_( - rhs.w()*x() + rhs.x()*w() + rhs.y()*z() - rhs.z()*y(), - rhs.w()*y() - rhs.x()*z() + rhs.y()*w() + rhs.z()*x(), - rhs.w()*z() + rhs.x()*y() - rhs.y()*x() + rhs.z()*w(), - rhs.w()*w() - rhs.x()*x() - rhs.y()*y() - rhs.z()*z() - ); - } + //! multiplication + inline const quaternion_ operator * (const quaternion_& rhs) const { + return quaternion_( + rhs.w()*x() + rhs.x()*w() + rhs.y()*z() - rhs.z()*y(), + rhs.w()*y() - rhs.x()*z() + rhs.y()*w() + rhs.z()*x(), + rhs.w()*z() + rhs.x()*y() - rhs.y()*x() + rhs.z()*w(), + rhs.w()*w() - rhs.x()*x() - rhs.y()*y() - rhs.z()*z() + ); + } - //! multiply with scalar - inline const quaternion_ operator * (const T& s) const { - return quaternion_(x()*s,y()*s,z()*s,w()*s); - } + //! multiply with scalar + inline const quaternion_ operator * (const T& s) const { + return quaternion_(x()*s,y()*s,z()*s,w()*s); + } - //! addition - inline const quaternion_ operator + (const quaternion_& rhs) const { - return quaternion_(coefficient_type(this->_q + rhs._q)); - } + //! addition + inline const quaternion_ operator + (const quaternion_& rhs) const { + return quaternion_(coefficient_type(this->_q + rhs._q)); + } - //! addition - inline const quaternion_ operator - (const quaternion_& rhs) const { - return quaternion_(this->_q - rhs._q); - } + //! addition + inline const quaternion_ operator - (const quaternion_& rhs) const { + return quaternion_(this->_q - rhs._q); + } - //! squared norm - inline const T squared_norm() const { return _q.squared_norm(); } + //! squared norm + inline const T squared_norm() const { return _q.squared_norm(); } - //! norm - inline const T norm() const { return _q.norm(); } + //! norm + inline const T norm() const { return _q.norm(); } - //! dot product - inline const T dot(const quaternion_& other) const { return dot(_q,other._q); } + //! dot product + inline const T dot(const quaternion_& other) const { return dot(_q,other._q); } - //! compute normalized - inline quaternion_ normalized() const { - return quaternion_(_q.normalized()); - } + //! compute normalized + inline quaternion_ normalized() const { + return quaternion_(_q.normalized()); + } - inline void normalize() { *this = this->normalized(); } + inline void normalize() { *this = this->normalized(); } - //! conversion from a matrix - inline static const quaternion_ from_matrix(const matrix_ &m); + //! conversion from a matrix + inline static const quaternion_ from_matrix(const matrix_ &m); - //! conversion to a matrix - const matrix_ to_matrix() const; + //! conversion to a matrix + const matrix_ to_matrix() const; - //! return identiy quaternion - static const quaternion_ identity(); + //! return identiy quaternion + static const quaternion_ identity(); - static const quaternion_ rotate_180_degree_around_x(); ///< rotate 180 degree around X axis - static const quaternion_ rotate_180_degree_around_y(); ///< rotate 180 degree around Y axis - static const quaternion_ rotate_180_degree_around_z(); ///< rotate 180 degree around Z axis + static const quaternion_ rotate_180_degree_around_x(); ///< rotate 180 degree around X axis + static const quaternion_ rotate_180_degree_around_y(); ///< rotate 180 degree around Y axis + static const quaternion_ rotate_180_degree_around_z(); ///< rotate 180 degree around Z axis - static const quaternion_ rotate_90_degree_around_x(bool negative = false); - static const quaternion_ rotate_90_degree_around_y(bool negative = false); - static const quaternion_ rotate_90_degree_around_z(bool negative = false); + static const quaternion_ rotate_90_degree_around_x(bool negative = false); + static const quaternion_ rotate_90_degree_around_y(bool negative = false); + static const quaternion_ rotate_90_degree_around_z(bool negative = false); - template - static const quaternion_ from_axisangle(const AxisAngleType &aa) { + template + static const quaternion_ from_axisangle(const AxisAngleType &aa) { - using std::sin; - using std::cos; + using std::sin; + using std::cos; - const T sinHalfAngle(sin(aa.angle() * T(0.5) )); + const T sinHalfAngle(sin(aa.angle() * T(0.5) )); - return quaternion_(aa.axis().x() * sinHalfAngle, // x - aa.axis().y() * sinHalfAngle, // y - aa.axis().z() * sinHalfAngle, // z - cos(aa.angle() * 0.5) // w - ); + return quaternion_(aa.axis().x() * sinHalfAngle, // x + aa.axis().y() * sinHalfAngle, // y + aa.axis().z() * sinHalfAngle, // z + cos(aa.angle() * 0.5) // w + ); - } + } - static const quaternion_ lerp(const quaternion_& qa,const quaternion_& qb,const T& t); - static const quaternion_ normalized_lerp(const quaternion_& qa,const quaternion_& qb,const T& t); - static const quaternion_ slerp(const quaternion_& qa,const quaternion_& qb,const T& t); + static const quaternion_ lerp(const quaternion_& qa,const quaternion_& qb,const T& t); + static const quaternion_ normalized_lerp(const quaternion_& qa,const quaternion_& qb,const T& t); + static const quaternion_ slerp(const quaternion_& qa,const quaternion_& qb,const T& t); protected: - coefficient_type _q; + coefficient_type _q; }; template @@ -265,42 +286,42 @@ const T quaternion_::_sqrt90 = std::sqrt(0.5); template const quaternion_ quaternion_::identity() { - return quaternion_(0,0,0,1); + return quaternion_(0,0,0,1); } template const quaternion_ quaternion_::rotate_180_degree_around_x() { - return quaternion_(1,0,0,0); + return quaternion_(1,0,0,0); } template const quaternion_ quaternion_::rotate_180_degree_around_y() { - return quaternion_(0,1,0,0); + return quaternion_(0,1,0,0); } template const quaternion_ quaternion_::rotate_180_degree_around_z() { - return quaternion_(0,0,1,0); + return quaternion_(0,0,1,0); } template const quaternion_ quaternion_::rotate_90_degree_around_x(bool negative/* = false*/) { - return quaternion_((negative) ? - _sqrt90 : _sqrt90,0,0,_sqrt90); + return quaternion_((negative) ? - _sqrt90 : _sqrt90,0,0,_sqrt90); } template const quaternion_ quaternion_::rotate_90_degree_around_y(bool negative/* = false*/) { - return quaternion_(0, (negative) ? -_sqrt90 : _sqrt90,0,_sqrt90); + return quaternion_(0, (negative) ? -_sqrt90 : _sqrt90,0,_sqrt90); } template const quaternion_ quaternion_::rotate_90_degree_around_z(bool negative/* = false*/) { - return quaternion_(0,0,(negative) ? -_sqrt90 : _sqrt90, _sqrt90); + return quaternion_(0,0,(negative) ? -_sqrt90 : _sqrt90, _sqrt90); } @@ -308,40 +329,40 @@ const quaternion_ quaternion_::rotate_90_degree_around_z(bool negative/* = template const quaternion_ quaternion_::slerp(const quaternion_& qa,const quaternion_& qb,const T& t) { - using std::abs; - using std::sqrt; - using std::acos; + using std::abs; + using std::sqrt; + using std::acos; - // quaternion to return - quaternion_ qm; - // Calculate angle between them. - double cosHalfTheta = qa.w() * qb.w() + qa.x() * qb.x() + qa.y() * qb.y() + qa.z() * qb.z(); - // if qa=qb or qa=-qb then theta = 0 and we can return qa - if (abs(cosHalfTheta) >= T(1.)) { - return qa; - } + // quaternion to return + quaternion_ qm; + // Calculate angle between them. + double cosHalfTheta = qa.w() * qb.w() + qa.x() * qb.x() + qa.y() * qb.y() + qa.z() * qb.z(); + // if qa=qb or qa=-qb then theta = 0 and we can return qa + if (abs(cosHalfTheta) >= T(1.)) { + return qa; + } - // Calculate temporary values. - double halfTheta = acos(cosHalfTheta); - double sinHalfTheta = sqrt(1.0 - cosHalfTheta * cosHalfTheta); - // if theta = 180 degrees then result is not fully defined - // we could rotate around any axis normal to qa or qb - if (::std::abs(sinHalfTheta) < 0.001){ // fabs is floating point absolute - qm.w() = (qa.w() * 0.5 + qb.w() * 0.5); - qm.x() = (qa.x() * 0.5 + qb.x() * 0.5); - qm.y() = (qa.y() * 0.5 + qb.y() * 0.5); - qm.z() = (qa.z() * 0.5 + qb.z() * 0.5); - return qm; - } - double ratioA = sin((1 - t) * halfTheta) / sinHalfTheta; - double ratioB = sin(t * halfTheta) / sinHalfTheta; - //calculate Quaternion. - qm.w() = (qa.w() * ratioA + qb.w() * ratioB); - qm.x() = (qa.x() * ratioA + qb.x() * ratioB); - qm.y() = (qa.y() * ratioA + qb.y() * ratioB); - qm.z() = (qa.z() * ratioA + qb.z() * ratioB); + // Calculate temporary values. + double halfTheta = acos(cosHalfTheta); + double sinHalfTheta = sqrt(1.0 - cosHalfTheta * cosHalfTheta); + // if theta = 180 degrees then result is not fully defined + // we could rotate around any axis normal to qa or qb + if (::std::abs(sinHalfTheta) < 0.001){ // fabs is floating point absolute + qm.w() = (qa.w() * 0.5 + qb.w() * 0.5); + qm.x() = (qa.x() * 0.5 + qb.x() * 0.5); + qm.y() = (qa.y() * 0.5 + qb.y() * 0.5); + qm.z() = (qa.z() * 0.5 + qb.z() * 0.5); + return qm; + } + double ratioA = sin((1 - t) * halfTheta) / sinHalfTheta; + double ratioB = sin(t * halfTheta) / sinHalfTheta; + //calculate Quaternion. + qm.w() = (qa.w() * ratioA + qb.w() * ratioB); + qm.x() = (qa.x() * ratioA + qb.x() * ratioB); + qm.y() = (qa.y() * ratioA + qb.y() * ratioB); + qm.z() = (qa.z() * ratioA + qb.z() * ratioB); - return qm; + return qm; } diff --git a/src/core/include/pw/core/serialize.hpp b/src/core/include/pw/core/serialize.hpp index 8395bb8..80cd020 100644 --- a/src/core/include/pw/core/serialize.hpp +++ b/src/core/include/pw/core/serialize.hpp @@ -33,12 +33,12 @@ namespace pw { struct serialize { - template - inline static std::string matrix(const matrix_& m) { + template + inline static std::string matrix(const matrix_& m) { std::stringstream ss; - for (int r = 0; r < m.rows();r++) { - for (int c = 0; c < m.cols();c++) { + for (int r = 0; r < m.rows;r++) { + for (int c = 0; c < m.cols;c++) { ss << m(r,c) << " "; } ss << std::endl; diff --git a/src/core/include/pw/core/size.hpp b/src/core/include/pw/core/size.hpp index eebb043..e00992a 100644 --- a/src/core/include/pw/core/size.hpp +++ b/src/core/include/pw/core/size.hpp @@ -41,8 +41,6 @@ struct size_ { template size_ cast() const { return size_(static_cast(width),static_cast(height)); } - - }; typedef size_ size; diff --git a/src/core/include/pw/core/vector.hpp b/src/core/include/pw/core/vector.hpp index 5b59463..6b7b19f 100644 --- a/src/core/include/pw/core/vector.hpp +++ b/src/core/include/pw/core/vector.hpp @@ -27,46 +27,36 @@ namespace pw { -template -struct vector_ : matrix_ +template +struct vector_ : matrix_ { - typedef matrix_ Base; + static const size_t coefficients = N; - using typename Base::value_type; - using Base::Base; - - static T dot(const Base &a,const Base &b) { - vector_ r; for (size_t i = 0;i < N;i++) r[i] = a[i] * b[i]; - return std::accumulate(std::begin(r), std::end(r), T(0)); - } - - static T angle_between(const Base &a,const Base &b) { - return std::acos( dot( a.normalized(), b.normalized() ) ); - } - - static const vector_ lerp(const vector_ &a,const vector_ &b,const T& t) { - return a + (b - a) * t; - } + using matrix_::matrix_; +// static T angle_between(const vector_ &a,const vector_ &b) { +// return std::acos( dot( a.normalized(), b.normalized() ) ); +// } }; template -struct vector2_ : vector_ { - - using vector_::vector_; - +struct vector2_ : vector_<2,T> { + using vector_<2,T>::vector_; inline const T& x() const { return (*this)[0]; } inline T& x() { return (*this)[0]; } inline const T& y() const { return (*this)[1]; } - inline T& y() { return (*this)[1]; } - inline auto homogenous(T w = 1) const { return vector_(x(),y(),w); } + + inline auto homogenous(T w = 1) const { return vector_<3,T>( { x(),y(),w } ); } }; + +#if defined(_D) + template struct vector3_ : vector_ { @@ -117,27 +107,28 @@ struct vector4_ : vector_ { }; + +#endif // // // using vector2f = vector2_; using vector2d = vector2_; -using vector2 = vector2_; +//using vector2 = vector2_; -using vector3f = vector3_; -using vector3d = vector3_; -using vector3 = vector3_; +//using vector3f = vector3_; +//using vector3d = vector3_; +//using vector3 = vector3_; + +//using vector4f = vector4_; +//using vector4d = vector4_; +//using vector4 = vector4_; -using vector4f = vector4_; -using vector4d = vector4_; -using vector4 = vector4_; } - - #if defined(___OLDSTUFF) template @@ -328,4 +319,6 @@ typedef vector4_ vector4ui; #endif + + #endif diff --git a/src/core/tests/CMakeLists.txt b/src/core/tests/CMakeLists.txt index 89e795b..517f07a 100644 --- a/src/core/tests/CMakeLists.txt +++ b/src/core/tests/CMakeLists.txt @@ -5,25 +5,25 @@ add_executable(pwcore_test_matrix target_link_libraries(pwcore_test_matrix pwcore) -add_executable(pwcore_test_vector - pwcore_test_vector.cpp - ) +#add_executable(pwcore_test_vector +# pwcore_test_vector.cpp +# ) -target_link_libraries(pwcore_test_vector - pwcore) +#target_link_libraries(pwcore_test_vector +# pwcore) -add_executable(pwcore_test_quaternion - pwcore_test_quaternion.cpp - ) +#add_executable(pwcore_test_quaternion +# pwcore_test_quaternion.cpp +# ) -target_link_libraries(pwcore_test_quaternion - pwcore) +#target_link_libraries(pwcore_test_quaternion +# pwcore) -add_executable(pwcore_test_axisangle - pwcore_test_axisangle.cpp - ) +#add_executable(pwcore_test_axisangle +# pwcore_test_axisangle.cpp +# ) -target_link_libraries(pwcore_test_axisangle - pwcore) +#target_link_libraries(pwcore_test_axisangle +# pwcore) diff --git a/src/core/tests/pwcore_test_axisangle.cpp b/src/core/tests/pwcore_test_axisangle.cpp index 4445193..0a36a03 100644 --- a/src/core/tests/pwcore_test_axisangle.cpp +++ b/src/core/tests/pwcore_test_axisangle.cpp @@ -8,11 +8,10 @@ int main(int argc,char **argv) { pw::axisangle_ aa = pw::axisangle_(); -// pw::quaternionf qf = pw::quaternionf::from_axisangle(aa); + pw::quaternionf qf = pw::quaternionf::from_axisangle(aa); -// std::cout << "aa as quaternion as vector = " << pw::serialize::matrix(qf.as_vector()) << std::endl; - -// std::cout << "aa.matrix() = " << pw::serialize::matrix(qf.to_matrix()) << std::endl; + std::cout << "aa as quaternion as matrix = " << pw::serialize::matrix(qf.to_matrix()) << std::endl; + std::cout << "aa.matrix() = " << pw::serialize::matrix(qf.to_matrix()) << std::endl; return 0; diff --git a/src/core/tests/pwcore_test_matrix.cpp b/src/core/tests/pwcore_test_matrix.cpp index 1803ab6..634a52a 100644 --- a/src/core/tests/pwcore_test_matrix.cpp +++ b/src/core/tests/pwcore_test_matrix.cpp @@ -2,27 +2,13 @@ #include #include - -//#include +#include #include #include #include -template inline static -std::basic_ostream& operator << (std::basic_ostream& os, - const pw::matrix_& m - ) -{ - for (size_t r = 0; r < R;r++){ - for (size_t c = 0;c < C;c++) { - os << m(r,c) << " "; - } - os << std::endl; - } - return os; -} int main(int argc,char **argv) { @@ -39,36 +25,39 @@ int main(int argc,char **argv) { vector2f v3( { 1.f,2.f } ); + auto m22_inv = m22.inverse(); auto m22_id = m22_inv * m22; + auto v2_t = m22_id * v2; auto v3_t = m22_id * v3; - - auto v2_f = m22 * v2; auto v2_b = m22_inv * v2_f; + vector2f r_m22 = m22.row(0); + debug::d() << "offset(0,1) col-major " << m22.offset(0,1); debug::d() << "det " << m22.determinant(); - std::cout << "m22 " << m22 << std::endl; - std::cout << "m22-1 " << m22_inv << std::endl; - std::cout << "m22-i " << m22_id << std::endl; - std::cout << "v22_t " << v2_t << std::endl; - std::cout << "v3_t " << v3_t << std::endl; + std::cout << "m22 " << pw::serialize::matrix(m22) << std::endl; + std::cout << "m22-1 " << pw::serialize::matrix(m22_inv) << std::endl; + std::cout << "m22-i " << pw::serialize::matrix(m22_id) << std::endl; + std::cout << "v22_t " << pw::serialize::matrix(v2_t) << std::endl; + std::cout << "v3_t " << pw::serialize::matrix(v3_t) << std::endl; - std::cout << "v2_f " << v2_f << std::endl; - std::cout << "v2_b " << v2_b << std::endl; + + std::cout << "v2_f " << pw::serialize::matrix(v2_f) << std::endl; + std::cout << "v2_b " << pw::serialize::matrix(v2_b) << std::endl; std::cout << "v2_b.norm " << v2_b.norm() << std::endl; // v2_b.normalize(); - std::cout << "v2_b.normalized " << v2_b.normalized() << std::endl; + std::cout << "v2_b.normalized " << pw::serialize::matrix(v2_b.normalized()) << std::endl; - std::cout << "v2_b~v3_t " << rad_to_deg(vector2f::angle_between(v2,v3)) << std::endl; +// std::cout << "v2_b~v3_t " << rad_to_deg(vector2f::angle_between(v2,v3)) << std::endl; diff --git a/src/core/tests/pwcore_test_quaternion.cpp b/src/core/tests/pwcore_test_quaternion.cpp index 9aa30fa..f7608c8 100644 --- a/src/core/tests/pwcore_test_quaternion.cpp +++ b/src/core/tests/pwcore_test_quaternion.cpp @@ -20,10 +20,8 @@ int main(int argc,char **argv) { pw::quaternionf qi = qf.inverse(); std::cout << "qf.inverse() (qi) = " << pw::serialize::matrix(qi) << std::endl; -// pw::quaternionf qmid = pw::quaternionf::normalized_lerp(qi,qf,0.5f); - -// std::cout << "qmid.dot() (half between qf and qi) = " << pw::rad_to_deg(std::acos(qmid.dot(qf))) << std::endl; - + pw::quaternionf qmid = pw::quaternionf::normalized_lerp(qi,qf,0.5f); +// std::cout << "qmid.dot() (half between qf and qi) = " << pw::rad_to_deg(quaternionf::angle_between()) << std::endl; diff --git a/src/core/tests/pwcore_test_vector.cpp b/src/core/tests/pwcore_test_vector.cpp index d0ae64c..0487ebd 100644 --- a/src/core/tests/pwcore_test_vector.cpp +++ b/src/core/tests/pwcore_test_vector.cpp @@ -6,30 +6,34 @@ int main(int argc,char **argv) { - pw::vector4_ v4; - pw::vector3f v; + pw::vector2_ v2; - v4.fill(1.5); + v2.x = 0.1f; - std::cout << "v4 = " << pw::serialize::matrix(v4) << std::endl; +// pw::vector4_ v4; +// pw::vector3f v; - std::cout << "rows() : " << v4.rows() << std::endl; - std::cout << "cols() : " << v4.cols() << std::endl; - std::cout << "ptr() : " << v4.ptr() << std::endl; - std::cout << "ptr()[0] : " << v4.ptr()[0] << std::endl; - std::cout << "(0,0) : " << v4(0,0) << std::endl; +// v4.fill(1.5); - auto v3 = v4.xyz(); +// std::cout << "v4 = " << pw::serialize::matrix(v4) << std::endl; - auto v3_p = v4.project(); +// std::cout << "rows() : " << v4.rows() << std::endl; +// std::cout << "cols() : " << v4.cols() << std::endl; +// std::cout << "ptr() : " << v4.ptr() << std::endl; +// std::cout << "ptr()[0] : " << v4.ptr()[0] << std::endl; +// std::cout << "(0,0) : " << v4(0,0) << std::endl; - auto v3_h = v.homogenous(); +// auto v3 = v4.xyz(); -// auto v3_lerp = vector4f::lerp() +// auto v3_p = v4.project(); - std::cout << "v3 = " << pw::serialize::matrix(v3) << std::endl; +// auto v3_h = v.homogenous(); - std::cout << "v3.normalized() = " << pw::serialize::matrix(v3.normalized()) << std::endl; +//// auto v3_lerp = vector4f::lerp() + +// std::cout << "v3 = " << pw::serialize::matrix(v3) << std::endl; + +// std::cout << "v3.normalized() = " << pw::serialize::matrix(v3.normalized()) << std::endl; return 0;