diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f1be2e5..e5cd101 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -5,8 +5,8 @@ set(hdrs include/pw/core/core.hpp include/pw/core/math.hpp include/pw/core/matrixbase.hpp -# include/pw/core/matrix.hpp -# include/pw/core/vector.hpp + include/pw/core/matrix.hpp + include/pw/core/vector.hpp # include/pw/core/quaternion.hpp # include/pw/core/serialize.hpp include/pw/core/image.hpp @@ -14,7 +14,7 @@ set(hdrs include/pw/core/rect.hpp include/pw/core/size.hpp include/pw/core/timer.hpp -# include/pw/core/mesh.hpp + include/pw/core/mesh.hpp include/pw/core/globals.hpp include/pw/core/image.hpp ) @@ -23,7 +23,7 @@ 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 diff --git a/src/core/include/pw/core/matrix.hpp b/src/core/include/pw/core/matrix.hpp index 6e7c43b..38323b4 100644 --- a/src/core/include/pw/core/matrix.hpp +++ b/src/core/include/pw/core/matrix.hpp @@ -32,6 +32,197 @@ namespace pw { + + +template +struct matrix_ : matrixbase_> { + + T data[R*C]; + + matrix_() = default; + + matrix_(const matrix_& other) + { + *this = other; + } + + matrix_& operator = (const matrix_& other) + { + for (size_t i = 0; i < other.size();i++) (*this)[i] = other[i]; + return *this; + } + + template + matrix_(Arguments ...values) + : data {values... } + { + static_assert(sizeof...(Arguments) == R*C, + "Incorrect number of arguments"); + } + + //! rows + inline std::size_t rows() const { return R; } + + //! return number of columns + inline std::size_t cols() const { return C; } + + //! get cell count + inline std::size_t coefficients() const { return this->size(); } + + inline size_t offset(size_t r,size_t c) const { + return (RowMajor) ? r * C + c : c * R + r; + } + + inline T& operator () (std::size_t r, std::size_t c) { + return data[offset(r,c)]; + } + + inline const T& operator () (std::size_t r, std::size_t c) const { + return data[offset(r,c)]; + } + + //! set identity + inline matrix_& set_identity() + { + for (unsigned int r = 0;r < rows(); r++) + for (unsigned int c = 0; c < cols(); c++) + this->at(r,c) = (c == r) ? T(1) : T(0); + return *this; + } + + template + matrix_ slice(std::size_t r,std::size_t c) const + { + 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); + return s; + } + + template + 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++) + (*this)(ri+r,ci+c) = s(ri,ci); + return *this; + } + + + template + matrix_ minor(std::size_t r0,std::size_t c0) const + { + matrix_ m; + size_t r = 0; + for (size_t ri = 0; ri < R; ri++) { + size_t c = 0; + if (ri == r0) + continue; + for (size_t ci = 0; ci < C; ci++) + { + if (ci == c0) + continue; + m(r,c) = (*this)(ri,ci); + c++; + } + r++; + } + return m; + } + + T determinant() const { + T det(0); + for (size_t c = 0; c < C; c++) + det += ((c % 2 == 0) ? (*this)(0,c) : -(*this)(0,c)) + * this->minor(0,c).determinant(); + return det; + } + + matrix_ transposed() const { + matrix_ res; + for (size_t r = this->rows();r-->0;) + for (size_t c = this->cols();c-->0;) + res(c,r) = (*this)(r,c); + return res; + } + + matrix_ inverse() const { + T invDet = T(1) / this->determinant(); + matrix_ inv; + for (int j = 0; j < C; j++) + for (int i = 0; i < R; i++) + { + const T minorDet = this->minor(j,i).determinant(); + const T coFactor = ((i + j) % 2 == 1) ? -minorDet : minorDet; + inv(i, j) = invDet * coFactor; + } + return inv; + } + + inline bool row_major() const { + return RowMajor; + } + + inline bool square() const { return R == C; } + + +}; + +template <> inline +float matrix_::determinant() const +{ + return (*this)(0,0); +} + +template <> inline +double matrix_::determinant() const +{ + return (*this)(0,0); +} + + + +template +auto operator * (const matrix_& A, + const matrix_& B + ) +{ + 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++) + result(r,c) += A(r,iI) * B(iI,c); // inner product + return result; +} + + +// +// +// + + +template using matrix2x2_ = matrix_; +template using matrix3x3_ = matrix_; +template using matrix4x4_ = matrix_; + +using matrix2x2f = matrix_; +using matrix2x2d = matrix_; +using matrix2x2 = matrix_; + +using matrix3x3f = matrix_; +using matrix3x3d = matrix_; +using matrix3x3 = matrix_; + +using matrix4x4f = matrix_; +using matrix4x4d = matrix_; +using matrix4x4 = matrix_; + +} + + +#if __OLD + template class matrix_ : public matrixbase { @@ -633,6 +824,7 @@ typedef matrix4x4_ matrix4x4f; } +#endif #endif diff --git a/src/core/include/pw/core/matrixbase.hpp b/src/core/include/pw/core/matrixbase.hpp index 402b631..7941fef 100644 --- a/src/core/include/pw/core/matrixbase.hpp +++ b/src/core/include/pw/core/matrixbase.hpp @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -54,9 +55,26 @@ struct matrixbase_ { } T trace() const { - return std::accumulate(std::begin(derived().data),std::end(derived().data),T()); + return std::accumulate(std::begin(derived().data),std::end(derived().data),T(0)); } + + inline T squared_norm() const { + return std::accumulate(std::begin(derived().data),std::end(derived().data), T(0), + [&](const T& a,const T& b){ + return a + b * b; + }); + } + + inline T norm() const { + return std::sqrt(squared_norm()); + } + + inline Derived& normalize() { + (*this) /= this->norm(); + return derived(); + } + using iterator = T*; using const_iterator = const T*; iterator begin() { return &derived().data[0]; } @@ -73,226 +91,18 @@ struct matrixbase_ { } 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(); } - 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(); } + inline Derived& operator -= (const T& b) { for (auto & e : *this) e -= b; return derived(); } -template -struct matrix_ : matrixbase_> { - - T data[R*C]; - - matrix_() = default; - - matrix_(const matrix_& other) - { - *this = other; - } - - matrix_& operator = (const matrix_& other) - { - for (size_t i = 0; i < other.size();i++) (*this)[i] = other[i]; - return *this; - } - - template - matrix_(Arguments ...values) - : data {values... } - { - static_assert(sizeof...(Arguments) == R*C, - "Incorrect number of arguments"); - } - - //! rows - inline std::size_t rows() const { return R; } - - //! return number of columns - inline std::size_t cols() const { return C; } - - //! get cell count - inline std::size_t coefficients() const { return R * C; } - - inline size_t offset(size_t r,size_t c) const { - return (RowMajor) ? r * C + c : c * R + r; - } - - inline T& operator () (std::size_t r, std::size_t c) { - return data[offset(r,c)]; - } - - inline const T& operator () (std::size_t r, std::size_t c) const { - return data[offset(r,c)]; - } - - //! set identity - inline matrix_& set_identity() - { - for (unsigned int r = 0;r < rows(); r++) - for (unsigned int c = 0; c < cols(); c++) - this->at(r,c) = (c == r) ? T(1) : T(0); - return *this; - } - - template - matrix_ slice(std::size_t r,std::size_t c) const - { - 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); - return s; - } - - template - 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++) - (*this)(ri+r,ci+c) = s(ri,ci); - return *this; - } - - - template - matrix_ minor(std::size_t r0,std::size_t c0) const - { - matrix_ m; - size_t r = 0; - for (size_t ri = 0; ri < R; ri++) { - size_t c = 0; - if (ri == r0) - continue; - for (size_t ci = 0; ci < C; ci++) - { - if (ci == c0) - continue; - m(r,c) = (*this)(ri,ci); - c++; - } - r++; - } - return m; - } - - T determinant() const { - T det(0); - for (size_t c = 0; c < C; c++) - det += ((c % 2 == 0) ? (*this)(0,c) : -(*this)(0,c)) - * this->minor(0,c).determinant(); - return det; - } - - matrix_ transposed() const { - matrix_ res; - for (size_t r = this->rows();r-->0;) - for (size_t c = this->cols();c-->0;) - res(c,r) = (*this)(r,c); - return res; - } - - matrix_ inverse() const { - T invDet = T(1) / this->determinant(); - matrix_ inv; - for (int j = 0; j < C; j++) - for (int i = 0; i < R; i++) - { - const T minorDet = this->minor(j,i).determinant(); - const T coFactor = ((i + j) % 2 == 1) ? -minorDet : minorDet; - inv(i, j) = invDet * coFactor; - } - return inv; - } - - inline bool row_major() const { - return RowMajor; - } - - inline bool square() const { return R == C; } - }; -template <> inline -float matrix_::determinant() const -{ - return (*this)(0,0); -} - -template <> inline -double matrix_::determinant() const -{ - return (*this)(0,0); -} - - -template -auto operator * (const matrix_& A, - const matrix_& B - ) -{ - 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++) - result(r,c) += A(r,iI) * B(iI,c); // inner product - return result; -} - // // // -template -struct vector_ : matrix_ -{ - typedef matrix_ derived_type; - vector_() = default; - vector_(const derived_type& rhs) : derived_type(rhs) {} - - template - vector_(Arguments ...values) - : derived_type( { values...} ) - { - static_assert(sizeof...(Arguments) == N, - "Incorrect number of arguments"); - } -}; - -template -auto operator * (const vector_& a, const vector_& b) --> vector_ { - vector_ result; - for (std::size_t i = 0; i < N; ++i) { - result[i] = a[i] * b[i]; - } - return result; -} - -template -auto dot(const vector_& a, const vector_& b) --> decltype(a[0] * b[0]) { - auto product = a * b; - using V = decltype(product.x); - return std::accumulate(std::begin(product), std::end(product), V(0)); -} - - -// -// -// - -template using matrix2x2_ = matrix_; -template using matrix3x3_ = matrix_; -template using matrix4x4_ = matrix_; - -using matrix2x2f = matrix_; - -template using vector2_ = vector_; -template using vector3_ = vector_; -template using vector4_ = vector_; -using vector2f = vector2_; ///** diff --git a/src/core/include/pw/core/vector.hpp b/src/core/include/pw/core/vector.hpp index 2bdee2c..cb9e07c 100644 --- a/src/core/include/pw/core/vector.hpp +++ b/src/core/include/pw/core/vector.hpp @@ -27,6 +27,70 @@ namespace pw { + +template +struct vector_ : matrix_ +{ + typedef matrix_ derived_type; + + vector_() = default; + vector_(const derived_type& rhs) : derived_type(rhs) {} + + template + vector_(Arguments ...values) + : derived_type( { values...} ) + { + static_assert(sizeof...(Arguments) == N, + "Incorrect number of arguments"); + } +}; + +template +auto operator * (const vector_& a, const vector_& b) +-> vector_ { + vector_ result; + for (std::size_t i = 0; i < N; ++i) { + result[i] = a[i] * b[i]; + } + return result; +} + +template +auto dot(const vector_& a, const vector_& b) +-> decltype(a[0] * b[0]) { + auto product = a * b; + using V = decltype(product.x); + return std::accumulate(std::begin(product), std::end(product), V(0)); +} + + +// +// +// + +template using vector2_ = vector_; +template using vector3_ = vector_; +template using vector4_ = vector_; + +using vector2f = vector2_; +using vector2d = vector2_; +using vector2 = vector2_; + +using vector3f = vector3_; +using vector3d = vector3_; +using vector3 = vector3_; + +using vector4f = vector4_; +using vector4d = vector4_; +using vector4 = vector4_; + +} + + + + +#if ___OLDSTUFF + template class vector_ : public matrix_ { public: @@ -213,6 +277,6 @@ typedef vector4_ vector4ui; - +#endif #endif diff --git a/src/core/src/mesh.cpp b/src/core/src/mesh.cpp index e02acf8..d10794c 100644 --- a/src/core/src/mesh.cpp +++ b/src/core/src/mesh.cpp @@ -9,7 +9,7 @@ void mesh::apply(const matrix4x4 &m) { // v = vector4(m * v.project(1)).un_project(); - auto vh = v.project(1); +// auto vh = v.project(1); // m.mul(vh); } } diff --git a/src/core/tests/pwcore_test_matrix.cpp b/src/core/tests/pwcore_test_matrix.cpp index ae063fc..b462ce6 100644 --- a/src/core/tests/pwcore_test_matrix.cpp +++ b/src/core/tests/pwcore_test_matrix.cpp @@ -1,7 +1,8 @@ -#include -//#include +#include +#include + //#include #include @@ -62,6 +63,12 @@ int main(int argc,char **argv) { std::cout << "v2_f " << v2_f << std::endl; std::cout << "v2_b " << v2_b << std::endl; + std::cout << "v2_b.norm " << v2_b.norm() << std::endl; + + v2_b.normalize(); + std::cout << "v2_b.normalized " << v2_b << std::endl; + +