I have written some code that positions an object around the origin of the world and then allows the camera to rotate around (in all directions) it using the mouse (like a trackball).
This is the code for the mouse:
glGetIntegerv(GL_VIEWPORT,viewport);
glGetDoublev ( GL_MODELVIEW_MATRIX, modelview );
glGetDoublev ( GL_PROJECTION_MATRIX, projection );
switch(event) {
case MOUSE_LEFT_DRAG:
// if there is an old value of the mouse coordinates
// calculates the zoom factor based on the projection
// of the mouse coordinates onto a semisphere covering
// the window and centered in the origin, simulating
// a trackball movement
if(oldMouseX!=-9999 && oldMouseY!=-9999) {
// the radius of the semisphere will be
// half of the height if the window is wider than taller,
// half of the width otherwise
GLfloat radius = 300.0f;
// calculates projections of the new and old mouse
// coordinates onto the trackball
GLfloat oldX = (oldMouseX - radius)/radius;
GLfloat oldY = (radius - oldMouseY)/radius;
GLfloat newX = (mx - radius)/radius;
GLfloat newY = (radius - my)/radius;
GLfloat oldDistance = sqrt(oldX*oldX+oldY*oldY);
GLfloat newDistance = sqrt(newX*newX+newY*newY);
if(oldDistance>1) {
oldDistance = 1;
oldX = oldX / oldDistance;
oldY = oldY / oldDistance;
}
if(newDistance>1) {
newDistance = 1;
newX = newX / newDistance;
newY = newY / newDistance;
}
GLfloat oldZ = sqrt(1-oldDistance*oldDistance);
GLfloat newZ = sqrt(1-newDistance*newDistance);
// the 'move' vector is the distance between the two
// 'old' and 'new' vectors
GLfloat moveX = newX - oldX;
GLfloat moveY = newY - oldY;
GLfloat moveZ = newZ - oldZ;
moveAngle = 90*sqrt(moveX*moveX+moveY*moveY+moveZ*moveZ);
// the move axis is calculated as the cross product of the
// old and new vectors
moveAxisX = oldY*newZ - oldZ*newY;
moveAxisY = oldZ*newX - oldX*newZ;
moveAxisZ = oldX*newY - oldY*newX;
}
// update the old coordinates of the mouse to be
// equal to the new ones
oldMouseX = mx;
oldMouseY = my;
redraw();
gui->computeWindow->redraw();
return;
case MOUSE_LEFT_RELEASE:
oldMouseX = -9999;
oldMouseY = -9999;
return;
}
and this is the code for the drawing:
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthFunc(GL_LEQUAL);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,w(),h());
gluPerspective(40.0,1.0,0.1,200.0);
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
GLfloat LightPos[] = {cameraX, cameraY, cameraZ, 1};
GLfloat LightDir[] = {0, 0, -1, 0};
glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, LightDir);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 60.0f);
// this is for the position of the camera
gluLookAt(cameraX, cameraY, cameraZ,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
// if we are rotating
if(oldMouseX != -9999 && oldMouseY != -9999) {
glPushMatrix();
glLoadIdentity();
// applies the new rotation on the rotation matrix
glRotatef(moveAngle, moveAxisX, moveAxisY, moveAxisZ);
glMultMatrixf((GLfloat *)matrix);
// gets the result of the multiplication
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)matrix);
glPopMatrix();
}
// applies the rotation matrix to the MODELVIEW matrix
glMultMatrixf((GLfloat *)matrix); // Sets the actual transform
drawScene();
Now, my program allows the user to add another object in the screen. Initially the object is positioned in the center of the world (origin) kind of overlapping with the existing one.
I want to allow the user to keep rotating around like before with the camera using the LEFT mouse button, but I want also to use the RIGHT mouse button to rotate the new object (leaving the camera where it is)…
I think I need a piece of code similar to this one, using a new matrix and “adding” to the new matrix the small changes in rotation at each mouse movement… but I am confused.
Can anyone venture into helping me with this one? I would REALLY REALLY appreciate some help, as I feel kinda lost…
THANKS!!!