summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2015-08-18 08:51:28 +0200
committerStanislaw Halik <sthalik@misaki.pl>2015-08-18 08:51:28 +0200
commitcfed344344b996aea1e6388031dc20b1d15a25f3 (patch)
treea881b7454f55e0d4b5e75ab8863f33532b27f493
parente6eb0bb0bc3f766953affe28cda7f8afbaab0985 (diff)
simple-mat: replace initializer_list with variadic ctor
Gives us type safety rather than argument count mismatch. Also there's no more narrowing conversion issue. Replace usages. Explicitly delete initializer_list ctor.
-rwxr-xr-xopentrack/simple-mat.hpp70
-rwxr-xr-xopentrack/tracker.cpp4
-rwxr-xr-xpose-widget/glwidget.cpp40
3 files changed, 76 insertions, 38 deletions
diff --git a/opentrack/simple-mat.hpp b/opentrack/simple-mat.hpp
index 9f0911cb..2b4cb72e 100755
--- a/opentrack/simple-mat.hpp
+++ b/opentrack/simple-mat.hpp
@@ -41,13 +41,43 @@ namespace {
enum { P = a == 1 ? 1 : 3 };
enum { Q = a == 1 ? 3 : 1 };
};
+
+ template<typename... arglist> struct assignable;
+
+ template<typename num>
+ struct assignable<num> {
+ enum { value = true };
+ };
+
+ template<typename num, typename t, typename... ts>
+ struct assignable<num, t, ts...> {
+ enum { value = std::is_assignable<num, t>::value && assignable<num, ts...>::value };
+ };
+
+ template<typename num, int h, int w, typename...ts>
+ struct is_arglist_correct
+ {
+ enum { value = h * w == sizeof...(ts) && assignable<num, ts...>::value };
+ };
}
template<typename num, int h_, int w_>
-struct Mat
+class Mat
{
num data[h_][w_];
+ static_assert(h_ > 0 && w_ > 0, "must have positive mat dimensions");
+
+ struct cast
+ {
+ template<typename u>
+ static num _(u x) { return static_cast<num>(x); }
+ };
+
+ Mat(std::initializer_list<num>&& xs) = delete;
+
+public:
+
// parameters w_ and h_ are rebound so that SFINAE occurs
// removing them causes a compile-time error -sh 20150811
@@ -101,9 +131,9 @@ struct Mat
typename std::enable_if<is_dim3<P, Q, R, S>::value, Mat<num, is_dim3<P, Q, R, S>::P, is_dim3<P, Q, R, S>::Q>>::type
cross(const Mat<num, R, S>& p2) const
{
- return Mat<num, R, S>({y() * p2.z() - p2.y() * z(),
- p2.x() * z() - x() * p2.z(),
- x() * p2.y() - y() * p2.x()});
+ return Mat<num, R, S>(y() * p2.z() - p2.y() * z(),
+ p2.x() * z() - x() * p2.z(),
+ x() * p2.y() - y() * p2.x());
}
Mat<num, h_, w_> operator+(const Mat<num, h_, w_>& other) const
@@ -161,9 +191,9 @@ struct Mat
num sum = num(0);
for (int k = 0; k < h_; k++)
- sum += data[j][k]*other.data[k][i];
+ sum += data[j][k]*other(k, i);
- ret.data[j][i] = sum;
+ ret(j, i) = sum;
}
return ret;
@@ -172,19 +202,29 @@ struct Mat
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<num>&& list)
+ template<typename... ts, typename = typename std::enable_if<is_arglist_correct<num, h_, w_, ts...>::value>>
+ Mat(ts const&... xs)
{
- auto iter = list.begin();
- for (int i = 0; i < h_; i++)
- for (int j = 0; j < w_; j++)
- data[i][j] = *iter++;
+ const std::initializer_list<num> init = { cast::_(xs)... };
+ auto iter = init.begin();
+ for (int j = 0; j < h_; j++)
+ for (int i = 0; i < w_; i++)
+ data[j][i] = *iter++;
+ }
+
+ template<typename t>
+ Mat(const t* xs)
+ {
+ for (int j = 0; j < h_; j++)
+ for (int i = 0; i < w_; i++)
+ data[j][i] = num(*xs++);
}
Mat()
{
for (int j = 0; j < h_; j++)
for (int i = 0; i < w_; i++)
- data[j][i] = 0;
+ data[j][i] = num(0);
}
Mat(const num* mem)
@@ -194,6 +234,8 @@ struct Mat
data[j][i] = mem[i*h_+j];
}
+ Mat(num* mem) : Mat(const_cast<const num*>(mem)) {}
+
// XXX add more operators as needed, third-party dependencies mostly
// not needed merely for matrix algebra -sh 20141030
@@ -237,10 +279,10 @@ struct Mat
if (std::abs(pitch_1) + std::abs(roll_1) + std::abs(yaw_1) > std::abs(pitch_2) + std::abs(roll_2) + std::abs(yaw_2))
{
bool fix_neg_pitch = pitch_1 < 0;
- return dmat<3, 1>({yaw_2, std::fmod(fix_neg_pitch ? -pi - pitch_1 : pitch_2, pi), roll_2});
+ return dmat<3, 1>(yaw_2, std::fmod(fix_neg_pitch ? -pi - pitch_1 : pitch_2, pi), roll_2);
}
else
- return dmat<3, 1>({yaw_1, pitch_1, roll_1});
+ return dmat<3, 1>(yaw_1, pitch_1, roll_1);
}
// tait-bryan angles, not euler
diff --git a/opentrack/tracker.cpp b/opentrack/tracker.cpp
index 22a8933c..403e87c5 100755
--- a/opentrack/tracker.cpp
+++ b/opentrack/tracker.cpp
@@ -52,7 +52,7 @@ double Tracker::map(double pos, Mapping& axis)
void Tracker::t_compensate(const rmat& rmat, const double* xyz, double* output, bool rz)
{
// TY is really yaw axis. need swapping accordingly.
- dmat<3, 1> tvec({ xyz[2], -xyz[0], -xyz[1] });
+ dmat<3, 1> tvec( xyz[2], -xyz[0], -xyz[1] );
const dmat<3, 1> ret = rmat * tvec;
if (!rz)
output[2] = ret(0);
@@ -107,7 +107,7 @@ void Tracker::logic()
};
const rmat cam = rmat::euler_to_rmat(off);
rmat r = rmat::euler_to_rmat(&value[Yaw]);
- dmat<3, 1> t { value(0), value(1), value(2) };
+ dmat<3, 1> t(value(0), value(1), value(2));
r = cam * r;
diff --git a/pose-widget/glwidget.cpp b/pose-widget/glwidget.cpp
index 6c04c4e6..334c845b 100755
--- a/pose-widget/glwidget.cpp
+++ b/pose-widget/glwidget.cpp
@@ -45,14 +45,10 @@ void GLWidget::rotateBy(float xAngle, float yAngle, float zAngle, float x, float
float c3 = cos(zAngle / 57.295781);
float s3 = sin(zAngle / 57.295781);
- float foo[] = {
- c2*c3, -c2*s3, s2,
- c1*s3+c3*s1*s2, c1*c3-s1*s2*s3, -c2*s1,
- s1*s3-c1*c3*s2, c3*s1+c1*s2*s3, c1*c2,
- };
-
- rotation = rmat(foo);
- translation = vec3({x, y, z});
+ rotation = rmat(c2*c3, -c2*s3, s2,
+ c1*s3+c3*s1*s2, c1*c3-s1*s2*s3, -c2*s1,
+ s1*s3-c1*c3*s2, c3*s1+c1*s2*s3, c1*c2);
+ translation = vec3(x, y, z);
update();
}
@@ -68,8 +64,8 @@ public:
const vec2& p3)
{
origin = p1;
- v0 = vec2({ p3.x() - p1.x(), p3.y() - p1.y() });
- v1 = vec2({ p2.x() - p1.x(), p2.y() - p1.y() });
+ v0 = vec2(p3.x() - p1.x(), p3.y() - p1.y());
+ v1 = vec2(p2.x() - p1.x(), p2.y() - p1.y());
dot00 = v0.dot(v0);
dot01 = v0.dot(v1);
dot11 = v1.dot(v1);
@@ -82,7 +78,7 @@ public:
const num dot02 = v0.dot(v2);
const num u = (dot11 * dot02 - dot01 * dot12) * invDenom;
const num v = (dot00 * dot12 - dot01 * dot02) * invDenom;
- uv = vec2({u, v});
+ uv = vec2(u, v);
return (u >= 0) && (v >= 0) && (u + v <= 1);
}
@@ -107,19 +103,19 @@ void GLWidget::project_quad_texture() {
const int sx = width(), sy = height();
vec2 pt[4];
const vec3 corners[] = {
- vec3({0., 0, 0}),
- vec3({sx-1, 0, 0}),
- vec3({0, sy-1, 0}),
- vec3({sx-1, sy-1, 0.})
+ vec3(0., 0, 0),
+ vec3(sx-1, 0, 0),
+ vec3(0, sy-1, 0),
+ vec3(sx-1, sy-1, 0.)
};
for (int i = 0; i < 4; i++) {
- pt[i] = project(vec3({corners[i].x() - sx/2, corners[i].y() - sy/2, 0}));
+ pt[i] = project(vec3(corners[i].x() - sx/2, corners[i].y() - sy/2, 0));
pt[i].x() += sx/2.;
pt[i].y() += sy/2.;
}
- vec3 normal1({0, 0, 1});
+ vec3 normal1(0, 0, 1);
vec3 normal2;
{
vec3 foo[3];
@@ -137,15 +133,15 @@ void GLWidget::project_quad_texture() {
vec2 p2[4];
for (int i = 0; i < 4; i++)
- p2[i] = vec2({pt[i].x(), pt[i].y()});
+ p2[i] = vec2(pt[i].x(), pt[i].y());
QImage texture(QSize(sx, sy), QImage::Format_RGB888);
QColor bgColor = palette().color(QPalette::Current, QPalette::Window);
texture.fill(bgColor);
const vec2 projected[2][3] = { { p2[0], p2[1], p2[2] }, { p2[3], p2[1], p2[2] } };
const vec2 origs[2][3] = {
- { vec2({0, 0}), vec2({ow-1, 0}), vec2({0, oh-1}) },
- { vec2({ow-1, oh-1}), vec2({ow-1, 0}), vec2({0, oh-1}) }
+ { vec2(0, 0), vec2(ow-1, 0), vec2(0, oh-1) },
+ { vec2(ow-1, oh-1), vec2(ow-1, 0), vec2(0, oh-1) }
};
const Triangle triangles[2] = {
Triangle(projected[0][0], projected[0][1], projected[0][2]),
@@ -167,7 +163,7 @@ void GLWidget::project_quad_texture() {
for (int y = 0; y < sy; y++)
for (int x = 0; x < sx; x++) {
- vec2 pos({x, y});
+ vec2 pos(x, y);
for (int i = 0; i < 2; i++) {
vec2 uv;
if (triangles[i].barycentric_coords(pos, uv))
@@ -205,7 +201,7 @@ GLWidget::vec2 GLWidget::project(const vec3 &point)
num y = h * translation.y() / 2 / -40;
if (std::abs(y) > h/2)
y = y > 0 ? h/2 : h/-2;
- return vec2 { z * (ret.x() + x), z * (ret.y() + y) };
+ return vec2(z * (ret.x() + x), z * (ret.y() + y));
}
GLWidget::vec3 GLWidget::project2(const vec3 &point)