some minor refresh

This commit is contained in:
Hartmut Seichter 2023-06-24 08:34:15 +02:00
parent 7d17df39b3
commit d65aba4d68
8 changed files with 278 additions and 768 deletions

7
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,7 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": []
}

20
.vscode/settings.json vendored
View file

@ -1,4 +1,22 @@
{ {
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
"cmake.configureOnOpen": true "cmake.configureOnOpen": true,
"files.associations": {
"array": "cpp",
"cwchar": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"functional": "cpp",
"initializer_list": "cpp",
"iosfwd": "cpp",
"istream": "cpp",
"new": "cpp",
"ostream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"type_traits": "cpp",
"tuple": "cpp"
},
"mesonbuild.configureOnOpen": false
} }

28
.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,28 @@
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ build active file",
"command": "/usr/bin/g++",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}

View file

@ -7,9 +7,9 @@ cmake_minimum_required(VERSION 3.8)
project(pixwerx) project(pixwerx)
# #
# pixwerx ist C++17 # pixwerx ist C++20
# #
set (CMAKE_CXX_STANDARD 23) set (CMAKE_CXX_STANDARD 20)
# internal cmake modules # internal cmake modules
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/etc/cmake ${CMAKE_MODULE_PATH}) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/etc/cmake ${CMAKE_MODULE_PATH})

View file

