2009-09-15 10 views
4

정확하게 설명하는 방법은 잘 모르겠지만 잘하면 내 뜻을 이해할 수있을 것입니다.OpenGL - 마우스로 카메라 움직이기

기본적으로 큐브를 그렸고 마우스를 드래그하여 모든면을 봅니다. 수평 또는 수직으로 만 회전해도 문제가 없지만이 두 가지를 결합하면 문제가 좀 이상해집니다.

수직으로 180도 회전하면 ('거꾸로 됨') 마우스를 수평으로 끌면 큐브가 마우스 동작의 반대 방향으로 회전합니다. 응용 프로그램이 gimbal lock을 앓고있는 것처럼

double camera_angle_h = 0; 
double camera_angle_v = 0; 

int drag_x_origin; 
int drag_y_origin; 
int dragging = 0; 

void display() { 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glLoadIdentity(); 
    gluLookAt(0.0, 0.0, 25.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); 
    glRotated(camera_angle_v, 1.0, 0.0, 0.0); 
    glRotated(camera_angle_h, 0.0, 1.0, 0.0); 

    draw_cube(); 

    glFlush(); 
    glutSwapBuffers(); 
} 

void mouse_click(int button, int state, int x, int y) { 
    if(button == GLUT_LEFT_BUTTON) { 
     if(state == GLUT_DOWN) { 
      dragging = 1; 
      drag_x_origin = x; 
      drag_y_origin = y; 
     } 
     else 
      dragging = 0; 
    } 
} 

void mouse_move(int x, int y) { 
    if(dragging) { 
     camera_angle_v += (y - drag_y_origin)*0.3; 
     camera_angle_h += (x - drag_x_origin)*0.3; 
     drag_x_origin = x; 
     drag_y_origin = y; 
    } 
} 

답변

2

그것은 소리 :

이 관련 코드입니다. 그것을 고칠 수있는 몇 가지 방법이 있습니다. 가장 쉬운 방법은 허용 된 회전을 클램핑하는 것입니다.

4

너는 오일러 각을 사용하고 있으므로 짐 벌락 문제가 있습니다.

간단한 해결책은 모델 행렬 내부에 회전을 저장하고 행렬 곱하기를 사용하여 2 개의 각도 만 저장하는 대신이 행렬을 회전시키는 것입니다. 자세한 내용은이 대답에

봐 : Will this cause gimbal-lock?

더 복잡한 솔루션 사원 수를 저장하는 것입니다

2

대부분의 응용 프로그램만을 위/아래로 회전 90도까지 허용; 그렇지 않으면보기가 거꾸로되어 예가 왼쪽에서 오른쪽으로 바뀝니다. 대부분의 어플리케이션에서, 당신은 세상을 거꾸로 뒤돌아 보면서 지금까지 회전하는 것은 의미가 없습니다.

또한 다른 답변자와 마찬가지로 짐벌 잠금 장치가 아닙니다. 짐벌 잠금 장치는 3 개 (또는 그 이상의?)의 회전 축을 필요로합니다. 간단히 말하면, 짐발 잠금은 한 축이 어느 한 방향으로 90도 회전되어 다른 두 축이 일렬로 정렬 된 경우입니다. 다른 두 축 중 하나를 회전하면 같은 효과가 발생합니다. 위키 백과 페이지의 중간에있는 비행기 이미지는 잘 보여줍니다.

어쨌든 가장 좋은 방법은 camera_angle_v을 (-90,90) 범위로 고정하는 것입니다. 즉, 추가하거나 빼기를 할 때마다 90보다 큰지 확인하고 90으로 설정하거나 -90보다 작 으면 -90으로 설정하십시오.

또한 v 각도가 정확히 90 또는 -90 일 때 나는 실제로 과거에 문제가 있었기 때문에 대신 +/- 89.9로 고정했습니다.

0

GLUT를 사용하고 있으므로 시스템에서이 코드를 처리 할 수 ​​있습니다. trackball.c 및 trackball.h 소스 파일을 살펴보십시오. 그 (것)들을 위해 인터넷 검색은 또한 근원을 찾아 낼 것이다. 이 정확한 문제를 해결하는 데 도움이되는 간단한 라이브러리입니다. 그것들을 사용하는 GLUT 예제는 dinospin, bounce 등입니다.

4

다른 사람들처럼 quaternions를 사용하는 것이 해결책입니다. Ken Shoemake는 그래픽 보석 IV의 쿼터니언과 오일러 각 사이의 변환을위한 훌륭한 코드를 제공합니다 (code samples here 참조, "오일러 각 변환"참조). 또한 회전 행렬과의 변환도 수행합니다.

마우스를 사용하여 회전을 원한다면 아마도 "황금 표준"은 그래픽 보석 IV의 Shoemake가 설명한 "Arcball"인터페이스입니다 (현재는 here).향상된 Arcball 버전은 Glut 라이브러리와 함께 "트랙볼"로 배포되며 클릭이 순환 영역 외부에서 발생할 때보다 직관적 인 인터페이스를 제공합니다. Gavin Bell에 의해 작성되었으며 herehere입니다. Bell의 트랙볼은 Blender project에서 사용하는 방법이며 상업용 패키지는 비슷한 것을 사용합니다.

관련 문제