diff options
| -rw-r--r-- | ftnoir_posewidget/glwidget.cpp | 81 | 
1 files changed, 42 insertions, 39 deletions
| diff --git a/ftnoir_posewidget/glwidget.cpp b/ftnoir_posewidget/glwidget.cpp index de19e91d..3ce44815 100644 --- a/ftnoir_posewidget/glwidget.cpp +++ b/ftnoir_posewidget/glwidget.cpp @@ -51,35 +51,39 @@ void GLWidget::rotateBy(double xAngle, double yAngle, double zAngle)      update();
  }
 -static __inline double dot(const Vec2f& p1, const Vec2f& p2) {
 -    return p1.x * p2.x + p1.y * p2.y;
 -}
 -
 -static bool barycentric_coords(const Vec2f& p1,
 -                               const Vec2f& p2,
 -                               const Vec2f& p3,
 -                               const Vec2f& px,
 -                               Vec2f& uv)
 -{
 -    Vec2f v0(p3.x - p1.x, p3.y - p1.y);
 -    Vec2f v1(p2.x - p1.x, p2.y - p1.y);
 -    Vec2f v2(px.x - p1.x, px.y - p1.y);
 -
 -    double dot00 = dot(v0, v0);
 -    double dot01 = dot(v0, v1);
 -    double dot02 = dot(v0, v2);
 -    double dot11 = dot(v1, v1);
 -    double dot12 = dot(v1, v2);
 -
 -    double invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
 -    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);
 -}
 +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 normal(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3)
  {
 @@ -146,8 +150,11 @@ void GLWidget::project_quad_texture() {          { 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])
 +    };
 -    double sqrt2 = std::sqrt(2.0);
      int orig_pitch = tex.bytesPerLine();
      int dest_pitch = texture.bytesPerLine();
 @@ -168,11 +175,7 @@ void GLWidget::project_quad_texture() {              pos.y = y;
              for (int i = 0; i < 2; i++) {
                  Vec2f coords;
 -                if (barycentric_coords(projected[i][0],
 -                                       projected[i][1],
 -                                       projected[i][2],
 -                                       pos,
 -                                       coords))
 +                if (triangles[i].barycentric_coords(pos, coords))
                  {
                      double qx = origs[i][0].x
                                  + coords.x * (origs[i][2].x - origs[i][0].x)
 @@ -190,10 +193,10 @@ void GLWidget::project_quad_texture() {                      double dx2 = qx2 - qx;
                      double dy2 = qy2 - qy;
 -                    double d1 = sqrt2 - std::sqrt(dx1 * dx1 + dy1 * dy1);
 -                    double d2 = sqrt2 - std::sqrt(dx2 * dx2 + dy2 * dy2);
 -                    double d3 = sqrt2 - std::sqrt(dx2 * dx2 + dy1 * dy1);
 -                    double d4 = sqrt2 - std::sqrt(dx1 * dx1 + dy2 * dy2);
 +                    double d1 = 2 - (dx1 * dx1 + dy1 * dy1);
 +                    double d2 = 2 - (dx2 * dx2 + dy2 * dy2);
 +                    double d3 = 2 - (dx2 * dx2 + dy1 * dy1);
 +                    double d4 = 2 - (dx1 * dx1 + dy2 * dy2);
                      double inv_norm = 1. / (d1 + d2 + d3 + d4);
 | 