@ -28,100 +28,108 @@
#include <pw/core/matrixbase.hpp> #include <pw/core/matrixbase.hpp>
#include <numeric> #include <numeric>
#include <array>
namespace pw { namespace pw
template <std::size_t R,std::size_t C, typename T, bool RowMajor = false>
struct matrix_ : matrixbase_<T, matrix_<R, C, T>>
{ {
T data[R*C];
template <std::size_t R, std::size_t C, typename T, bool RowMajor = false>
struct matrix_ : matrixbase_<T, matrix_<R, C, T>>
{
T data[R * C];
using matrixbase_<T, matrix_<R, C, T>>::matrixbase_; using matrixbase_<T, matrix_<R, C, T>>::matrixbase_;
static constexpr std::size_t rows { R }; static constexpr std::size_t rows{R};
static constexpr std::size_t cols { C }; static constexpr std::size_t cols{C};
static constexpr std::size_t coefficients { R * C }; static constexpr std::size_t coefficients{R * C};
using col_type = matrix_<R,1,T>; using col_type = matrix_<R, 1, T>;
using row_type = matrix_<1,C,T>; using row_type = matrix_<1, C, T>;
using transpose_type = matrix_<C,R,T>; using transpose_type = matrix_<C, R, T>;
matrix_(const matrix_<R,C,T>& other) matrix_<R, C, T> &operator=(const matrix_<R, C, T> &other)
{ {
*this = other; for (size_t i = 0; i < other.size(); i++)
} (*this)[i] = other[i];
matrix_<R,C,T>& operator = (const matrix_<R,C,T>& other)
{
for (size_t i = 0; i < other.size();i++) (*this)[i] = other[i];
return *this; return *this;
} }
matrix_(std::initializer_list<T> args) matrix_(std::initializer_list<T> args)
{ {
typename std::initializer_list<T>::iterator it = args.begin(); typename std::initializer_list<T>::iterator it = args.begin();
for (;it != args.end();it++) data[it-args.begin()] = *it; for (; it != args.end(); it++)
data[it - args.begin()] = *it;
} }
template <typename... Arguments> template <typename... Arguments>
matrix_& set(Arguments ...values) matrix_ &set(Arguments... values)
{ {
static_assert(sizeof...(Arguments) == R*C, "Incorrect number of arguments"); static_assert(sizeof...(Arguments) == R * C, "Incorrect number of arguments");
data = {values... }; data = {values...};
return *this; return *this;
} }
inline size_t offset(size_t r,size_t c) const { inline size_t offset(size_t r, size_t c) const
{
return (RowMajor) ? r * C + c : c * R + r; return (RowMajor) ? r * C + c : c * R + r;
} }
inline T& operator () (std::size_t r, std::size_t c) { inline T &operator()(std::size_t r, std::size_t c)
return data[offset(r,c)]; {
return data[offset(r, c)];
} }
inline const T& operator () (std::size_t r, std::size_t c) const { inline const T &operator()(std::size_t r, std::size_t c) const
return data[offset(r,c)]; {
return data[offset(r, c)];
} }
inline const T *ptr() const { return &data[0]; } inline const T *ptr() const { return &data[0]; }
//! set identity //! set identity
inline matrix_& set_identity() inline matrix_ &set_identity()
{ {
for (std::size_t r = 0;r < rows; r++) for (std::size_t r = 0; r < rows; r++)
for (std::size_t c = 0; c < cols; c++) for (std::size_t c = 0; c < cols; c++)
(*this)(r,c) = (c == r) ? T(1) : T(0); (*this)(r, c) = (c == r) ? T(1) : T(0);
return *this; return *this;
} }
template<std::size_t Rs,std::size_t Cs,bool RowMajorSlice = RowMajor> inline matrix_ &set_uniform(const T& v)
auto slice(std::size_t r,std::size_t c) const
{ {
matrix_<Rs,Cs,T,RowMajorSlice> s; std::fill(std::begin(data),std::end(data),v);
for (std::size_t ri = 0;ri < Rs;ri++) return *this;
for (std::size_t ci = 0;ci < Cs;ci++) }
s(ri,ci) = (*this)(ri+r,ci+c);
template <std::size_t Rs, std::size_t Cs, bool RowMajorSlice = RowMajor>
auto slice(std::size_t r, std::size_t c) const
{
matrix_<Rs, Cs, T, RowMajorSlice> 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; return s;
} }
template<std::size_t Rs,std::size_t Cs,bool RowMajorSlice = RowMajor> template <std::size_t Rs, std::size_t Cs, bool RowMajorSlice = RowMajor>
matrix_& set_slice(const matrix_<Rs,Cs,T,RowMajorSlice>& s, matrix_ &set_slice(const matrix_<Rs, Cs, T, RowMajorSlice> &s,
std::size_t r,std::size_t c) std::size_t r, std::size_t c)
{ {
for (std::size_t ri = 0;ri < Rs;ri++) for (std::size_t ri = 0; ri < Rs; ri++)
for (std::size_t ci = 0;ci < Cs;ci++) for (std::size_t ci = 0; ci < Cs; ci++)
(*this)(ri+r,ci+c) = s(ri,ci); (*this)(ri + r, ci + c) = s(ri, ci);
return *this; return *this;
} }
template <std::size_t Rs, std::size_t Cs, bool RowMajorSlice = RowMajor>
template<std::size_t Rs,std::size_t Cs,bool RowMajorSlice = RowMajor> auto minor(std::size_t r0, std::size_t c0) const
auto minor(std::size_t r0,std::size_t c0) const
{ {
matrix_<Rs,Cs,T,RowMajorSlice> m; matrix_<Rs, Cs, T, RowMajorSlice> m;
size_t r = 0; size_t r = 0;
for (size_t ri = 0; ri < R; ri++) { for (size_t ri = 0; ri < R; ri++)
{
size_t c = 0; size_t c = 0;
if (ri == r0) if (ri == r0)
continue; continue;
@ -129,7 +137,7 @@ struct matrix_ : matrixbase_<T, matrix_<R, C, T>>
{ {
if (ci == c0) if (ci == c0)
continue; continue;
m(r,c) = (*this)(ri,ci); m(r, c) = (*this)(ri, ci);
c++; c++;
} }
r++; r++;
@ -137,686 +145,135 @@ struct matrix_ : matrixbase_<T, matrix_<R, C, T>>
return m; return m;
} }
T determinant() const { T determinant() const
{
T det(0); T det(0);
for (size_t c = 0; c < C; c++) for (size_t c = 0; c < C; c++)
det += ((c % 2 == 0) ? (*this)(0,c) : -(*this)(0,c)) det += ((c % 2 == 0) ? (*this)(0, c) : -(*this)(0, c)) * this->minor<R - 1, C - 1, RowMajor>(0, c).determinant();
* this->minor<R-1,C-1,RowMajor>(0,c).determinant();
return det; return det;
} }
auto transposed() const { auto transposed() const
{
transpose_type res; transpose_type res;
for (size_t r = rows;r-->0;) for (size_t r = rows; r-- > 0;)
for (size_t c = cols;c-->0;) for (size_t c = cols; c-- > 0;)
res(c,r) = (*this)(r,c); res(c, r) = (*this)(r, c);
return res; return res;
} }
auto inverse() const { auto inverse() const
{
T invDet = T(1) / this->determinant(); T invDet = T(1) / this->determinant();
matrix_<R,C,T,RowMajor> inv; matrix_<R, C, T, RowMajor> inv;
for (int j = 0; j < C; j++) for (int j = 0; j < C; j++)
for (int i = 0; i < R; i++) for (int i = 0; i < R; i++)
{ {
const T minorDet = this->minor<R-1,C-1,RowMajor>(j,i).determinant(); const T minorDet = this->minor<R - 1, C - 1, RowMajor>(j, i).determinant();
const T coFactor = ((i + j) % 2 == 1) ? -minorDet : minorDet; const T coFactor = ((i + j) % 2 == 1) ? -minorDet : minorDet;
inv(i, j) = invDet * coFactor; inv(i, j) = invDet * coFactor;
} }
return inv; return inv;
} }
inline bool row_major() const { inline bool row_major() const
{
return RowMajor; return RowMajor;
} }
inline bool square() const { return R == C; } inline bool square() const { return R == C; }
inline const matrix_ operator+(const matrix_ &other) const
inline const matrix_ operator + (const matrix_ &other) const { {
matrix_ res(*this); matrix_ res(*this);
for (size_t r = 0; r < R;r++) for (size_t r = 0; r < R; r++)
for (size_t c = 0; c < C;c++) for (size_t c = 0; c < C; c++)
res(r,c) += other(r,c); res(r, c) += other(r, c);
return res; return res;
} }
inline const matrix_ operator - (const matrix_ &other) const { inline const matrix_ operator-(const matrix_ &other) const
{
matrix_ res(*this); matrix_ res(*this);
for (size_t r = 0; r < R;r++) for (size_t r = 0; r < R; r++)
for (size_t c = 0; c < C;c++) for (size_t c = 0; c < C; c++)
res(r,c) -= other(r,c); res(r, c) -= other(r, c);
return res; return res;
} }
auto row(size_t row_) const { auto row(size_t row_) const
{
row_type r; row_type r;
for (size_t i = 0; i < cols; i++) r[i] = (*this)(row_,i); for (size_t i = 0; i < cols; i++)
r[i] = (*this)(row_, i);
return r; return r;
} }
auto column(size_t col_) const { auto column(size_t col_) const
{
col_type c; col_type c;
for (size_t i = 0; i < rows; i++) c[i] = (*this)(i,col_); for (size_t i = 0; i < rows; i++)
c[i] = (*this)(i, col_);
return c; return c;
} }
static constexpr auto identity() { static constexpr auto identity()
{
matrix_ res; matrix_ res;
for (std::size_t r = 0;r < rows; r++) for (std::size_t r = 0; r < rows; r++)
for (std::size_t c = 0; c < cols; c++) for (std::size_t c = 0; c < cols; c++)
res(r,c) = (c == r) ? T(1) : T(0); res(r, c) = (c == r) ? T(1) : T(0);
return res; return res;
} }
}; };
template <> inline template <>
float matrix_<1,1,float>::determinant() const inline float matrix_<1, 1, float>::determinant() const
{ {
return (*this)(0,0); return (*this)(0, 0);
} }
template <> inline template <>
double matrix_<1,1,double>::determinant() const inline double matrix_<1, 1, double>::determinant() const
{ {
return (*this)(0,0); return (*this)(0, 0);
} }
template <typename T, std::size_t R, std::size_t Ca, std::size_t Cb>
template <typename T, std::size_t R, std::size_t Ca,std::size_t Cb> auto operator*(const matrix_<R, Ca, T> &A,
auto operator * (const matrix_<R, Ca, T>& A, const matrix_<R, Cb, T> &B)
const matrix_<R, Cb, T>& B {
) matrix_<R, Cb, T> result;
{ result.zero(); // zero the output
matrix_<R,Cb,T> result; result.zero(); // zero the output
for (size_t r = 0; r < R; r++) for (size_t r = 0; r < R; r++)
for (size_t c = 0; c < Cb; c++) for (size_t c = 0; c < Cb; c++)
for (size_t iI = 0; iI < R; iI++) for (size_t iI = 0; iI < R; iI++)
result(r,c) += A(r,iI) * B(iI,c); // inner product result(r, c) += A(r, iI) * B(iI, c); // inner product
return result; return result;
}
//
//
//
template <typename T> using matrix2x2_ = matrix_<2, 2, T>;
template <typename T> using matrix3x3_ = matrix_<3, 3, T>;
template <typename T> using matrix4x4_ = matrix_<4, 4, T>;
using matrix2x2f = matrix2x2_<float>;
using matrix2x2d = matrix2x2_<double>;
using matrix2x2 = matrix2x2_<real_t>;
using matrix3x3f = matrix3x3_<float>;
using matrix3x3d = matrix3x3_<double>;
using matrix3x3 = matrix3x3_<real_t>;
using matrix4x4f = matrix4x4_<float>;
using matrix4x4d = matrix4x4_<double>;
using matrix4x4 = matrix4x4_<real_t>;
}
#if __OLD
template <unsigned int R, unsigned int C, typename T>
class matrix_ : public matrixbase<T> {
T m[R*C];
public:
using typename matrixbase<T>::value_type;
using typename matrixbase<T>::size_type;
matrix_();
matrix_(const matrix_& mtc);
matrix_& operator = (const matrix_& other);
matrix_(std::initializer_list<T> il)
{
this->set(il);
} }
matrix_ set(std::initializer_list<T> il) //
{ // common matrix types
int i = 0; //
for (T e : il) (*this).at(i++) = e;
} template <typename T>
using matrix2x2_ = matrix_<2, 2, T>;
matrix_ transposed() const; template <typename T>
using matrix3x3_ = matrix_<3, 3, T>;
inline matrix_& operator *= (const T& b) { for (unsigned int i = this->cells(); i--> 0;) this->at(i) *= b; return *this; } template <typename T>
inline matrix_& operator /= (const T& b) { for (unsigned int i = this->cells(); i--> 0;) this->at(i) /= b; return *this; } using matrix4x4_ = matrix_<4, 4, T>;
inline matrix_& operator += (const T& b) { for (unsigned int i = this->cells(); i--> 0;) this->at(i) += b; return *this; }
inline matrix_& operator -= (const T& b) { for (unsigned int i = this->cells(); i--> 0;) this->at(i) -= b; return *this; } using matrix2x2f = matrix2x2_<float>;
using matrix2x2d = matrix2x2_<double>;
inline matrix_& operator += (const matrix_& other) { for (unsigned int i = this->cells(); i--> 0;) this->at(i) += other.at(i); return *this; } using matrix2x2 = matrix2x2_<real_t>;
inline matrix_& operator -= (const matrix_& other) { for (unsigned int i = this->cells(); i--> 0;) this->at(i) -= other.at(i); return *this; }
using matrix3x3f = matrix3x3_<float>;
inline const matrix_ normalized() const { using matrix3x3d = matrix3x3_<double>;
const T one_over_n = T(1) / this->norm(); using matrix3x3 = matrix3x3_<real_t>;
return *this * one_over_n;
} using matrix4x4f = matrix4x4_<float>;
using matrix4x4d = matrix4x4_<double>;
using matrix4x4 = matrix4x4_<real_t>;
inline const matrix_
get_inverse() const
{
matrix_ resMat;
for ( unsigned int r = 0; r < C; ++r) {
for ( unsigned int j = 0; j < R; ++j) {
short sgn = ( (r+j)%2) ? -1 : 1;
matrix_<R-1,C-1,T> minor;
this->get_minor(minor,r,j);
resMat.at(r,j) = minor.determinant() * sgn;
}
}
resMat = resMat.transposed();
resMat *= (static_cast<T>(1)/this->determinant());
return resMat;
}
inline
matrix_& invert() {
*this = this->get_inverse();
return *this;
}
void get_minor(matrix_<R-1,C-1,T>& res, unsigned int r0, unsigned int c0) const;
T determinant() const;
T squared_norm() const;
T norm() const;
matrix_<R,C,T>& operator *= (const matrix_<R,C,T>& rhs);
matrix_<R,C,T>& copy_from_data(const T* src) { for (unsigned int i = 0; i < R*C; ++i) { (*this).at(i) = src[i]; } return *this; }
const matrix_<C,R,T> reshape() const {
matrix_<C,R,T> m;
for (unsigned int r = 0; r < R; ++r)
for (unsigned int c = 0; c < C; ++c)
m(r,c) = (*this)(c,r);
return m;
}
const matrix_<R,1,T> get_column(unsigned int col) const {
matrix_<R,1,T> c; for (unsigned int r = 0; r < R; ++r) c(r,0) = (this)(r,col);
return c;
}
const matrix_<1,C,T> get_row(unsigned int row) const {
matrix_<1,C,T> r; for (unsigned int c = 0; c < C; ++c) r(0,c) = (this)(row,c);
return r;
}
void normalize();
template <unsigned int bC>
matrix_<R,bC,T> operator * (const matrix_<R,bC,T>& B) const
{
// aC == bR
// set all null
matrix_<R,bC,T> res;
res.fill(0);
// compute all resulting cells
for (unsigned int r = 0; r < R; ++r) {
for (unsigned int c = 0; c < bC; ++c) {
// building inner product
for (unsigned int iI = 0; iI < R;iI++) {
res.at(r,c) += (*this).at(r,iI) * B.at(iI,c);
}
}
}
return res;
}
};
/////////////////////////////////////////////////////////////////////////////
template <unsigned int aR, unsigned int aC, typename T>
inline matrix_<aR,aC,T> operator * (const matrix_<aR,aC,T>& a, const T& b)
{
matrix_<aR,aC,T> res;
for (unsigned int i = res.cells(); i--> 0;) res.at(i) = a.at(i) * b;
return res;
}
template <unsigned int aR, unsigned int aC, typename T>
inline matrix_<aR,aC,T> operator / (const matrix_<aR,aC,T>& a, const T& b)
{
matrix_<aR,aC,T> res; T oneOverB(1./b);
for (unsigned int i = res.cells(); i--> 0;) res.at(i) = a.at(i) * oneOverB;
return res;
}
template <unsigned int aR, unsigned int aC, typename T>
inline matrix_<aR,aC,T> operator + (const matrix_<aR,aC,T>& a, const T& b)
{
matrix_<aR,aC,T> res;
for (unsigned int i = res.cells(); i--> 0;) res.at(i) = a.at(i) + b;
return res;
}
template <unsigned int aR, unsigned int aC, typename T>
inline matrix_<aR,aC,T> operator - (const matrix_<aR,aC,T>& a, const T& b)
{
matrix_<aR,aC,T> res;
for (unsigned int i = res.cells(); i--> 0;) res.at(i) = a.at(i) - b;
return res;
}
template <unsigned int R, unsigned int C, typename T>
inline matrix_<R,C,T> operator + (const matrix_<R,C,T>& a, const matrix_<R,C,T>& b)
{
matrix_<R,C,T> res;
for (unsigned int i = res.cells(); i--> 0;) res.at(i) = a.at(i) + b.at(i);
return res;
}
template <unsigned int R, unsigned int C, typename T>
inline matrix_<R,C,T> operator - (const matrix_<R,C,T>& a, const matrix_<R,C,T>& b)
{
matrix_<R,C,T> res;
for (unsigned int i = res.cells(); i--> 0;) res.at(i) = a.at(i) - b.at(i);
return res;
}
//template <unsigned int aR,unsigned int aCbR, unsigned int bC, typename T>
//matrix_<aR,bC,T> static inline
//mul(const matrix_<aR,aCbR,T>& A, const matrix_<aCbR,bC,T>& B)
//{
// // aC == bR
// // set all null
// matrix_<aR,bC,T> res;
// res.fill(0);
// // compute all resulting cells
// for (unsigned int r = 0; r < aR; ++r) {
// for (unsigned int c = 0; c < bC; ++c) {
// // building inner product
// for (unsigned int iI = 0; iI < aCbR;iI++) {
// res.at(r,c) += A.at(r,iI) * B.at(iI,c);
// }
// }
// }
// return res;
//}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
template <unsigned int R, unsigned int C,typename T>
matrix_<R,C,T>& matrix_<R,C,T>::operator *= (const matrix_& rhs)
{
*this = *this * rhs;
return *this;
}
/////////////////////////////////////////////////////////////////////////////
template <unsigned int R, unsigned int C,typename T>
matrix_<R,C,T>::matrix_()
: matrixbase<T>(R,C,&m[0],true)
{
}
template <unsigned int R, unsigned int C,typename T>
matrix_<R,C,T>::matrix_(const matrix_ &mtc) :
matrixbase<T>(R,C,&m[0],true)
{
*this = mtc;
}
template <unsigned int R, unsigned int C,typename T>
matrix_<R,C,T> &matrix_<R,C,T>::operator = (const matrix_<R,C,T> &other)
{
if (this != &other)
for (unsigned int r = 0; r < R;++r)
for (unsigned int c = 0; c < C;++c)
(*this).at(r,c) = other.at(r,c);
return *this;
}
template <unsigned int R, unsigned int C,typename T>
matrix_<R,C,T> matrix_<R,C,T>::transposed() const
{
matrix_<C,R,T> res;
for (unsigned int r = this->rows();r-->0;)
for (unsigned int c = this->cols();c-->0;)
res.at(c,r) = this->at(r,c);
return res;
}
template <unsigned int R, unsigned int C,typename T>
void matrix_<R,C,T>::get_minor(matrix_<R-1,C-1,T>& res,unsigned int r0, unsigned int c0) const
{
unsigned int r = 0;
for (unsigned int ri = 0; ri < R; ri++)
{
unsigned int c = 0;
if (ri == r0) continue;
for (unsigned int ci = 0; ci < C; ci++)
{
if (ci == c0) continue;
res.data()[r*(C-1)+c] = this->data()[ri*C + ci];//(*this)(ri,ci);
c++;
}
r++;
}
}
template <unsigned int R, unsigned int C,typename T> inline
T matrix_<R,C,T>::determinant() const
{
T res(0);
matrix_<R-1,C-1,T> minor;
// using Laplace Expansion at compile time
for (unsigned int c = 0; c < C; c++) {
this->get_minor(minor,0,c);
res += ((c % 2 == 0) ? m[c] : -m[c]) * minor.determinant();
}
return res;
}
template <unsigned int R, unsigned int C,typename T> inline
T matrix_<R,C,T>::squared_norm() const
{
T res(0);
for (unsigned int r = 0; r < R; ++r)
for (unsigned int c = 0; c < C; ++c)
res += ((*this).at(r,c) * (*this).at(r,c));
return res;
}
template <unsigned int R, unsigned int C,typename T> inline
T matrix_<R,C,T>::norm() const
{
using std::sqrt;
return sqrt(this->squared_norm());
}
template <unsigned int R, unsigned int C,typename T> inline
void matrix_<R,C,T>::normalize()
{
T n = norm();
if (n > 0) {
for (unsigned int r = 0; r < R; ++r)
for (unsigned int c = 0; c < C; ++c)
(*this)(r,c) /= n;
}
}
/////////////////////////////////////////////////////////////////////////////
// explicit specializations
// 4x4
template <typename T>
class matrix4x4_ : public matrix_<4,4,T>
{
public:
using matrix_<4,4,T>::matrix_;
matrix4x4_(const matrix_<4,4,T>& i)
{
*this = i;
}
matrix4x4_& operator = (const matrix_<4,4,T>& rhs) {
if (this != &rhs){
this->at(0,0) = rhs.at(0,0);this->at(0,1) = rhs.at(0,1);this->at(0,2) = rhs.at(0,2);this->at(0,3) = rhs.at(0,3);
this->at(1,0) = rhs.at(1,0);this->at(1,1) = rhs.at(1,1);this->at(1,2) = rhs.at(1,2);this->at(1,3) = rhs.at(1,3);
this->at(2,0) = rhs.at(2,0);this->at(2,1) = rhs.at(2,1);this->at(2,2) = rhs.at(2,2);this->at(2,3) = rhs.at(2,3);
this->at(3,0) = rhs.at(3,0);this->at(3,1) = rhs.at(3,1);this->at(3,2) = rhs.at(3,2);this->at(3,3) = rhs.at(3,3);
}
return *this;
}
#if TACIT_PIXEL_STUFF_NEEDS_TO_MOVE_TO_SCENE
matrix<4,4,T>&
translate(const T& v1,const T& v2,const T& v3)
{
this->at(12) += v1;
this->at(13) += v2;
this->at(14) += v3;
return *this;
}
matrix<4,4,T>&
setTranslation(const T& v1,const T& v2,const T& v3)
{
this->identity();
this->at(12) = v1;
this->at(13) = v2;
this->at(14) = v3;
return *this;
}
matrix<4,4,T>&
setScale(const T& v1,const T& v2,const T& v3)
{
this->identity();
(*this)(0,0) = v1;
(*this)(1,1) = v2;
(*this)(2,2) = v3;
return *this;
}
matrix<4,4,T>&
scale(const T& v1,const T& v2,const T& v3)
{
(*this)(0,0) *= v1;
(*this)(1,1) *= v2;
(*this)(2,2) *= v3;
return *this;
}
static
matrix<4,4,T>
Translation(const T& v1,const T& v2,const T& v3)
{
matrix44<T> res = matrix44<T>::Identity(); res.setTranslation(v1,v2,v3);
return res;
}
inline static
matrix<4,4,T>
AngleAxis(const T& radianRotation,const matrix<3,1,T>& vec);
inline static
matrix<4,4,T> Frustum(T Left,T Right,T Bottom,T Top,T zNear,T zFar)
{
matrix<4,4,T> frustum;
frustum.fill(0);
frustum(0,0) = 2 * zNear/(Right-Left);
frustum(1,1) = 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) = -(2 * zFar*zNear)/(zFar-zNear); //D
frustum(2,3) = -1;
return frustum;
}
inline static
matrix<4,4,T> LookAt(const matrix<3,1,T>& eye,
const matrix<3,1,T>& target,
const matrix<3,1,T>& up);
matrix<4,4,T>&
rotate(const matrix<3,1,T>& vec, const T& rotation)
{
matrix44<T> rot = matrix44<T>::AngleAxis(rotation,vec); *this *= rot;
return *this;
}
#endif
};
//
// Specializations
//
template <> inline
float matrix_<1,1,float>::determinant() const
{
return this->at(0);
}
template <> inline
double matrix_<1,1,double>::determinant() const
{
return this->at(0);
}
#if TACIT_PIXEL_STUFF_NEEDS_TO_MOVE_TO_SCENE
template <typename T>
class matrix31 : public matrix<3,1,T> {
public:
using matrix<3,1,T>::operator =;
inline static
matrix<3,1,T> Cross(const matrix<3,1,T>& vec1, const matrix<3,1,T>& vec2)
{
matrix<3,1,T> res;
res.at(0) = vec1.at(1) * vec2.at(2) - vec2.at(1) * vec1.at(2);
res.at(1) = vec1.at(2) * vec2.at(0) - vec2.at(2) * vec1.at(0);
res.at(2) = vec1.at(0) * vec2.at(1) - vec2.at(0) * vec1.at(1);
return res;
}
};
template <typename T>
matrix<4,4,T>
matrix44<T>::AngleAxis(const T &radianRotation, const matrix<3,1,T> &vec)
{
matrix44<T> R = matrix44<T>::Identity();
if (vec.norm() < std::numeric_limits<T>::epsilon()) return R;
T _fCos = (T) cos (radianRotation);
matrix<3,1,T> _vCos(vec * (1 - _fCos));
matrix<3,1,T> _vSin(vec * (T)sin(radianRotation));
R.at(0) = (T) ((vec(0,0) * _vCos(0,0)) + _fCos);
R.at(4) = (T) ((vec(0,0) * _vCos(1,0)) - _vSin(2,0));
R.at(8) = (T) ((vec(0,0) * _vCos(2,0)) + _vSin(1,0));
R.at(1) = (T) ((vec(1,0) * _vCos(0,0)) + _vSin(2,0));
R.at(5) = (T) ((vec(1,0) * _vCos(1,0)) + _fCos);
R.at(9) = (T) ((vec(1,0) * _vCos(2,0)) - _vSin(0,0));
R.at(2) = (T) ((vec(2,0) * _vCos(0,0)) - _vSin(1,0));
R.at(6) = (T) ((vec(2,0) * _vCos(1,0)) + _vSin(0,0));
R.at(10)= (T) ((vec(2,0) * _vCos(2,0)) + _fCos);
return R;
}
template <typename T>
matrix<4,4,T>
matrix44<T>::LookAt(const matrix<3,1,T> &eye, const matrix<3,1,T> &target, const matrix<3,1,T> &up)
{
matrix<4,4,T> lookat = matrix<4,4,T>::Identity();
matrix<3,1,T> L; L = target - eye;
L.normalize();
matrix<3,1,T> S = matrix31<T>::Cross(L,up);
S.normalize();
matrix<3,1,T> Ud = matrix31<T>::Cross(S,L);
Ud.normalize();
lookat(0,0) = S.at(0);
lookat(0,1) = S.at(1);
lookat(0,2) = S.at(2);
lookat(0,3) = T(0);
lookat(1,0) = Ud.at(0);
lookat(1,1) = Ud.at(1);
lookat(1,2) = Ud.at(2);
lookat(1,3) = T(0);
lookat(2,0) = -L.at(0);
lookat(2,1) = -L.at(1);
lookat(2,2) = -L.at(2);
lookat(3,2) = T(0);
lookat(3,0) = eye.at(0);
lookat(3,1) = eye.at(1);
lookat(3,2) = eye.at(2);
lookat(3,3) = 1;
return lookat;
} }
#endif #endif
// predefined matricies
typedef matrix4x4_<real_t> matrix4x4;
typedef matrix4x4_<double> matrix4x4d;
typedef matrix4x4_<float> matrix4x4f;
}
#endif
#endif

