I have an assignment where I need to implement arcball using Opengl (~2.0). I have it more or less implemented but I have a some problems/issues/bugs and I'm not sure whats either causing them or how to solve.
Arcball rotation: Specically minor variance in mouse movement away from the axis I'm rotating on seems to "confuse" my program, causing artifacts (such as rotating briefly a completely different direction before resuming its current path).
Code:
void mouse_motion(int mx, int my)
{
float angleRadians;
//handles mouse motion events
if ( arcball_on && (mx != last_mx || my != last_my) ) {
// if left button is pressed
lArcAngle = arcAngle;
cout << " Last Angle: " << lArcAngle << endl;
cur_mx = mx;
cur_my = my;
glm::vec3 va = get_arcball_vector(last_mx, last_my);
glm::vec3 vb = get_arcball_vector(cur_mx, cur_my);
angleRadians = acos(min(1.0f, glm::dot(va, vb)));
arcAngle = ( ( angleRadians * 180 ) / 3.14159265 );
cout << " Angle in degrees: " << arcAngle << endl;
//cout << " ArcAngle after Mult: " << arcAngle << endl;
arcAngle += lArcAngle;
cout << " ArcAngle after accumulation: " << arcAngle << endl;
axis_in_world_coord = glm::cross(va, vb);
last_mx = cur_mx;
last_my = cur_my;
//glutPostRedisplay();
}
// other code for other functionality...
}
void display()
{
//Background color
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
// Matrix setup
glMatrixMode(GL_PROJECTION);
glViewport(0, 0, width, height);
glLoadIdentity();
gluPerspective(40, (float)width / (float)height, 0.1, 1000);
// Matrix setup
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -3);
int myFlagCtr = getFlagCtr();
//cout << "CRX: " << crx << " CRY: " << cry << " CRZ: " << crz << endl;
glPushMatrix();
//glRotatef(arcAngle, axis_in_world_coord.x, axis_in_world_coord.y, axis_in_world_coord.z);
glTranslatef(vec_blx, vec_bly, zScaling);
glRotatef(arcAngle, axis_in_world_coord.x, axis_in_world_coord.y, axis_in_world_coord.z);
if (myFlagCtr == 1) {
// Set Wireframe
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// color red
glColor3f(1.0f, 0.0f, 0.0f);
}
else if (myFlagCtr == 2) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// color red
glColor3f(1.0f, 0.0f, 0.0f);
glEnable(GL_POLYGON_OFFSET_LINE);
glPolygonOffset(-1.0, -1.0);
//draw object
blDrawMouseMesh();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// color red
glColor3f(0.0f, 1.0f, 0.0f);
}
else if (myFlagCtr == 0 || myFlagCtr == -1) {
// Bring back to Default
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glColor3f(0.53f, 0.12f, 0.47f);
}
blDrawMouseMesh();
glPopMatrix();
glutSwapBuffers();
}
As you can see between the two mouse vectors I get the angle between them, and the orthonogol vector which is the axis I am rotating around. But this only seems to work in a rather "dirty" and not particularly smooth way.
Edit: I now think the problem is the accumulation of degrees, when I switch axis's it remembers the angle from before, so it will "rotate" by the same amount previously plus the new angle, I'm not sure how to solve given the loading of the identity matrix causing non-accumulated values to reset.