implementing trackball rotation in opengl with FLTK: how to 'remember' successive rotations -
i'm working on fltk project (my first attempt @ guis , opengl: please bear me!) , have fl_gl_window displays various things depending on other widgets. 1 of options display contents of screen in 3d , have use able rotate in 3d mouse. in principle fine (i use fl::event functions in window handler achieve mouse/window positions , updated x,y,and z rotation angle applied in given order), way doing unintuitive (because of non-commuting rotations etc etc) implementing trackball (similar 1 here: http://www.csee.umbc.edu/~squire/download/trackball.c). understand how works , can rotate expected along correct axis first mouse drag. but...
the problem is, far can tell, in order work (ie multiple mouse drags) modelview matrix has maintained in order rotate object relative displayed orientation glrotatef applied every mouse drag. now, way have learned basic opengl fltk have draw() function called whenever changes, (as far can tell in fltk , me) has start scratch every time window has contents changes depending on user options (they might select 2d view etc. etc.) , draws things later not intended rotated. such can't see how code such modelview matrix sucessively updated every redraw as
a) on redraws need default no rotations (eg 2d option) (but still 'remember' rotation of 3d object)
b) rest of scene not rotated have pop matrix previous glortho...
immediate ways round can see are
1) build array of mouse drags , record accordingly that, example, on 10th mouse drag 10 rotations applied through glrotatef (i don't solution, ugly!)
2) record state of modelview matrix , save & load when appropriate. (i have read things suggest not how opengl supposed used?)
3) find mathematical transform manages reduce
glrotatef(ang1,ax1_1,ax2_1,ax3_1); glrotatef(ang2,ax1_2,ax2_2,ax3_2);
into
glrotatef(ang_tot,ax1_tot,ax2_tot,ax3_tot);
this solution most... pleasing.
(psuedo-)code:
class mygl : public fl_gl_window { void draw(); int handle(int); void map_to_trackball(double*); void calc_rotation(); //data including: double old_vec[3];//old mouse position on hemisphere double new_vec[3];//new mouse position on hemisphere double ang; //rotation amount; double rot[3]; //axis of rotation information public: mygl(int x, int y, int w, int h, const char *l): fl_gl_window(x, y, w, h, l) { //constructor... ang=0;rot[0]=0;rot[1]=0;rot[2]=0; } } void mygl::draw(){ if (3d){ glloadidentity(); glviewport(0,0,w(),h()); glortho(minx,maxx,miny,maxy,minz,maxz); glpushmatrix(); glrotatef(ang,rot[0],rot[1],rot[2]); //could save previous rotations , put them here ie: // glrotatef(ang_old,rot_old[0],rot_old[1],rot_old[2]); // seems clunky , require limitless number of rotations , memory if // user keeps tracking draw_object(); //including glbegin(), glvertex3f() , glend() etc. glpopmatrix(); // draw other non rotated things } } int mygl::handle(int e){ switch(e){ case: mouse_down map_to_trackball(old_vec);//projects starting mouse position onto hemisphere //if recording old rotations successive implementation in draw() // save them here. return 1; //<-- needed in fltk recognise drag event case: drag (//pseudocode map_to_trackball(new_vec);//projects current dragged mouse //position onto hemisphere calc_rotation(); //calculates , sets ang , rot[3] //using old_vec , new_vec break; } return fl_gl_window::handle(e); } void map_to_trackball(double* v){ // trackball_ptov() http://www.csee.umbc.edu/~squire/download/trackball.c } void calc_rotation(){ // mousemotion() http://www.csee.umbc.edu/~squire/download/trackball.c }
here decent implementation: https://github.com/sanko/fltk-2.0.x/blob/master/test/trackball.c .
Comments
Post a Comment