00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <GL/glew.h>
00033 #include <wrap/gl/math.h>
00034 #include <wrap/gl/space.h>
00035 #include <wrap/gl/addons.h>
00036
00037 #include "activecoordinateframe.h"
00038
00039 using namespace vcg;
00040
00041 ActiveCoordinateFrame::ActiveCoordinateFrame(float size)
00042 :MovableCoordinateFrame(size),manipulator(NULL),drawmoves(true),
00043 drawrotations(true),move_button(Trackball::BUTTON_RIGHT),
00044 rotate_button(Trackball::BUTTON_LEFT),x_modifier(Trackball::BUTTON_NONE),
00045 y_modifier(Trackball::KEY_CTRL),z_modifier(Trackball::KEY_SHIFT),
00046 x_axis(1,0,0),y_axis(0,1,0),z_axis(0,0,1),rot_snap_rad(0.0f),mov_snap(0.0f),
00047 movx(move_button | x_modifier),movy(move_button | y_modifier),
00048 movz(move_button | z_modifier),rotx(rotate_button | x_modifier),
00049 roty(rotate_button | y_modifier),rotz(rotate_button | z_modifier)
00050 {
00051 manipulator=new Trackball();
00052 Update();
00053 }
00054
00055 ActiveCoordinateFrame::~ActiveCoordinateFrame()
00056 {
00057 if(manipulator!=NULL) {
00058 delete manipulator;
00059 manipulator=NULL;
00060 }
00061 }
00062
00063 void ActiveCoordinateFrame::Render(QGLWidget* glw)
00064 {
00065 glPushMatrix();
00066
00067 manipulator->radius=size;
00068 manipulator->center=position;
00069 manipulator->GetView();
00070 manipulator->Apply(false);
00071
00072 MovableCoordinateFrame::Render(glw);
00073
00074
00075 if(!drawmoves && !drawrotations){
00076 glPopMatrix();
00077 return;
00078 }
00079
00080 int current_mode=manipulator->current_button;
00081 bool rotating=(current_mode==rotx)||(current_mode==roty)||(current_mode==rotz);
00082 bool moving=(current_mode==movx)||(current_mode==movy)||(current_mode==movz);
00083
00084
00085 glPushAttrib(GL_ALL_ATTRIB_BITS);
00086 glDisable(GL_LIGHTING);
00087 glDisable(GL_TEXTURE_2D);
00088 glEnable(GL_BLEND);
00089 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00090 glEnable(GL_LINE_SMOOTH);
00091 glEnable(GL_POINT_SMOOTH);
00092
00093 QString message("this should never be seen");
00094 char axis_name;
00095 float verse;
00096
00097 if(current_mode==x_modifier){
00098 glColor(xcolor); message = QString("move or rotate on X axis");
00099 } else if(current_mode==y_modifier){
00100 glColor(ycolor); message = QString("move or rotate on Y axis");
00101 } else if(current_mode==z_modifier){
00102 glColor(zcolor); message = QString("move or rotate on Z axis");
00103 } else
00104 if(rotating && drawrotations){
00105 Point3f axis, arc_point;
00106 float angle;
00107 manipulator->track.rot.ToAxis(angle,axis);
00108 angle = -angle;
00109 if(current_mode==rotx){
00110 verse=((axis+x_axis).Norm()<1?-1:1);
00111 glColor(xcolor); axis_name='x'; arc_point=y_axis*(size*0.8);
00112 } else if(current_mode==roty) {
00113 verse=((axis+y_axis).Norm()<1?-1:1);
00114 glColor(ycolor); axis_name='y'; arc_point=z_axis*(size*0.8);
00115 } else if(current_mode==rotz) {
00116 verse=((axis+z_axis).Norm()<1?-1:1);
00117 glColor(zcolor); axis_name='z'; arc_point=x_axis*(size*0.8);
00118 } else assert(0);
00119
00120 float sign = ((angle*verse)<0) ? -1 : 1;
00121 float abs_angle = (angle<0) ? -angle : angle;
00122 angle = sign * ( (abs_angle>M_PI) ? 2*M_PI-abs_angle : abs_angle );
00123 axis = axis * verse;
00124 message = QString("rotated %1 deg around %2")
00125 .arg(((angle*180.0)/M_PI),5,'f',3)
00126 .arg(axis_name);
00127 Quaternionf arc_rot;
00128 arc_rot.FromAxis(angle/18.0,axis);
00129 glBegin(GL_POLYGON);
00130 glVertex(position);
00131 glVertex(position+arc_point);
00132 for(int i=0;i<18;i++){
00133 arc_point = arc_rot.Rotate(arc_point);
00134 glVertex(position+arc_point);
00135 }
00136 glEnd();
00137 } else if(moving && drawmoves){
00138 Point3f ntra=manipulator->track.tra;
00139 ntra.Normalize();
00140 if(current_mode==movx){
00141 verse=((ntra+x_axis).Norm()<1?-1:1);
00142 glColor(xcolor); axis_name='x';
00143 }else if(current_mode==movy){
00144 verse=((ntra+y_axis).Norm()<1?-1:1);
00145 glColor(ycolor); axis_name='y';
00146 }else if(current_mode==movz){
00147 verse=((ntra+z_axis).Norm()<1?-1:1);
00148 glColor(zcolor); axis_name='z';
00149 }else assert(0);
00150 message = QString("moved %1 units along %2")
00151 .arg(verse*manipulator->track.tra.Norm(),5,'f',3)
00152 .arg(axis_name);
00153 Point3f old_pos = position-manipulator->track.tra;
00154 glLineWidth(2*linewidth);
00155 glPointSize(4*linewidth);
00156 glBegin(GL_LINES);
00157 glVertex(position);
00158 glVertex(old_pos);
00159 glEnd();
00160 glBegin(GL_POINTS);
00161 glVertex(old_pos);
00162 glEnd();
00163 } else {
00164 glPopAttrib();
00165 glPopMatrix();
00166 return;
00167 }
00168
00169 font.setBold(true);
00170 font.setPixelSize(12);
00171 QPoint cursor=glw->mapFromGlobal(glw->cursor().pos());
00172 glw->renderText(cursor.x()+16,cursor.y()+16,message,font);
00173
00174 glPopAttrib();
00175 glPopMatrix();
00176 }
00177
00178 void ActiveCoordinateFrame::Reset(bool reset_position,bool reset_alignment)
00179 {
00180 MovableCoordinateFrame::Reset(reset_position, reset_alignment);
00181 Update();
00182 manipulator->Reset();
00183 }
00184
00185 void ActiveCoordinateFrame::SetPosition(const Point3f newpos)
00186 {
00187 MovableCoordinateFrame::SetPosition(newpos);
00188 Update();
00189 manipulator->Reset();
00190 }
00191
00192 void ActiveCoordinateFrame::SetRotation(const Quaternionf newrot)
00193 {
00194 MovableCoordinateFrame::SetRotation(newrot);
00195 Update();
00196 manipulator->Reset();
00197 }
00198
00199 void ActiveCoordinateFrame::AlignWith(const Point3f primary,const Point3f secondary,const char c1,const char c2)
00200 {
00201 MovableCoordinateFrame::AlignWith(primary,secondary,c1,c2);
00202 Update();
00203 manipulator->Reset();
00204 }
00205
00206 void ActiveCoordinateFrame::MouseDown(int x, int y, int button)
00207 {
00208 Move(manipulator->track);
00209 manipulator->Reset();
00210 manipulator->MouseDown(x,y,button);
00211 }
00212
00213 void ActiveCoordinateFrame::MouseMove(int x, int y)
00214 {
00215 manipulator->MouseMove(x,y);
00216 }
00217
00218 void ActiveCoordinateFrame::MouseUp(int x, int y, int button)
00219 {
00220 Move(manipulator->track);
00221 manipulator->Reset();
00222 manipulator->MouseUp(x, y, button);
00223 }
00224
00225 void ActiveCoordinateFrame::ButtonUp(int button)
00226 {
00227 Move(manipulator->track);
00228 manipulator->Reset();
00229 manipulator->ButtonUp((Trackball::Button) button);
00230 }
00231
00232 void ActiveCoordinateFrame::ButtonDown(int button)
00233 {
00234 Move(manipulator->track);
00235 manipulator->Reset();
00236 manipulator->ButtonDown((Trackball::Button) button);
00237 }
00238
00239 void ActiveCoordinateFrame::SetSnap(float rot_deg)
00240 {
00241 assert((rot_deg>=0.0)&&(rot_deg<=180));
00242 rot_snap_rad=rot_deg*M_PI/180.0;
00243 Update();
00244 }
00245
00246 void ActiveCoordinateFrame::Move(const Similarityf track)
00247 {
00248 MovableCoordinateFrame::Move(track);
00249 Update();
00250 }
00251
00252 void ActiveCoordinateFrame::Update()
00253 {
00254 movx=(move_button | x_modifier);
00255 movy=(move_button | y_modifier);
00256 movz=(move_button | z_modifier);
00257 rotx=(rotate_button | x_modifier);
00258 roty=(rotate_button | y_modifier);
00259 rotz=(rotate_button | z_modifier);
00260
00261 Point3f p=position;
00262 Quaternionf r=Inverse(rotation);
00263 x_axis=r.Rotate(Point3f(1,0,0));
00264 y_axis=r.Rotate(Point3f(0,1,0));
00265 z_axis=r.Rotate(Point3f(0,0,1));
00266
00267 manipulator->ClearModes();
00268 manipulator->modes[0] = NULL;
00269 manipulator->modes[movx] = new AxisMode(p,x_axis);
00270 manipulator->modes[movy] = new AxisMode(p,y_axis);
00271 manipulator->modes[movz] = new AxisMode(p,z_axis);
00272 manipulator->modes[rotx] = new CylinderMode(p,x_axis,rot_snap_rad);
00273 manipulator->modes[roty] = new CylinderMode(p,y_axis,rot_snap_rad);
00274 manipulator->modes[rotz] = new CylinderMode(p,z_axis,rot_snap_rad);
00275 manipulator->SetCurrentAction();
00276 }