View file

@ -1,4 +1,4 @@
cmake_minimum_required (VERSION 2.6) cmake_minimum_required (VERSION 3.20)
project (lua) project (lua)

View file

@ -124,7 +124,7 @@ struct renderer::impl {
this->_change_count = m.change_count(); this->_change_count = m.change_count();
#if 0 #if 1
// get errors // get errors
auto error = glGetError(); auto error = glGetError();
if (error != GL_NO_ERROR) { if (error != GL_NO_ERROR) {

View file

@ -159,17 +159,17 @@ struct shader::impl
void bind(int location,const matrix3x3f& m) void bind(int location,const matrix3x3f& m)
{ {
glUniformMatrix3fv(location,1,GL_FALSE,m.data); glUniformMatrix3fv(location,1,GL_FALSE,m.ptr());
} }
void bind(int location,const matrix4x4f& m) void bind(int location,const matrix4x4f& m)
{ {
glUniformMatrix4fv(location,1,GL_FALSE,m.data); glUniformMatrix4fv(location,1,GL_FALSE,m.ptr());
} }
void bind(int location,const vector4f& v) void bind(int location,const vector4f& v)
{ {
glUniform4fv(location,1,v.data); glUniform4fv(location,1,v.ptr());
} }
void bind(int location,const float& v) void bind(int location,const float& v)