Pārlūkot izejas kodu

bug fixes in rotate wiget, templates

Former-commit-id: 5bcce40c19bc3002afc086087fedda355ff6931b
Alec Jacobson (jalec 11 gadi atpakaļ
vecāks
revīzija
072cde3df4

+ 5 - 4
examples/rotate-widget/example.cpp

@@ -328,7 +328,7 @@ void mouse(int glutButton, int glutState, int mouse_x, int mouse_y)
           is_rotating = false;
           break;
         case 0:
-          bool widget_using = s.widget.down(mouse_x,mouse_y);
+          bool widget_using = s.widget.down(mouse_x,height-mouse_y);
           if(widget_using)
           {
             push_undo();
@@ -385,7 +385,7 @@ void mouse_drag(int mouse_x, int mouse_y)
 
   push_scene();
   push_object();
-  s.widget.drag(mouse_x,mouse_y);
+  s.widget.drag(mouse_x,height-mouse_y);
   pop_object();
   pop_scene();
 
@@ -439,7 +439,7 @@ void init_relative()
   Vmin = V.colwise().minCoeff();
   Vmid = 0.5*(Vmax + Vmin);
   bbd = (Vmax-Vmin).norm();
-  s.widget.pos = Vmid;
+  s.widget.pos = Vmin+0.3*(Vmax-Vmin);
 }
 
 void undo()
@@ -607,7 +607,7 @@ int main(int argc, char * argv[])
   // Init antweakbar
   glutInitDisplayString( "rgba depth double samples>=8 ");
   glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH)/2.0,glutGet(GLUT_SCREEN_HEIGHT)/2.0);
-  glutCreateWindow("upright");
+  glutCreateWindow("rotate-widget");
   glutDisplayFunc(display);
   glutReshapeFunc(reshape);
   glutKeyboardFunc(key);
@@ -629,6 +629,7 @@ int main(int argc, char * argv[])
   };
   glutTimerFunc(500, timer, 500);
 
+  s.camera.dolly_zoom(25-s.camera.m_angle);
   glutMainLoop();
 
 

+ 1 - 1
examples/skeleton/example.cpp

@@ -675,7 +675,7 @@ int main(int argc, char * argv[])
   rebar.TwAddVarRW("skeleton_on_top", TW_TYPE_BOOLCPP,&skeleton_on_top,"key=O");
   rebar.TwAddVarRW("wireframe", TW_TYPE_BOOLCPP,&wireframe,"key=l");
   TwType SkelStyleTypeTW = ReTwDefineEnumFromString("SkelStyleType",
-    "3d,vector graphics");
+    "3d,vector-graphics");
   rebar.TwAddVarRW("style",SkelStyleTypeTW,&skel_style,"key=s");
   rebar.load(REBAR_NAME);
 

+ 2 - 0
examples/upright/Makefile

@@ -21,6 +21,8 @@ ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework Ap
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(CARBON_LIB)
 
+CFLAGS+=-g
+
 upright: upright.o
 	g++ $(OPENMP) $(AFLAGS) $(CFLAGS) -o upright upright.o $(LIB)
 

+ 5 - 6
include/igl/ReAntTweakBar.cpp

@@ -125,12 +125,13 @@ namespace
 }
 
 IGL_INLINE igl::ReTwBar::ReTwBar():
- bar(NULL),rw_items(),cb_items()
+ bar(NULL),name(),rw_items(),cb_items()
 {
 }
 
 IGL_INLINE igl::ReTwBar::ReTwBar(const igl::ReTwBar & that):
   bar(that.bar),
