summaryrefslogtreecommitdiffhomepage
path: root/pose-widget
diff options
context:
space:
mode:
Diffstat (limited to 'pose-widget')
-rw-r--r--pose-widget/pose-widget.cpp73
-rw-r--r--pose-widget/pose-widget.hpp21
2 files changed, 60 insertions, 34 deletions
diff --git a/pose-widget/pose-widget.cpp b/pose-widget/pose-widget.cpp
index a0653f17..e711a617 100644
--- a/pose-widget/pose-widget.cpp
+++ b/pose-widget/pose-widget.cpp
@@ -23,16 +23,14 @@ pose_transform::pose_transform(QWidget* dst) :
image2(w, h, QImage::Format_ARGB32),
width(w), height(h)
{
+ fresh.clear(std::memory_order_seq_cst);
+
front = QImage(QString(":/images/side1.png"));
back = QImage(QString(":/images/side6.png"));
image.fill(Qt::transparent);
image2.fill(Qt::transparent);
- rotateBy(0, 0, 0, 0, 0, 0, QSize(w, h));
-
- project_quad_texture();
-
start();
}
@@ -57,15 +55,15 @@ void pose_transform::run()
if (isInterruptionRequested())
break;
- static struct cruft
{
- void lock() {}
- void unlock() {}
- } not_a_mutex;
+ lock_guard l(mtx);
+ const cv_status st = cvar.wait_for(l, std::chrono::milliseconds(2000));
+ if (st == cv_status::timeout)
+ continue;
- const cv_status st = cvar.wait_for(not_a_mutex, std::chrono::milliseconds(2000));
- if (st == cv_status::timeout)
- continue;
+ rotation = rotation_;
+ translation = translation_;
+ }
project_quad_texture();
}
@@ -73,18 +71,22 @@ void pose_transform::run()
pose_widget::pose_widget(QWidget* parent) : QWidget(parent), xform(this)
{
+ rotate_sync(0,0,0, 0,0,0);
}
pose_widget::~pose_widget()
{
}
-void pose_widget::rotateBy(double xAngle, double yAngle, double zAngle, double x, double y, double z)
+void pose_widget::rotate_async(double xAngle, double yAngle, double zAngle, double x, double y, double z)
{
- xform.rotateBy(xAngle, yAngle, zAngle, x, y, z, size());
+ if (!xform.fresh.test_and_set(std::memory_order_seq_cst))
+ update();
+ xform.rotate_async(xAngle, yAngle, zAngle, x, y, z);
}
-void pose_transform::rotateBy(double xAngle, double yAngle, double zAngle, double x, double y, double z, const QSize& size)
+template<typename F>
+void pose_transform::with_rotate(F&& fun, double xAngle, double yAngle, double zAngle, double x, double y, double z)
{
using std::sin;
using std::cos;
@@ -98,11 +100,31 @@ void pose_transform::rotateBy(double xAngle, double yAngle, double zAngle, doubl
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
- rotation(i, j) = num(r(i, j));
+ rotation_(i, j) = num(r(i, j));
- translation = vec3(x, y, z);
+ translation_ = vec3(x, y, z);
- cvar.notify_one();
+ fun();
+}
+
+void pose_widget::rotate_sync(double xAngle, double yAngle, double zAngle, double x, double y, double z)
+{
+ xform.rotate_sync(xAngle, yAngle, zAngle, x, y, z);
+}
+
+void pose_transform::rotate_async(double xAngle, double yAngle, double zAngle, double x, double y, double z)
+{
+ with_rotate([this]() { cvar.notify_one(); }, xAngle, yAngle, zAngle, x, y, z);
+}
+
+void pose_transform::rotate_sync(double xAngle, double yAngle, double zAngle, double x, double y, double z)
+{
+ with_rotate([this]() {
+ rotation = rotation_;
+ translation = translation_;
+ project_quad_texture();
+ dst->repaint();
+ }, xAngle, yAngle, zAngle, x, y, z);
}
class Triangle {
@@ -182,8 +204,6 @@ void pose_transform::project_quad_texture()
const int sx = width - 1, sy = height - 1;
vec2 projected[3];
- lock_guard l(mtx);
-
{
const int sx_ = (sx - std::max(0, (sx - sy)/2)) * 5/9;
const int sy_ = (sy - std::max(0, (sy - sx)/2)) * 5/9;
@@ -318,21 +338,22 @@ void pose_transform::project_quad_texture()
lock_guard l2(mtx2);
image2.fill(Qt::transparent);
std::swap(image, image2);
+ fresh.clear();
}
-
- run_in_thread_async(dst->thread(), [this]() { dst->update(); });
}
vec2 pose_transform::project(const vec3 &point)
{
+ using std::fabsf;
+
vec3 ret = rotation * point;
- num z = std::max<num>(.75f, 1 + translation.z()/-60);
+ num z = std::max<num>(.5, 1 + translation.z()/-80);
num w = width, h = height;
- num x = w * translation.x() / 2 / -40;
- if (std::abs(x) > w/2)
+ num x = w * translation.x() / 2 / -80;
+ if (fabsf(x) > w/2)
x = x > 0 ? w/2 : w/-2;
- num y = h * translation.y() / 2 / -40;
- if (std::abs(y) > h/2)
+ num y = h * translation.y() / 2 / -80;
+ if (fabsf(y) > h/2)
y = y > 0 ? h/2 : h/-2;
return vec2(z * (ret.x() + x), z * (ret.y() + y));
}
diff --git a/pose-widget/pose-widget.hpp b/pose-widget/pose-widget.hpp
index 4f50008e..7befe72d 100644
--- a/pose-widget/pose-widget.hpp
+++ b/pose-widget/pose-widget.hpp
@@ -16,6 +16,7 @@
#include <mutex>
#include <condition_variable>
+#include <atomic>
#ifdef BUILD_POSE_WIDGET
# define POSE_WIDGET_EXPORT Q_DECL_EXPORT
@@ -46,9 +47,11 @@ class pose_transform final : private QThread
friend class pose_widget;
- void rotateBy(double xAngle, double yAngle, double zAngle,
- double x, double y, double z,
- const QSize& size);
+ void rotate_async(double xAngle, double yAngle, double zAngle, double x, double y, double z);
+ void rotate_sync(double xAngle, double yAngle, double zAngle, double x, double y, double z);
+
+ template<typename F>
+ void with_rotate(F&& fun, double xAngle, double yAngle, double zAngle, double x, double y, double z);
void run() override;
@@ -61,10 +64,10 @@ class pose_transform final : private QThread
static vec3 normal(const vec3& p1, const vec3& p2, const vec3& p3);
- rmat rotation;
- vec3 translation;
+ rmat rotation, rotation_;
+ vec3 translation, translation_;
- std::condition_variable_any cvar;
+ std::condition_variable cvar;
std::mutex mtx, mtx2;
QWidget* dst;
@@ -74,6 +77,8 @@ class pose_transform final : private QThread
int width, height;
+ std::atomic_flag fresh;
+
static constexpr int w = 320, h = 240;
};
@@ -82,8 +87,8 @@ class POSE_WIDGET_EXPORT pose_widget final : public QWidget
public:
pose_widget(QWidget *parent = nullptr);
~pose_widget();
- void rotateBy(double xAngle, double yAngle, double zAngle,
- double x, double y, double z);
+ void rotate_async(double xAngle, double yAngle, double zAngle, double x, double y, double z);
+ void rotate_sync(double xAngle, double yAngle, double zAngle, double x, double y, double z);
private:
pose_transform xform;