diff options
Diffstat (limited to 'pose-widget')
-rw-r--r-- | pose-widget/glwidget.cpp | 104 | ||||
-rw-r--r-- | pose-widget/glwidget.h | 12 |
2 files changed, 56 insertions, 60 deletions
diff --git a/pose-widget/glwidget.cpp b/pose-widget/glwidget.cpp index 8fbe046e..2cb858d7 100644 --- a/pose-widget/glwidget.cpp +++ b/pose-widget/glwidget.cpp @@ -31,38 +31,37 @@ void GLWidget::paintEvent ( QPaintEvent * event ) { p.drawImage(event->rect(), texture); } -void GLWidget::rotateBy(double xAngle, double yAngle, double zAngle, double x, double y, double z) +void GLWidget::rotateBy(float xAngle, float yAngle, float zAngle, float x, float y, float z) { - double c1 = cos(yAngle / 57.295781); - double s1 = sin(yAngle / 57.295781); - double c2 = cos(xAngle / 57.295781); - double s2 = sin(xAngle / 57.295781); - double c3 = cos(zAngle / 57.295781); - double s3 = sin(zAngle / 57.295781); - - double 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}); + float c1 = cos(yAngle / 57.295781); + float s1 = sin(yAngle / 57.295781); + float c2 = cos(xAngle / 57.295781); + float s2 = sin(xAngle / 57.295781); + float c3 = cos(zAngle / 57.295781); + float s3 = sin(zAngle / 57.295781); + + 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(); } class Triangle { + using num = GLWidget::num; + using vec2 = GLWidget::vec2; + using vec3 = GLWidget::vec3; public: Triangle(const vec2& p1, const vec2& p2, 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); @@ -70,28 +69,28 @@ public: } bool barycentric_coords(const vec2& px, vec2& uv) const { - vec2 v2 = px - origin; - double dot12 = v1.dot(v2); - double dot02 = v0.dot(v2); - double u = (dot11 * dot02 - dot01 * dot12) * invDenom; - double v = (dot00 * dot12 - dot01 * dot02) * invDenom; - uv = vec2({u, v}); + const vec2 v2 = px - origin; + const num dot12 = v1.dot(v2); + 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); return (u >= 0) && (v >= 0) && (u + v <= 1); } private: - double dot00, dot01, dot11, invDenom; + num dot00, dot01, dot11, invDenom; vec2 v0, v1, origin; }; -static __inline vec3 normal(const vec3& p1, const vec3& p2, const vec3& p3) +inline GLWidget::vec3 GLWidget::normal(const vec3& p1, const vec3& p2, const vec3& p3) { vec3 u = p2 - p1; vec3 v = p3 - p1; vec3 tmp = u.cross(v); - double i = 1./sqrt(tmp.dot(tmp)); + num i = 1./sqrt(tmp.dot(tmp)); return tmp * i; } @@ -100,19 +99,16 @@ 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].x() += sx/2.; - pt[i].y() += sy/2.; - } + for (int i = 0; i < 4; i++) + pt[i] = project(vec3(corners[i].x() - sx/2, corners[i].y() - sy/2, 0)) + vec2(sx/2, sy/2); - vec3 normal1({0, 0, 1}); + vec3 normal1(0, 0, 1); vec3 normal2; { vec3 foo[3]; @@ -121,24 +117,20 @@ void GLWidget::project_quad_texture() { normal2 = normal(foo[0], foo[1], foo[2]); } - double dir = normal1.dot(normal2); + num dir = normal1.dot(normal2); QImage& tex = dir < 0 ? back : front; int ow = tex.width(), oh = tex.height(); - vec2 p2[4]; - - for (int i = 0; i < 4; i++) - 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 projected[2][3] = { { pt[0], pt[1], pt[2] }, { pt[3], pt[1], pt[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]), @@ -160,9 +152,11 @@ void GLWidget::project_quad_texture() { for (int y = 0; y < sy; y++) for (int x = 0; x < sx; x++) { - vec2 pos({(double)x, (double)y}); + vec2 pos(x, y); for (int i = 0; i < 2; i++) { vec2 uv; + // XXX knowing center of the lookup pos, + // we have symmetry so only one lookup is needed -sh 20150831 if (triangles[i].barycentric_coords(pos, uv)) { const int px = origs[i][0].x() @@ -172,9 +166,9 @@ void GLWidget::project_quad_texture() { + uv.x() * (origs[i][2].y() - origs[i][0].y()) + uv.y() * (origs[i][1].y() - origs[i][0].y()); - int r = orig[py * orig_pitch + px * orig_depth + 2]; - int g = orig[py * orig_pitch + px * orig_depth + 1]; - int b = orig[py * orig_pitch + px * orig_depth + 0]; + const unsigned char r = orig[py * orig_pitch + px * orig_depth + 2]; + const unsigned char g = orig[py * orig_pitch + px * orig_depth + 1]; + const unsigned char b = orig[py * orig_pitch + px * orig_depth + 0]; dest[y * dest_pitch + x * dest_depth + 0] = r; dest[y * dest_pitch + x * dest_depth + 1] = g; @@ -187,21 +181,21 @@ void GLWidget::project_quad_texture() { this->texture = texture; } -vec2 GLWidget::project(const vec3 &point) +GLWidget::vec2 GLWidget::project(const vec3 &point) { vec3 ret = rotation * point; - double z = std::max(.75, 1. + translation.z()/-60.); + num z = std::max<num>(.75, 1. + translation.z()/-60); int w = width(), h = height(); - double x = w * translation.x() / 2. / -40.; + num x = w * translation.x() / 2 / -40; if (std::abs(x) > w/2) x = x > 0 ? w/2 : w/-2; - double y = h * translation.y() / 2. / -40.; + 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)); } -vec3 GLWidget::project2(const vec3 &point) +GLWidget::vec3 GLWidget::project2(const vec3 &point) { return rotation * point; } diff --git a/pose-widget/glwidget.h b/pose-widget/glwidget.h index 88961fbd..81517399 100644 --- a/pose-widget/glwidget.h +++ b/pose-widget/glwidget.h @@ -12,22 +12,24 @@ #include "opentrack/plugin-api.hpp" #include "opentrack/simple-mat.hpp" -typedef dmat<2, 1> vec2; -typedef dmat<3, 1> vec3; -typedef dmat<3, 3> rmat; - class GLWidget : public QWidget { public: + using num = float; + using vec2 = Mat<num, 2, 1>; + using vec3 = Mat<num, 3, 1>; + using rmat = Mat<num, 3, 3>; + GLWidget(QWidget *parent); ~GLWidget(); - void rotateBy(double xAngle, double yAngle, double zAngle, double x, double y, double z); + void rotateBy(float xAngle, float yAngle, float zAngle, float x, float y, float z); protected: void paintEvent ( QPaintEvent * event ) override; private: vec2 project(const vec3& point); vec3 project2(const vec3& point); void project_quad_texture(); + static inline vec3 normal(const vec3& p1, const vec3& p2, const vec3& p3); rmat rotation; vec3 translation; QImage front; |