From b7f128745f7a5a506ec2786bdb2645f4d0ec7c86 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 2 Nov 2014 07:03:22 +0100 Subject: rename pose widget subdir --- CMakeLists.txt | 5 +- ftnoir_posewidget/glwidget.cpp | 199 ------------------------------------- ftnoir_posewidget/glwidget.h | 90 ----------------- ftnoir_posewidget/images/side1.png | Bin 26449 -> 0 bytes ftnoir_posewidget/images/side6.png | Bin 26493 -> 0 bytes ftnoir_posewidget/posewidget.qrc | 6 -- pose-widget/glwidget.cpp | 199 +++++++++++++++++++++++++++++++++++++ pose-widget/glwidget.h | 90 +++++++++++++++++ pose-widget/images/side1.png | Bin 0 -> 26449 bytes pose-widget/images/side6.png | Bin 0 -> 26493 bytes pose-widget/posewidget.qrc | 6 ++ 11 files changed, 298 insertions(+), 297 deletions(-) delete mode 100644 ftnoir_posewidget/glwidget.cpp delete mode 100644 ftnoir_posewidget/glwidget.h delete mode 100644 ftnoir_posewidget/images/side1.png delete mode 100644 ftnoir_posewidget/images/side6.png delete mode 100644 ftnoir_posewidget/posewidget.qrc create mode 100644 pose-widget/glwidget.cpp create mode 100644 pose-widget/glwidget.h create mode 100644 pose-widget/images/side1.png create mode 100644 pose-widget/images/side6.png create mode 100644 pose-widget/posewidget.qrc diff --git a/CMakeLists.txt b/CMakeLists.txt index 162b6ba4..8f2ed953 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -228,9 +228,10 @@ opentrack_module(opentrack-csv ftnoir_csv) add_library(opentrack-csv STATIC ${opentrack-csv-c}) target_link_libraries(opentrack-csv ${MY_QT_LIBS}) -opentrack_module(opentrack-pose-widget ftnoir_posewidget) -include_directories(ftnoir_posewidget/) +opentrack_module(opentrack-pose-widget pose-widget) +include_directories(pose-widget/) # else Qt moc breaks opentrack_qt(opentrack-pose-widget) + add_library(opentrack-pose-widget STATIC ${opentrack-pose-widget-all}) target_link_libraries(opentrack-pose-widget ${MY_QT_LIBS}) diff --git a/ftnoir_posewidget/glwidget.cpp b/ftnoir_posewidget/glwidget.cpp deleted file mode 100644 index 07445c8a..00000000 --- a/ftnoir_posewidget/glwidget.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* Copyright (c) 2013 Stanislaw Halik - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - */ - -#include "glwidget.h" -#include -#include - -#include -#include - -GLWidget::GLWidget(QWidget *parent) : QWidget(parent) -{ - Q_INIT_RESOURCE(posewidget); - - front = QImage(QString(":/images/side1.png")); - back = QImage(QString(":/images/side6.png")); - rotateBy(0, 0, 0); -} - -GLWidget::~GLWidget() -{ -} - -void GLWidget::paintEvent ( QPaintEvent * event ) { - QPainter p(this); - project_quad_texture(); - p.drawImage(event->rect(), texture); -} - -void GLWidget::rotateBy(double xAngle, double yAngle, double zAngle) -{ - - 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, - }; - - for (int i = 0; i < 9; i++) - matrix[i] = foo[i]; - - update(); -} - -class Triangle { -public: - Triangle(const Vec2f& p1, - const Vec2f& p2, - const Vec2f& p3) - { - origin = p1; - v0 = Vec2f(p3.x - p1.x, p3.y - p1.y); - v1 = Vec2f(p2.x - p1.x, p2.y - p1.y); - dot00 = dot(v0, v0); - dot01 = dot(v0, v1); - dot11 = dot(v1, v1); - invDenom = 1 / (dot00 * dot11 - dot01 * dot01); - } - bool barycentric_coords(const Vec2f& px, Vec2f& uv) const - { - Vec2f v2(px.x - origin.x, px.y - origin.y); - double dot12 = dot(v1, v2); - double dot02 = dot(v0, v2); - double u = (dot11 * dot02 - dot01 * dot12) * invDenom; - double v = (dot00 * dot12 - dot01 * dot02) * invDenom; - uv.x = u; - uv.y = v; - return (u >= 0) && (v >= 0) && (u + v <= 1); - } - -private: - double dot00, dot01, dot11, invDenom; - Vec2f v0, v1, origin; - double dot(const Vec2f& p1, const Vec2f& p2) const { - return p1.x * p2.x + p1.y * p2.y; - } -}; - -static __inline Vec3f cross(const Vec3f& p1, const Vec3f& p2) -{ - return Vec3f(p1.y * p2.z - p2.y * p1.z, - p2.x * p1.z - p1.x * p2.z, - p1.x * p2.y - p1.y * p2.x); -} - -static __inline Vec3f normal(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3) -{ - Vec3f u(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z); - Vec3f v(p3.x - p1.x, p3.y - p1.y, p3.z - p1.z); - - Vec3f tmp = cross(u, v); - - double i = 1./sqrt(tmp.x * tmp.x + tmp.y * tmp.y + tmp.z * tmp.z); - - return Vec3f(i * tmp.x, i * tmp.y, i * tmp.z); -} - -void GLWidget::project_quad_texture() { - const int sx = width(), sy = height(); - Point pt[4]; - static Vec3f corners[] = { - Vec3f(0, 0, 0), - Vec3f(sx-1, 0, 0), - Vec3f(0, sy-1, 0), - Vec3f(sx-1, sy-1, 0) - }; - - for (int i = 0; i < 4; i++) { - pt[i] = project(Vec3f(corners[i].x - sx/2, corners[i].y - sy/2, 0)); - pt[i].x += sx/2; - pt[i].y += sy/2; - } - - Vec3f normal1(0, 0, 1); - Vec3f normal2; - { - Vec3f foo[3]; - for (int i = 0; i < 3; i++) - foo[i] = project2(corners[i]); - normal2 = normal(foo[0], foo[1], foo[2]); - } - - double dir = normal1.x * normal2.x + normal1.y * normal2.y + normal1.z * normal2.z; - - QImage& tex = dir < 0 ? back : front; - - int ow = tex.width(), oh = tex.height(); - - Vec2f p2[4]; - - for (int i = 0; i < 4; i++) - p2[i] = Vec2f(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 Vec2f projected[2][3] = { { p2[0], p2[1], p2[2] }, { p2[3], p2[1], p2[2] } }; - const Vec2f origs[2][3] = { - { Vec2f(0, 0), Vec2f(ow-1, 0), Vec2f(0, oh-1) }, - { Vec2f(ow-1, oh-1), Vec2f(ow-1, 0), Vec2f(0, oh-1) } - }; - const Triangle triangles[2] = { - Triangle(projected[0][0], projected[0][1], projected[0][2]), - Triangle(projected[1][0], projected[1][1], projected[1][2]) - }; - - int orig_pitch = tex.bytesPerLine(); - int dest_pitch = texture.bytesPerLine(); - - const unsigned char* orig = tex.bits(); - unsigned char* dest = texture.bits(); - - int orig_depth = tex.depth() / 8; - int dest_depth = texture.depth() / 8; - - /* image breakage? */ - if (orig_depth < 3) - return; - - for (int y = 0; y < sy; y++) - for (int x = 0; x < sx; x++) { - Vec2f pos; - pos.x = x; - pos.y = y; - for (int i = 0; i < 2; i++) { - Vec2f coords; - if (triangles[i].barycentric_coords(pos, coords)) - { - int px = origs[i][0].x - + coords.x * (origs[i][2].x - origs[i][0].x) - + coords.y * (origs[i][1].x - origs[i][0].x); - int py = origs[i][0].y - + coords.x * (origs[i][2].y - origs[i][0].y) - + coords.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]; - - dest[y * dest_pitch + x * dest_depth + 0] = r; - dest[y * dest_pitch + x * dest_depth + 1] = g; - dest[y * dest_pitch + x * dest_depth + 2] = b; - - break; - } - } - } - this->texture = texture; -} diff --git a/ftnoir_posewidget/glwidget.h b/ftnoir_posewidget/glwidget.h deleted file mode 100644 index 43a0f853..00000000 --- a/ftnoir_posewidget/glwidget.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright (c) 2013 Stanislaw Halik - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - */ - -#pragma once - -#include -#include -#include "opentrack/plugin-api.hpp" - -struct Point { - Point(int x, int y) : - x(x), y(y) - { - } - Point() : - x(0), y(0) - { - } - int x, y; -}; - -struct Vec3f { - double x, y, z; - Vec3f(double x, double y, double z) : - x(x), y(y), z(z) - { - } - Vec3f() : - x(0), y(0), z(0) - { - } -}; - -struct Vec2f { - double x, y; - Vec2f(double x, double y) : - x(x), y(y) - { - } - Vec2f() : - x(0), y(0) - { - } -}; - -class GLWidget : public QWidget -{ -public: - GLWidget(QWidget *parent); - ~GLWidget(); - void rotateBy(double xAngle, double yAngle, double zAngle); -protected: - void paintEvent ( QPaintEvent * event ) override; -private: - Point project(const Vec3f& point) { - Point rect; - - rect.x = point.x * matrix[0] - + point.y * matrix[1] - + point.z * matrix[2]; - rect.y = point.x * matrix[3] - + point.y * matrix[4] - + point.z * matrix[5]; - - return rect; - } - Vec3f project2(const Vec3f& point) { - Vec3f rect; - - rect.x = point.x * matrix[0] - + point.y * matrix[1] - + point.z * matrix[2]; - rect.y = point.x * matrix[3] - + point.y * matrix[4] - + point.z * matrix[5]; - rect.z = point.x * matrix[6] - + point.y * matrix[7] - + point.z * matrix[8]; - return rect; - } - void project_quad_texture(); - double matrix[9]; - QImage front; - QImage back; - QImage texture; -}; diff --git a/ftnoir_posewidget/images/side1.png b/ftnoir_posewidget/images/side1.png deleted file mode 100644 index d7467943..00000000 Binary files a/ftnoir_posewidget/images/side1.png and /dev/null differ diff --git a/ftnoir_posewidget/images/side6.png b/ftnoir_posewidget/images/side6.png deleted file mode 100644 index eaa80d7e..00000000 Binary files a/ftnoir_posewidget/images/side6.png and /dev/null differ diff --git a/ftnoir_posewidget/posewidget.qrc b/ftnoir_posewidget/posewidget.qrc deleted file mode 100644 index e799432f..00000000 --- a/ftnoir_posewidget/posewidget.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - images/side1.png - images/side6.png - - diff --git a/pose-widget/glwidget.cpp b/pose-widget/glwidget.cpp new file mode 100644 index 00000000..07445c8a --- /dev/null +++ b/pose-widget/glwidget.cpp @@ -0,0 +1,199 @@ +/* Copyright (c) 2013 Stanislaw Halik + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#include "glwidget.h" +#include +#include + +#include +#include + +GLWidget::GLWidget(QWidget *parent) : QWidget(parent) +{ + Q_INIT_RESOURCE(posewidget); + + front = QImage(QString(":/images/side1.png")); + back = QImage(QString(":/images/side6.png")); + rotateBy(0, 0, 0); +} + +GLWidget::~GLWidget() +{ +} + +void GLWidget::paintEvent ( QPaintEvent * event ) { + QPainter p(this); + project_quad_texture(); + p.drawImage(event->rect(), texture); +} + +void GLWidget::rotateBy(double xAngle, double yAngle, double zAngle) +{ + + 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, + }; + + for (int i = 0; i < 9; i++) + matrix[i] = foo[i]; + + update(); +} + +class Triangle { +public: + Triangle(const Vec2f& p1, + const Vec2f& p2, + const Vec2f& p3) + { + origin = p1; + v0 = Vec2f(p3.x - p1.x, p3.y - p1.y); + v1 = Vec2f(p2.x - p1.x, p2.y - p1.y); + dot00 = dot(v0, v0); + dot01 = dot(v0, v1); + dot11 = dot(v1, v1); + invDenom = 1 / (dot00 * dot11 - dot01 * dot01); + } + bool barycentric_coords(const Vec2f& px, Vec2f& uv) const + { + Vec2f v2(px.x - origin.x, px.y - origin.y); + double dot12 = dot(v1, v2); + double dot02 = dot(v0, v2); + double u = (dot11 * dot02 - dot01 * dot12) * invDenom; + double v = (dot00 * dot12 - dot01 * dot02) * invDenom; + uv.x = u; + uv.y = v; + return (u >= 0) && (v >= 0) && (u + v <= 1); + } + +private: + double dot00, dot01, dot11, invDenom; + Vec2f v0, v1, origin; + double dot(const Vec2f& p1, const Vec2f& p2) const { + return p1.x * p2.x + p1.y * p2.y; + } +}; + +static __inline Vec3f cross(const Vec3f& p1, const Vec3f& p2) +{ + return Vec3f(p1.y * p2.z - p2.y * p1.z, + p2.x * p1.z - p1.x * p2.z, + p1.x * p2.y - p1.y * p2.x); +} + +static __inline Vec3f normal(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3) +{ + Vec3f u(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z); + Vec3f v(p3.x - p1.x, p3.y - p1.y, p3.z - p1.z); + + Vec3f tmp = cross(u, v); + + double i = 1./sqrt(tmp.x * tmp.x + tmp.y * tmp.y + tmp.z * tmp.z); + + return Vec3f(i * tmp.x, i * tmp.y, i * tmp.z); +} + +void GLWidget::project_quad_texture() { + const int sx = width(), sy = height(); + Point pt[4]; + static Vec3f corners[] = { + Vec3f(0, 0, 0), + Vec3f(sx-1, 0, 0), + Vec3f(0, sy-1, 0), + Vec3f(sx-1, sy-1, 0) + }; + + for (int i = 0; i < 4; i++) { + pt[i] = project(Vec3f(corners[i].x - sx/2, corners[i].y - sy/2, 0)); + pt[i].x += sx/2; + pt[i].y += sy/2; + } + + Vec3f normal1(0, 0, 1); + Vec3f normal2; + { + Vec3f foo[3]; + for (int i = 0; i < 3; i++) + foo[i] = project2(corners[i]); + normal2 = normal(foo[0], foo[1], foo[2]); + } + + double dir = normal1.x * normal2.x + normal1.y * normal2.y + normal1.z * normal2.z; + + QImage& tex = dir < 0 ? back : front; + + int ow = tex.width(), oh = tex.height(); + + Vec2f p2[4]; + + for (int i = 0; i < 4; i++) + p2[i] = Vec2f(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 Vec2f projected[2][3] = { { p2[0], p2[1], p2[2] }, { p2[3], p2[1], p2[2] } }; + const Vec2f origs[2][3] = { + { Vec2f(0, 0), Vec2f(ow-1, 0), Vec2f(0, oh-1) }, + { Vec2f(ow-1, oh-1), Vec2f(ow-1, 0), Vec2f(0, oh-1) } + }; + const Triangle triangles[2] = { + Triangle(projected[0][0], projected[0][1], projected[0][2]), + Triangle(projected[1][0], projected[1][1], projected[1][2]) + }; + + int orig_pitch = tex.bytesPerLine(); + int dest_pitch = texture.bytesPerLine(); + + const unsigned char* orig = tex.bits(); + unsigned char* dest = texture.bits(); + + int orig_depth = tex.depth() / 8; + int dest_depth = texture.depth() / 8; + + /* image breakage? */ + if (orig_depth < 3) + return; + + for (int y = 0; y < sy; y++) + for (int x = 0; x < sx; x++) { + Vec2f pos; + pos.x = x; + pos.y = y; + for (int i = 0; i < 2; i++) { + Vec2f coords; + if (triangles[i].barycentric_coords(pos, coords)) + { + int px = origs[i][0].x + + coords.x * (origs[i][2].x - origs[i][0].x) + + coords.y * (origs[i][1].x - origs[i][0].x); + int py = origs[i][0].y + + coords.x * (origs[i][2].y - origs[i][0].y) + + coords.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]; + + dest[y * dest_pitch + x * dest_depth + 0] = r; + dest[y * dest_pitch + x * dest_depth + 1] = g; + dest[y * dest_pitch + x * dest_depth + 2] = b; + + break; + } + } + } + this->texture = texture; +} diff --git a/pose-widget/glwidget.h b/pose-widget/glwidget.h new file mode 100644 index 00000000..43a0f853 --- /dev/null +++ b/pose-widget/glwidget.h @@ -0,0 +1,90 @@ +/* Copyright (c) 2013 Stanislaw Halik + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#pragma once + +#include +#include +#include "opentrack/plugin-api.hpp" + +struct Point { + Point(int x, int y) : + x(x), y(y) + { + } + Point() : + x(0), y(0) + { + } + int x, y; +}; + +struct Vec3f { + double x, y, z; + Vec3f(double x, double y, double z) : + x(x), y(y), z(z) + { + } + Vec3f() : + x(0), y(0), z(0) + { + } +}; + +struct Vec2f { + double x, y; + Vec2f(double x, double y) : + x(x), y(y) + { + } + Vec2f() : + x(0), y(0) + { + } +}; + +class GLWidget : public QWidget +{ +public: + GLWidget(QWidget *parent); + ~GLWidget(); + void rotateBy(double xAngle, double yAngle, double zAngle); +protected: + void paintEvent ( QPaintEvent * event ) override; +private: + Point project(const Vec3f& point) { + Point rect; + + rect.x = point.x * matrix[0] + + point.y * matrix[1] + + point.z * matrix[2]; + rect.y = point.x * matrix[3] + + point.y * matrix[4] + + point.z * matrix[5]; + + return rect; + } + Vec3f project2(const Vec3f& point) { + Vec3f rect; + + rect.x = point.x * matrix[0] + + point.y * matrix[1] + + point.z * matrix[2]; + rect.y = point.x * matrix[3] + + point.y * matrix[4] + + point.z * matrix[5]; + rect.z = point.x * matrix[6] + + point.y * matrix[7] + + point.z * matrix[8]; + return rect; + } + void project_quad_texture(); + double matrix[9]; + QImage front; + QImage back; + QImage texture; +}; diff --git a/pose-widget/images/side1.png b/pose-widget/images/side1.png new file mode 100644 index 00000000..d7467943 Binary files /dev/null and b/pose-widget/images/side1.png differ diff --git a/pose-widget/images/side6.png b/pose-widget/images/side6.png new file mode 100644 index 00000000..eaa80d7e Binary files /dev/null and b/pose-widget/images/side6.png differ diff --git a/pose-widget/posewidget.qrc b/pose-widget/posewidget.qrc new file mode 100644 index 00000000..e799432f --- /dev/null +++ b/pose-widget/posewidget.qrc @@ -0,0 +1,6 @@ + + + images/side1.png + images/side6.png + + -- cgit v1.2.3