Вращение вокруг сферы с использованием OpenGL и gluLookAt

Итак, я пытаюсь щелкнуть и перетащить, чтобы вращать объект, используя C++ и OpenGL. Я использую gluLookAt с центром в начале координат, и я получаю координаты глаза, используя параметрические уравнения для сферы (eyex = 2* cos(theta) * sin(phi); eyey = 2* sin( theta) * sin(phi); eyez = 2* cos(phi);). В основном это работает, так как я могу щелкнуть и повернуть по горизонтали, но когда я пытаюсь повернуть по вертикали, он делает узкие круги, а не вращается по вертикали. Я пытаюсь получить вектор вверх, используя положение камеры и вектор под углом 90 градусов вдоль плоскости xz и взяв векторное произведение этого. Код у меня следующий:

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;
}         

Я несколько основываюсь на этом, но это не работает, поэтому я попробовал свой путь вместо этого.


person Billy R    schedule 09.05.2012    source источник


Ответы (1)


Это не совсем решение для того, как вы это делаете, но на днях я сделал что-то подобное. Я сделал это, используя D3DXMatrixRotationAxis и D3DXVec3TransformCoord DX. Математику метода D3DXMatrixRotationAxis можно найти внизу следующей страницы: D3DXMatrixRotationAxis Math используйте это, если вы не можете использовать DX. Это позволит вам вращаться вокруг любой оси, которую вы проходите. В моем объектном коде я отслеживаю направление и вектор вверх, и я просто поворачиваю каждый из них вокруг оси движения (в вашем случае рыскание и шаг).

Чтобы реализовать камеру с фиксированным расстоянием, подобную этой, я бы просто сделал скалярное произведение текущего местоположения камеры и исходного местоположения (если это никогда не изменится, вы можете просто сделать это один раз.), а затем переместите камеру в исходное положение, поверните ее на величину затем вам нужно переместить его обратно с новым направлением и значениями вверх.

person Brendan    schedule 09.05.2012