+  name(that.name),
   rw_items(that.rw_items),
   cb_items(that.cb_items)
 {
@@ -150,12 +151,10 @@ IGL_INLINE igl::ReTwBar & igl::ReTwBar::operator=(const igl::ReTwBar & that)
 
 
 // BAR WRAPPERS
-IGL_INLINE void igl::ReTwBar::TwNewBar(const char *name)
+IGL_INLINE void igl::ReTwBar::TwNewBar(const char * _name)
 {
-  // double colon without anything in front of it means look for this in the
-  // global namespace... I hope...
-  this->name = name;
-  this->bar = ::TwNewBar(name);
+  this->name = _name;
+  this->bar = ::TwNewBar(_name);
 }
 
 IGL_INLINE int igl::ReTwBar::TwAddVarRW(

+ 69 - 34
include/igl/RotateWidget.h

@@ -5,16 +5,17 @@
 // This Source Code Form is subject to the terms of the Mozilla Public License 
 // v. 2.0. If a copy of the MPL was not distributed with this file, You can 
 // obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_HEADER_ONLY
-#define IGL_HEADER_ONLY
-#include <Eigen/Core>
+#ifndef IGL_ROTATE_WIDGET_H
+#define IGL_ROTATE_WIDGET_H
 #include <Eigen/Geometry>
+#include <Eigen/Core>
 #include <vector>
 #include <igl/material_colors.h>
 
 namespace igl
 {
-  // 3D Rotate tool widget 
+  // 3D Rotate tool widget similar to Maya's. Works best if field of view angle
+  // is less than ~25.
   class RotateWidget
   {
     public:
@@ -23,6 +24,7 @@ namespace igl
       inline static Eigen::Vector3d view_direction(const Eigen::Vector3d & pos);
       Eigen::Vector3d pos;
       Eigen::Quaterniond rot,down_rot;
+      // This line causes trouble if RotateWidget.h is included before bbw.h
       Eigen::Vector2d down_xy,drag_xy,down_dir;
       Eigen::Vector3d udown,udrag;
       double outer_radius_on_screen;
@@ -91,10 +93,7 @@ inline Eigen::Vector3d igl::RotateWidget::view_direction(const int x, const int
 {
   using namespace Eigen;
   using namespace igl;
-  Vector4i vp;
-  glGetIntegerv(GL_VIEWPORT,vp.data());
-  const int height = vp(3);
-  const Vector3d win_s(x,height-y,0), win_d(x,height-y,1);
+  const Vector3d win_s(x,y,0), win_d(x,y,1);
   const Vector3d s = unproject(win_s);
   const Vector3d d = unproject(win_d);
   return d-s;
@@ -125,10 +124,8 @@ inline bool igl::RotateWidget::intersect(const int x, const int y, Eigen::Vector
   using namespace Eigen;
   using namespace igl;
   Vector3d view = view_direction(x,y);
-  Vector4i vp;
-  glGetIntegerv(GL_VIEWPORT,vp.data());
   const Vector3d ppos = project(pos);
-  Vector3d uxy = unproject(Vector3d(x,vp(3)-y,ppos(2)));
+  Vector3d uxy = unproject(Vector3d(x,y,ppos(2)));
   double t0,t1;
   if(!ray_sphere_intersect(uxy,view,pos,unprojected_inner_radius(),t0,t1))
   {
@@ -150,16 +147,31 @@ inline double igl::RotateWidget::unprojected_inner_radius()
   return (pos-pos_off).norm();
 }
 
-inline Eigen::Vector3d igl::RotateWidget::unproject_onto(const int x, const int y)
+inline Eigen::Vector3d igl::RotateWidget::unproject_onto(
+  const int x, 
+  const int y)
 {
   using namespace Eigen;
   using namespace igl;
-  Vector4i vp;
-  glGetIntegerv(GL_VIEWPORT,vp.data());
-  const Vector3d ppos = project(pos);
-  Vector3d uxy = unproject( Vector3d(x,vp(3)-y,ppos(2)))-pos;
-  uxy /= unprojected_inner_radius()*outer_over_inner*outer_over_inner;
-  return uxy;
+  // KNOWN BUG: This projects to same depths as pos. I think what we actually
+  // want is The intersection with the plane perpendicular to the view
+  // direction at pos. If the field of view angle is small then this difference
+  // is negligible.
+  //const Vector3d ppos = project(pos);
+  //const Vector3d uxy = unproject( Vector3d(x,y,ppos(2)));
+  // http://en.wikipedia.org/wiki/Line-plane_intersection
+  //
+  // Hrrmmm. There's still something wrong here if the ball's in the corner of
+  // the screen. Am I somehow not accounting for perspective correctly?
+  //
+  // Q: What about just projecting the circle's equation and solving for the
+  // distance?
+  const Vector3d l0 = unproject(Vector3d(x,y,0));
+  const Vector3d l = unproject(Vector3d(x,y,1))-l0;
+  const Vector3d n = view_direction(pos);
+  const double t = (pos-l0).dot(n)/l.dot(n);
+  const Vector3d uxy = l0+t*l;
+  return (uxy-pos)/unprojected_inner_radius()*outer_over_inner*outer_over_inner;
 }
 
 inline bool igl::RotateWidget::down(const int x, const int y)
@@ -189,7 +201,7 @@ inline bool igl::RotateWidget::down(const int x, const int y)
     const bool is_hit = intersect(down_xy(0),down_xy(1),hit);
     if(!is_hit)
     {
-      cout<<"~~~!is_hit"<<endl;
+      //cout<<"~~~!is_hit"<<endl;
     }
     auto on_meridian = [&](
       const Vector3d & hit, 
@@ -224,9 +236,9 @@ inline bool igl::RotateWidget::down(const int x, const int y)
           dir3 = (rot*axis_q(a)*dir3).eval();
           down_dir = (project((hit+dir3).eval())-project(hit)).head(2);
           down_dir.normalize();
-          // flip y because y coordinate is going to be given backwards in
-          // drag()
-          down_dir(1) *= -1;
+          //// flip y because y coordinate is going to be given backwards in
+          //// drag()
+          //down_dir(1) *= -1;
         }
         return true;
       }
@@ -269,25 +281,30 @@ inline bool igl::RotateWidget::drag(const int x, const int y)
         const Vector2d A = down_xy - ppos.head(2);
         const Vector2d B = drag_xy - ppos.head(2);
         const double dtheta = atan2(A(0)*B(1)-A(1)*B(0),A(0)*B(0)+A(1)*B(1));
-        Vector3d view = view_direction(pos).normalized();
-        Quaterniond dq(AngleAxisd(dtheta,view));
+        Vector3d n = view_direction(pos).normalized();
+        Quaterniond dq(AngleAxisd(dtheta,-n));
+        //Vector3d n = udrag.cross(udown).normalized();
+        //Quaterniond dq(AngleAxisd(fabs(dtheta),-n));
         rot = dq * down_rot;
       }
       return true;
     case DOWN_TYPE_TRACKBALL:
       {
         Vector3d ppos = project(pos);
-        const int w = outer_radius_on_screen/outer_over_inner;
-        const int h = w;
+        const double r = (double)outer_radius_on_screen/outer_over_inner*2.0;
+        //const int h = w;
+        Vector4i vp;
+        glGetIntegerv(GL_VIEWPORT,vp.data());
+        const int h = vp(3);
         Quaterniond dq;
         trackball(
-          w,h,
+          r,r,
           1,
           Quaterniond::Identity(),
-          (down_xy(0)-ppos(0)+w/2),
-          (down_xy(1)-ppos(1)+h/2),
-          (     x-ppos(0)+w/2),
-          (     y-ppos(1)+h/2),
+          double(    down_xy(0)-ppos(0)    )+r/2.,
+          double((h-down_xy(1))-(h-ppos(1)))+r/2.,
+          double(             x-ppos(0)    )+r/2.,
+          double(         (h-y)-(h-ppos(1)))+r/2.,
           dq);
         // We've computed change in rotation according to this view:
         // R = mv * r, R' = rot * (mv * r)
@@ -307,7 +324,7 @@ inline bool igl::RotateWidget::drag(const int x, const int y)
   }
 }
 
-inline bool igl::RotateWidget::up(const int x, const int y)
+inline bool igl::RotateWidget::up(const int /*x*/, const int /*y*/)
 {
   down_type = DOWN_TYPE_NONE;
   return false;
@@ -323,6 +340,11 @@ inline void igl::RotateWidget::draw()
   using namespace Eigen;
   using namespace std;
   using namespace igl;
+  int l,dt;
+  glGetIntegerv(GL_LIGHTING,&l);
+  glGetIntegerv(GL_DEPTH_TEST,&dt);
+  double lw;
+  glGetDoublev(GL_LINE_WIDTH,&lw);
 
   glDisable(GL_LIGHTING);
   glDisable(GL_DEPTH_TEST);
@@ -408,7 +430,10 @@ inline void igl::RotateWidget::draw()
   glColor4fv(MAYA_GREY.data());
   draw_guide();
   glPopMatrix();
-  glEnable(GL_DEPTH_TEST);
+
+  glLineWidth(lw);
+  (l ? glEnable(GL_LIGHTING):glDisable(GL_LIGHTING));
+  (dt ? glEnable(GL_DEPTH_TEST):glDisable(GL_DEPTH_TEST));
 };
 
 inline void igl::RotateWidget::draw_guide()
@@ -416,6 +441,12 @@ inline void igl::RotateWidget::draw_guide()
   using namespace Eigen;
   using namespace std;
   using namespace igl;
+  int posm,post,cf;
+  glGetIntegerv(GL_CULL_FACE,&cf);
+  glGetIntegerv(GL_POINT_SMOOTH,&posm);
+  glGetIntegerv(GL_POLYGON_STIPPLE,&post);
+  double posi;
+  glGetDoublev(GL_POINT_SIZE,&posi);
   // http://www.codeproject.com/Articles/23444/A-Simple-OpenGL-Stipple-Polygon-Example-EP_OpenGL_
   const GLubyte halftone[] = {
     0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
@@ -450,6 +481,7 @@ inline void igl::RotateWidget::draw_guide()
   const Vector3d nudown(udown.normalized()), 
     nudrag(udrag.normalized());
   glPushMatrix();
+  glDisable(GL_CULL_FACE);
   glDisable(GL_POINT_SMOOTH);
   glPointSize(5.);
   glBegin(GL_POINTS);
@@ -475,8 +507,11 @@ inline void igl::RotateWidget::draw_guide()
   }
   glVertex3dv(nudrag.data());
   glEnd();
-  glDisable(GL_POLYGON_STIPPLE);
   glPopMatrix();
+  glPointSize(posi);
+  (cf?glEnable(GL_CULL_FACE):glDisable(GL_CULL_FACE));
+  (posm?glEnable(GL_POINT_SMOOTH):glDisable(GL_POINT_SMOOTH));
+  (post?glEnable(GL_POLYGON_STIPPLE):glDisable(GL_POLYGON_STIPPLE));
 }
 
 #endif

+ 1 - 1
include/igl/Viewport.h

@@ -42,7 +42,7 @@ namespace igl
     //
     // Inputs:
     //   my  mouse y-coordinate
-    //   wh  window weight
+    //   wh  window height
     // Returns y-coordinate in viewport
     int mouse_y(const int my,const int wh)
     {

+ 10 - 1
include/igl/draw_skeleton_3d.cpp

@@ -32,9 +32,14 @@ IGL_INLINE void igl::draw_skeleton_3d(
 {
   using namespace Eigen;
   using namespace std;
+  // old settings
+  int old_lighting=0;
+  double old_line_width=1;
+  glGetIntegerv(GL_LIGHTING,&old_lighting);
+  glGetDoublev(GL_LINE_WIDTH,&old_line_width);
   glDisable(GL_LIGHTING);
-  glColor4fv(MAYA_SEA_GREEN.data());
   glLineWidth(1.0);
+  glColor4fv(MAYA_SEA_GREEN.data());
 
   auto draw_sphere = [](const double r)
   {
@@ -109,9 +114,13 @@ IGL_INLINE void igl::draw_skeleton_3d(
     draw_sphere(r);
     glPopMatrix();
   }
+  // Reset settings
+  (old_lighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING));
+  glLineWidth(old_line_width);
 }
 
 #ifndef IGL_HEADER_ONLY
 // Explicit template instanciation
 template void igl::draw_skeleton_3d<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&);
+template void igl::draw_skeleton_3d<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
 #endif

+ 19 - 2
include/igl/draw_skeleton_vector_graphics.cpp

@@ -24,14 +24,18 @@ IGL_INLINE void igl::draw_skeleton_vector_graphics(
   const float * line_color)
 {
   using namespace Eigen;
-  glLineWidth(10.0);
 
+  int old_lighting=0;
+  double old_line_width=1;
+  glGetIntegerv(GL_LIGHTING,&old_lighting);
+  glGetDoublev(GL_LINE_WIDTH,&old_line_width);
   int cm;
   glGetIntegerv(GL_COLOR_MATERIAL,&cm);
   glDisable(GL_LIGHTING);
   glDisable(GL_LINE_STIPPLE);
   //glEnable(GL_POLYGON_OFFSET_FILL);
   glEnable(GL_COLOR_MATERIAL);
+  glLineWidth(10.0);
   glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
   float mat_ambient[4] = {0.1,0.1,0.1,1.0};
   float mat_specular[4] = {0.0,0.0,0.0,1.0};
@@ -71,6 +75,8 @@ IGL_INLINE void igl::draw_skeleton_vector_graphics(
   (cm ? glEnable(GL_COLOR_MATERIAL):glDisable(GL_COLOR_MATERIAL));
   //glDisable(GL_POLYGON_OFFSET_FILL);
   glEnable(GL_LIGHTING);
+  (old_lighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING));
+  glLineWidth(old_line_width);
 }
 
 template <typename DerivedC, typename DerivedBE, typename DerivedT>
@@ -78,6 +84,17 @@ IGL_INLINE void igl::draw_skeleton_vector_graphics(
   const Eigen::PlainObjectBase<DerivedC> & C,
   const Eigen::PlainObjectBase<DerivedBE> & BE,
   const Eigen::PlainObjectBase<DerivedT> & T)
+{
+  return draw_skeleton_vector_graphics(C,BE,T,BBW_POINT_COLOR,BBW_LINE_COLOR);
+}
+
+template <typename DerivedC, typename DerivedBE, typename DerivedT>
+IGL_INLINE void igl::draw_skeleton_vector_graphics(
+  const Eigen::PlainObjectBase<DerivedC> & C,
+  const Eigen::PlainObjectBase<DerivedBE> & BE,
+  const Eigen::PlainObjectBase<DerivedT> & T,
+  const float * point_color,
+  const float * line_color)
 {
   Eigen::PlainObjectBase<DerivedC> CT;
   Eigen::PlainObjectBase<DerivedBE> BET;
@@ -96,7 +113,7 @@ IGL_INLINE void igl::draw_skeleton_vector_graphics(
     CT.row(2*e) =   c0 * L + t;
     CT.row(2*e+1) = c1 * L + t;
   }
-  draw_skeleton_vector_graphics(CT,BET);
+  draw_skeleton_vector_graphics(CT,BET,point_color,line_color);
 }
 
 #ifndef IGL_HEADER_ONLY

+ 7 - 0
include/igl/draw_skeleton_vector_graphics.h

@@ -31,6 +31,13 @@ namespace igl
     const Eigen::MatrixXi & BE);
   //   T  #BE*(dim+1) by dim  matrix of stacked transposed bone transformations
   template <typename DerivedC, typename DerivedBE, typename DerivedT>
+  IGL_INLINE void draw_skeleton_vector_graphics(
+    const Eigen::PlainObjectBase<DerivedC> & C,
+    const Eigen::PlainObjectBase<DerivedBE> & BE,
+    const Eigen::PlainObjectBase<DerivedT> & T,
+    const float * point_color,
+    const float * line_color);
+  template <typename DerivedC, typename DerivedBE, typename DerivedT>
   IGL_INLINE void draw_skeleton_vector_graphics(
     const Eigen::PlainObjectBase<DerivedC> & C,
     const Eigen::PlainObjectBase<DerivedBE> & BE,

+ 1 - 0
include/igl/material_colors.h

@@ -7,6 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_MATERIAL_COLORS_H
 #define IGL_MATERIAL_COLORS_H
+#include <Eigen/Core>
 // Define constant material colors for use with opengl glMaterialfv
 // Most of these colors come from IGL publications
 namespace igl

+ 1 - 0
include/igl/project.cpp

@@ -116,6 +116,7 @@ template int igl::project<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<do
 template Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > igl::project<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&);
 template int igl::project<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> >&);
 template Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > igl::project<Eigen::Matrix<float, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&);
+template Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > igl::project<Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&);
 #endif
 
 #endif