2

Alright, so I'm trying to click and drag to rotate around an object using C++ and OpenGL. The way I have it is to use gluLookAt centered at the origin and I'm getting coordinates for the eye by using parametric equations for a sphere (eyex = 2* cos(theta) * sin(phi); eyey = 2* sin(theta) * sin(phi); eyez = 2* cos(phi);). This works mostly, as I can click and rotate horizontally, but when I try to rotate vertically it makes tight circles instead of rotating vertically. I'm trying to get the up vector by using the position of the camera and a vecter at a 90 degree angle along the x-z plane and taking the cross product of that. The code I have is as follows:

double dotProduct(double v1[], double v2[]) {
    return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
}
void mouseDown(int button, int state, int x, int y) {
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) {
        xpos = x;
        ypos = y;
    }
}
void mouseMovement(int x, int y) {
    diffx = x - xpos;
    diffy = y - ypos;
    xpos = x;
    ypos = y;
}
void camera (void) {

    theta += 2*PI * (-diffy/glutGet(GLUT_SCREEN_HEIGHT));
        phi += PI * (-diffx/glutGet(GLUT_WINDOW_WIDTH));

    eyex = 2* cos(theta) * sin(phi);
    eyey = 2* sin(theta) * sin(phi);
    eyez = 2* cos(phi);

    double rightv[3], rightt[3], eyes[3];
    rightv[0] = 2* cos(theta + 2/PI) * sin(phi);
    rightv[1] = 0;
    rightv[2] = 2* cos(phi);
    rightt[0] = rightv[0];
    rightt[1] = rightv[1];
    rightt[2] = rightv[2];
    rightv[0] = rightv[0] / sqrt(dotProduct(rightt, rightt));
    rightv[1] = rightv[1] / sqrt(dotProduct(rightt, rightt));
    rightv[2] = rightv[2] / sqrt(dotProduct(rightt, rightt));

    eyes[0] = eyex;
    eyes[1] = eyey;
    eyes[2] = eyez;
    upx = (eyey/sqrt(dotProduct(eyes,eyes)))*rightv[2] + (eyez/sqrt(dotProduct(eyes,eyes)))*rightv[1];
    upy = (eyez/sqrt(dotProduct(eyes,eyes)))*rightv[0] + (eyex/sqrt(dotProduct(eyes,eyes)))*rightv[2];
    upz = (eyex/sqrt(dotProduct(eyes,eyes)))*rightv[1] + (eyey/sqrt(dotProduct(eyes,eyes)))*rightv[0];

    diffx = 0;
    diffy = 0;
}         

I am somewhat basing things off of this but it doesn't work, so I tried my way instead.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Billy R
  • 41
  • 6

1 Answers1

2

This isn't exactly a solution for the way you are doing it but I did something similar the other day. I did it by using DX's D3DXMatrixRotationAxis and D3DXVec3TransformCoord The math behind the D3DXMatrixRotationAxis method can be found at the bottom of the following page: D3DXMatrixRotationAxis Math use this if you are unable to use DX. This will allow you to rotate around any axis you pass in. In my object code I keep track of a direction and up vector and I simply rotate each of these around the axis of movement(in your case the yaw and pitch).

To implement the fixed distance camera like this I would simply do the dot product of the current camera location and the origin location (if this never changes then you can simply do it once.) and then move the camera to the origin rotate it the amount you need then move it back with its new direction and up values.

Brendan
  • 161
  • 1
  • 6