From 0c0f2728d48fca12b8d05cb97ff62c4fbe1855eb Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Mon, 1 Jun 2015 17:09:12 +0200 Subject: simple-mat: implement vector indexing --- opentrack/simple-mat.hpp | 148 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 113 insertions(+), 35 deletions(-) (limited to 'opentrack') diff --git a/opentrack/simple-mat.hpp b/opentrack/simple-mat.hpp index 158cb30d..649d7086 100644 --- a/opentrack/simple-mat.hpp +++ b/opentrack/simple-mat.hpp @@ -1,39 +1,117 @@ #pragma once #include +#include -template +namespace { + // last param to fool SFINAE into overloading + template + struct equals + { + enum { value = i == j }; + }; + template + struct maybe_add_swizzle + { + enum { value = (i == 1 || j == 1) && (i >= min || j >= min) }; + }; +} + +template struct Mat { - num data[h][w]; + num data[h_][w_]; + + template typename std::enable_if::value, num>::type + __inline operator()(int i) const { return data[i][0]; } + + template typename std::enable_if::value, num>::type + __inline operator()(int i) const { return data[0][i]; } + + template typename std::enable_if::value, num&>::type + __inline operator()(int i) { return data[i][0]; } + + template typename std::enable_if::value, num&>::type + __inline operator()(int i) { return data[0][i]; } + + template typename std::enable_if::value, num>::type + __inline x() const { return operator()(0); } + + template typename std::enable_if::value, num>::type + __inline y() const { return operator()(1); } - Mat operator+(const Mat& other) const + template typename std::enable_if::value, num>::type + __inline z() const { return operator()(2); } + + template typename std::enable_if::value, num>::type + __inline w() const { return operator()(3); } + + template typename std::enable_if::value, num&>::type + __inline x() { return operator()(0); } + + template typename std::enable_if::value, num&>::type + __inline y() { return operator()(1); } + + template typename std::enable_if::value, num&>::type + __inline z() { return operator()(2); } + + template typename std::enable_if::value, num&>::type + __inline w() { return operator()(3); } + + Mat operator+(const Mat& other) const { - Mat ret; - for (int j = 0; j < h; j++) + Mat ret; + for (int j = 0; j < h_; j++) for (int i = 0; i < w; i++) ret(j, i) = this->operator ()(j, i) + other(j, i); return ret; } - Mat operator-(const Mat& other) const + Mat operator-(const Mat& other) const { - Mat ret; - for (int j = 0; j < h; j++) - for (int i = 0; i < w; i++) + Mat ret; + for (int j = 0; j < h_; j++) + for (int i = 0; i < w_; i++) ret(j, i) = this->operator ()(j, i) - other(j, i); return ret; } - + + Mat operator+(const num& other) const + { + Mat ret; + for (int j = 0; j < h_; j++) + for (int i = 0; i < w; i++) + ret(j, i) = this->operator ()(j, i) + other; + return ret; + } + + Mat operator-(const num& other) const + { + Mat ret; + for (int j = 0; j < h_; j++) + for (int i = 0; i < w_; i++) + ret(j, i) = this->operator ()(j, i) - other; + return ret; + } + + Mat operator*(const num& other) const + { + Mat ret; + for (int j = 0; j < h_; j++) + for (int i = 0; i < w_; i++) + ret(j, i) = operator()(j, i) * other; + return ret; + } + template - Mat operator*(const Mat& other) const + Mat operator*(const Mat& other) const { - Mat ret; - for (int j = 0; j < w; j++) + Mat ret; + for (int j = 0; j < w_; j++) for (int i = 0; i < p; i++) { num sum = num(0); - for (int k = 0; k < h; k++) + for (int k = 0; k < h_; k++) sum += data[j][k]*other.data[k][i]; ret.data[j][i] = sum; @@ -42,59 +120,59 @@ struct Mat return ret; } - num operator()(int j, int i) const { return data[j][i]; } - num& operator()(int j, int i) { return data[j][i]; } + __inline num operator()(int j, int i) const { return data[j][i]; } + __inline num& operator()(int j, int i) { return data[j][i]; } Mat(std::initializer_list&& list) { auto iter = list.begin(); - for (int i = 0; i < h; i++) - for (int j = 0; j < w; j++) + for (int i = 0; i < h_; i++) + for (int j = 0; j < w_; j++) data[i][j] = *iter++; } Mat() { - for (int j = 0; j < h; j++) - for (int i = 0; i < w; i++) + for (int j = 0; j < h_; j++) + for (int i = 0; i < w_; i++) data[j][i] = 0; } Mat(const num* mem) { - for (int j = 0; j < h; j++) - for (int i = 0; i < w; i++) - data[j][i] = mem[i*h+j]; + for (int j = 0; j < h_; j++) + for (int i = 0; i < w_; i++) + data[j][i] = mem[i*h_+j]; } // XXX add more operators as needed, third-party dependencies mostly // not needed merely for matrix algebra -sh 20141030 - static Mat eye() + static Mat eye() { - Mat ret; - for (int j = 0; j < h; j++) - for (int i = 0; i < w; i++) + Mat ret; + for (int j = 0; j < h_; j++) + for (int i = 0; i < w_; i++) ret.data[j][i] = 0; - for (int i = 0; i < h; i++) + for (int i = 0; i < h_; i++) ret.data[i][i] = 1; return ret; } - Mat t() const + Mat t() const { - Mat ret; + Mat ret; - for (int j = 0; j < h; j++) - for (int i = 0; i < w; i++) + for (int j = 0; j < h_; j++) + for (int i = 0; i < w_; i++) ret.data[i][j] = data[j][i]; return ret; } - template using dmat = Mat; + template using dmat = Mat; // http://stackoverflow.com/a/18436193 static dmat<3, 1> rmat_to_euler(const dmat<3, 3>& R) @@ -151,5 +229,5 @@ struct Mat return dmat<3, 3>(foo); } }; - -template using dmat = Mat; + +template using dmat = Mat; -- cgit v1.2.3