I'm using mouse motion to rotate my scene. It works fine if you just click and drag. The problem is when you release the mouse and then try to drag again: unless you do it from exactly the same spot, it seems to generate a new rotation when it should start from where you leave off. In other words, it doesn't modify the existing rotation matrix it seems to create a new one. I want it to make incremental changes.
Here is the relevant code, any ideas what's causing the problem?
int camera::begin_tracking(int x, int y,int width,int height)
{ tracking=true;
init_tb(x,y,width,height);
return 1;
}
int camera::stop_tracking(void)
{ tracking=false;
return 1;
}
//assumes that we are tracking
int camera::mouse_motion(int x, int y, int scr_width, int scr_height)
{ update_tb(x,y,scr_width,scr_height);
return 1;
}
void camera::trackball_ptov(int x, int y, int width, int height, float v[3])
{ float d, a;
/* project x,y onto a hemi-sphere centered within width, height */
v[0] = (2.0F*x - width) / width;
v[1] = (height - 2.0F*y) / height;
d = (float) sqrt(v[0]*v[0] + v[1]*v[1]);
v[2] = (float) cos((M_PI/2.0F) * ((d < 1.0F) ? d : 1.0F));
a = 1.0F / (float) sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
v[0] *= a;
v[1] *= a;
v[2] *= a;
}
void camera::init_tb(int x, int y, int width, int height )
{ trackball_ptov(x, y, width, height, last_pos);
}
void camera::update_tb(int x, int y, int width, int height)
{ float cur_pos[3], dx, dy, dz, angle, axis[3];
trackball_ptov( x, y, width, height, cur_pos );
dx = cur_pos[0] - last_pos[0];
dy = cur_pos[1] - last_pos[1];
dz = cur_pos[2] - last_pos[2];
if ( fabs(dx) > 0 || fabs(dy) > 0 || fabs(dz) > 0 )
{ angle = 90 * sqrt( dx*dx + dy*dy + dz*dz );
axis[0] = last_pos[1]*cur_pos[2] - last_pos[2]*cur_pos[1];
axis[1] = last_pos[2]*cur_pos[0] - last_pos[0]*cur_pos[2];
axis[2] = last_pos[0]*cur_pos[1] - last_pos[1]*cur_pos[0];
last_pos[0] = cur_pos[0];
last_pos[1] = cur_pos[1];
last_pos[2] = cur_pos[2];
glPushMatrix();
glLoadIdentity();
glRotatef(angle, axis[0], axis[1], axis[2]);
glMultMatrixf(tb_matrix);
glGetFloatv(GL_MODELVIEW_MATRIX, tb_matrix);
glPopMatrix();
}
}