summaryrefslogtreecommitdiffhomepage
path: root/pose-widget/glwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pose-widget/glwidget.cpp')
-rw-r--r--pose-widget/glwidget.cpp232
1 files changed, 130 insertions, 102 deletions
diff --git a/pose-widget/glwidget.cpp b/pose-widget/glwidget.cpp
index b2ec68a7..5de26eef 100644
--- a/pose-widget/glwidget.cpp
+++ b/pose-widget/glwidget.cpp
@@ -51,44 +51,13 @@ void GLWidget::rotateBy(float xAngle, float yAngle, float zAngle, float x, float
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());
- dot00 = v0.dot(v0);
- dot01 = v0.dot(v1);
- dot11 = v1.dot(v1);
- const num denom = dot00 * dot11 - dot01 * dot01;
- if (std::fabs(denom) < 1e3f)
- {
- // for perpendicular plane, ensure u and v don't come out right
- // this is done here to avoid branching below, in a hot loop
- invDenom = 0;
- dot00 = dot01 = dot11 = 0;
- v0 = v1 = vec2(0, 0);
- }
- else
- invDenom = 1 / denom;
- }
- bool barycentric_coords(const vec2& px, vec2& uv) const
- {
- 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);
- }
+ Triangle(const vec2& p1, const vec2& p2, const vec2& p3);
+ bool barycentric_coords(const vec2& px, vec2& uv, int& i) const;
private:
num dot00, dot01, dot11, invDenom;
@@ -109,7 +78,56 @@ inline GLWidget::vec3 GLWidget::normal(const vec3& p1, const vec3& p2, const vec
return tmp * i;
}
-void GLWidget::project_quad_texture() {
+Triangle::Triangle(const Triangle::vec2& p1, const Triangle::vec2& p2, const Triangle::vec2& p3)
+{
+ using std::fabs;
+
+ origin = p1;
+
+ v0 = vec2(p3 - p1);
+ v1 = vec2(p2 - p1);
+
+ dot00 = v0.dot(v0);
+ dot01 = v0.dot(v1);
+ dot11 = v1.dot(v1);
+
+ const num denom = dot00 * dot11 - dot01 * dot01;
+
+ if (fabs(denom) < num(1e3))
+ {
+ // for perpendicular plane, ensure u and v don't come out right
+ // this is done here to avoid branching below, in a hot loop
+ invDenom = 0;
+ dot00 = dot01 = dot11 = 0;
+ v0 = v1 = vec2(0, 0);
+ }
+ else
+ invDenom = 1 / denom;
+}
+
+bool Triangle::barycentric_coords(const Triangle::vec2& px, Triangle::vec2& uv, int& i) const
+{
+ i = 0;
+ const vec2 v2 = px - origin;
+ const num dot12 = v1.dot(v2);
+ const num dot02 = v0.dot(v2);
+ num u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+ num v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+ if (!(u >= 0 && v >= 0))
+ return false;
+ if (u + v > 1)
+ {
+ i = 1;
+
+ u = 1 - u;
+ v = 1 - v;
+ }
+ uv = vec2(u, v);
+ return u >= 0 && v >= 0 && u + v <= 1;
+}
+
+void GLWidget::project_quad_texture()
+{
const int sx = width(), sy = height();
const int ow = front.width(), oh = front.height();
const vec3 corners[] = {
@@ -141,12 +159,27 @@ void GLWidget::project_quad_texture() {
QColor bgColor = palette().color(QPalette::Current, QPalette::Window);
texture.fill(bgColor);
- 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) }
+ const vec2 projected[2][3] =
+ {
+ { pt[0], pt[1], pt[2] },
+ { pt[3], pt[1], pt[2] }
};
- const Triangle triangles[2] = {
+
+ const vec2 origs[2][3] =
+ {
+ {
+ vec2(0, 0),
+ vec2(ow-1, 0),
+ vec2(0, oh-1) },
+ {
+ vec2(ow-1, oh-1),
+ vec2(0, oh-1),
+ vec2(ow-1, 0)
+ }
+ };
+
+ const Triangle triangles[2] =
+ {
Triangle(projected[0][0], projected[0][1], projected[0][2]),
Triangle(projected[1][0], projected[1][1], projected[1][2])
};
@@ -165,70 +198,64 @@ void GLWidget::project_quad_texture() {
return;
for (int y = 0; y < sy; y++)
- for (int x = 0; x < sx; x++) {
+ for (int x = 0; x < sx; x++)
+ {
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 float fx = origs[i][0].x()
- + uv.x() * (origs[i][2].x() - origs[i][0].x())
- + uv.y() * (origs[i][1].x() - origs[i][0].x());
- const float fy = origs[i][0].y()
- + uv.x() * (origs[i][2].y() - origs[i][0].y())
- + uv.y() * (origs[i][1].y() - origs[i][0].y());
-
- const int px_ = fx + .5f;
- const int py_ = fy + .5f;
- const int px = fx;
- const int py = fy;
- const float ax_ = fx - px;
- const float ay_ = fy - py;
- const float ax = 1.f - ax_;
- const float ay = 1.f - ay_;
-
- // 0, 0 -- ax, ay
- const int orig_pos = py * orig_pitch + px * orig_depth;
- const unsigned char r = orig[orig_pos + 2];
- const unsigned char g = orig[orig_pos + 1];
- const unsigned char b = orig[orig_pos + 0];
-
- // 1, 1 -- ax_, ay_
- const int orig_pos_ = py_ * orig_pitch + px_ * orig_depth;
- const unsigned char r_ = orig[orig_pos_ + 2];
- const unsigned char g_ = orig[orig_pos_ + 1];
- const unsigned char b_ = orig[orig_pos_ + 0];
-
- // 1, 0 -- ax_, ay
- const int orig_pos__ = py * orig_pitch + px_ * orig_depth;
- const unsigned char r__ = orig[orig_pos__ + 2];
- const unsigned char g__ = orig[orig_pos__ + 1];
- const unsigned char b__ = orig[orig_pos__ + 0];
-
- // 0, 1 -- ax, ay_
- const int orig_pos___ = py_ * orig_pitch + px * orig_depth;
- const unsigned char r___ = orig[orig_pos___ + 2];
- const unsigned char g___ = orig[orig_pos___ + 1];
- const unsigned char b___ = orig[orig_pos___ + 0];
-
- const unsigned char a1 = orig[orig_pos + 3];
- const unsigned char a2 = orig[orig_pos_ + 3];
- const unsigned char a3 = orig[orig_pos__ + 3];
- const unsigned char a4 = orig[orig_pos___ + 3];
-
- const int pos = y * dest_pitch + x * dest_depth;
-
- //qDebug() << "pos" << fx << fy << "uv" << ax << ay;
-
- dest[pos + 0] = (r * ax + r__ * ax_) * ay + (r___ * ax + r_ * ax_) * ay_;
- dest[pos + 1] = (g * ax + g__ * ax_) * ay + (g___ * ax + g_ * ax_) * ay_;
- dest[pos + 2] = (b * ax + b__ * ax_) * ay + (b___ * ax + b_ * ax_) * ay_;
- dest[pos + 3] = (a1 * ax + a3 * ax_) * ay + (a4 * ax + a2 * ax_) * ay_;
-
- break;
- }
+ vec2 uv;
+ int i;
+ if (triangles[0].barycentric_coords(pos, uv, i))
+ {
+ const float fx = origs[i][0].x()
+ + uv.x() * (origs[i][2].x() - origs[i][0].x())
+ + uv.y() * (origs[i][1].x() - origs[i][0].x());
+ const float fy = origs[i][0].y()
+ + uv.x() * (origs[i][2].y() - origs[i][0].y())
+ + uv.y() * (origs[i][1].y() - origs[i][0].y());
+
+ const int px_ = fx + .5f;
+ const int py_ = fy + .5f;
+ const int px = fx;
+ const int py = fy;
+ const float ax_ = fx - px;
+ const float ay_ = fy - py;
+ const float ax = 1.f - ax_;
+ const float ay = 1.f - ay_;
+
+ // 0, 0 -- ax, ay
+ const int orig_pos = py * orig_pitch + px * orig_depth;
+ const unsigned char r = orig[orig_pos + 2];
+ const unsigned char g = orig[orig_pos + 1];
+ const unsigned char b = orig[orig_pos + 0];
+
+ // 1, 1 -- ax_, ay_
+ const int orig_pos_ = py_ * orig_pitch + px_ * orig_depth;
+ const unsigned char r_ = orig[orig_pos_ + 2];
+ const unsigned char g_ = orig[orig_pos_ + 1];
+ const unsigned char b_ = orig[orig_pos_ + 0];
+
+ // 1, 0 -- ax_, ay
+ const int orig_pos__ = py * orig_pitch + px_ * orig_depth;
+ const unsigned char r__ = orig[orig_pos__ + 2];
+ const unsigned char g__ = orig[orig_pos__ + 1];
+ const unsigned char b__ = orig[orig_pos__ + 0];
+
+ // 0, 1 -- ax, ay_
+ const int orig_pos___ = py_ * orig_pitch + px * orig_depth;
+ const unsigned char r___ = orig[orig_pos___ + 2];
+ const unsigned char g___ = orig[orig_pos___ + 1];
+ const unsigned char b___ = orig[orig_pos___ + 0];
+
+ const unsigned char a1 = orig[orig_pos + 3];
+ const unsigned char a2 = orig[orig_pos_ + 3];
+ const unsigned char a3 = orig[orig_pos__ + 3];
+ const unsigned char a4 = orig[orig_pos___ + 3];
+
+ const int pos = y * dest_pitch + x * dest_depth;
+
+ dest[pos + 0] = (r * ax + r__ * ax_) * ay + (r___ * ax + r_ * ax_) * ay_;
+ dest[pos + 1] = (g * ax + g__ * ax_) * ay + (g___ * ax + g_ * ax_) * ay_;
+ dest[pos + 2] = (b * ax + b__ * ax_) * ay + (b___ * ax + b_ * ax_) * ay_;
+ dest[pos + 3] = (a1 * ax + a3 * ax_) * ay + (a4 * ax + a2 * ax_) * ay_;
}
}
image = texture;
@@ -252,3 +279,4 @@ GLWidget::vec3 GLWidget::project2(const vec3 &point)
{
return rotation * point;
}
+