카메라가 목표 지점에 대해 어떻게 선회 할 수 있습니까?


18

카메라가 우주를 자유롭게 이동하는 장면을 그리고 있습니다. 카메라 클래스는 시점 (또는 보기 ), 카메라 위치 및 위쪽 벡터를 추적합니다. 이 벡터 / 포인트는 gluLookAt로 전달됩니다.

이동 및 확대 / 축소는 구현하기가 거의 쉽지 않습니다. 그러나 나는 훨씬 더 문제가 될 수 있는 시점에 대한 로테이션을 찾고 있습니다. 두 각도를 취하는 Camera.rotate 함수를 작성하고 싶습니다. 하나는 위 / 아래로 회전하고 다른 하나 시점을 중심으로 가상의 구를 따라 왼쪽 / 오른쪽으로 회전 합니다.

이 작업을 수행하는 쉬운 방법이 있습니까?

나는 쿼터니언에 대해 (간결하게) 읽었지만 상대적으로 간단한 장면 구성으로 더 쉬운 해결책이 있는지 알고 싶었습니다.


축과 각도가 주어지면 도구 상자에 원점을 중심으로 점을 회전시키는 것이 있습니까?
sam hocevar

쿼터니언에 대한 나의 느슨한 이해 외에는 없습니다. 내가 이것을 더 많이 볼수록 쿼터니언이 답이 될 것이라고 생각합니다. 그러나 Quaternion 수식에 사용할 x, y 및 z 값을 계산하는 방법을 잘 모르겠습니다 .
Luke

나는 쿼터니언이 갈 길이 아니라고 말하지 않을 것입니다. 그들은 당신의 문제에 아주 좋은 해결책입니다. 그러나 쿼터니언 클래스와 GL 및 GLU와 상호 작용하는 방법이 필요하며 먼저 변환 행렬에 익숙해 져야한다고 생각합니다. 다른 사람들은 동의하지 않을 수 있습니다.
sam hocevar

회전 순서를 고려하십시오. 월드 공간으로 이동하거나 카메라 공간으로 이동하기 위해 회전을 적용하는 것은 다릅니다.
Charlie

답변:


25

당신이 요구하는 것을 아크 볼 회전이라고합니다. 쿼터니언은 작동 방식을 이해 한 경우에만 쉬운 솔루션입니다. 그러나 쿼터니언 없이도 동일한 결과를 얻을 수 있습니다.

전제 조건

일반적인 개체 회전 방법을 알고 있습니까? 원점에 객체가 있다고 가정 해 봅시다. 회전 방법을 알고 있습니까 (힌트 : 회전 행렬을 곱함)? 그렇다면 객체를 먼저 번역 한 다음 회전하면 어떻게 될지 알고 있다고 가정합니다.

각도 축에서 회전 행렬을 계산하는 방법을 알아야합니다 (파이처럼 쉽고 온라인에서 무수한 방정식을 살펴보십시오. 많은 방정식도 코드를 제공합니다)

해결책

  • 카메라의 위쪽오른쪽 벡터를 가져 옵니다 . 그것들은 정규화되어야합니다.
  • 초점에서 카메라로 벡터를 가져옵니다 (camPosition-Focus). 이것이 회전하려는 벡터입니다. 이 camFocusVector 라고합시다 .
  • 카메라와 관련하여 요 / 피치에서 얼마나 회전시킬 것인지 결정
  • 두 개의 회전 행렬을 만듭니다. 첫 번째 회전 행렬은 카메라 의 위쪽 을 사용자가 결정한 축 및 각도로 사용합니다. 두 번째 회전 매트릭스는 카메라 의 오른쪽 을 사용자가 결정한 축 및 피치 각도로 사용합니다.
  • 이제 새로운 회전 행렬로 camFocusVector 를 회전하십시오 . 이것은 이제 원점을 기준으로 한 카메라의 새로운 위치입니다. 물론 초점과 관련이 있기를 바랍니다.
  • 초점 위치를 camFocusVector에 추가하십시오 . 이것은 이제 카메라의 새로운 위치입니다. 그에 따라 카메라를 번역하십시오.
  • 마지막으로 lookAt () 함수를 호출하여 카메라가 포커스 포인트에 초점을 맞추도록 요청하십시오.

경고

카메라가 작동을 멈출 특정 사례 나 특이점을 찾아야합니다. 예를 들어 똑바로보고 / 위로. 나는 당신이 그것들을 다루는 방법을 알아낼 것입니다.

EDIT1 : 카메라의 직교 법선 벡터를 다시 계산하는 방법

카메라의 방향을 이미 알고 있습니다 ((cameraPos-focusPoint) .normalize ()). 이제 카메라의 업이 + Y라고 가정하십시오 (또는 세계의 현재 업 축은 ... 당신에게 달려 있습니다). 이제 위쪽 으로 방향 을 건너면 오른쪽 으로 갈 수 있습니다 . 끝난? 아니! 위 벡터는 더 이상 다른 두 벡터와 직교하지 않습니다. 즉, 크로스 해결하려면 우측 으로 방향을 당신은 당신의 새로운 도착 을 위로 .

있습니다 그람 슈미트 orthonormalize 벡터로 사용되어야한다 정말로이다.

다시 말하지만, (어떤 경우에는 작동하지 않을 것입니다이 같은주의 사항을주의 깊게 살펴 방향 에 평행 까지 예를 들면).


오른쪽 벡터는 normalize(up ^ camFocusVector)(또는 왼손잡이의 경우 반대)을 사용하여 얻을 수 있습니다 .
sam hocevar

지금까지는 잘 보이고 왼쪽 / 오른쪽 회전에 아름답게 작동했습니다 (업 벡터가 있으므로 쉽습니다). 귀하의 의견 @SamHocevar에서 '^'은 무슨 뜻입니까? 교차 제품입니까? 또한 번역을 한 후 업 벡터를 어떻게 다시 계산할 수 있습니까?
Luke

@Luke : 내 EDIT1 확인
Samaursa

1
@Samaursa 대단히 감사합니다. 귀하의 솔루션은 완벽하게 작동하며 그 과정에서 많은 것을 배웠습니다!
Luke

2
이것은 훌륭한 답변입니다. 설명해 주셔서 감사합니다. 필자의 경우 카메라가 XY 평면의 대상 점을 중심으로 회전하기를 원했기 때문에 모든 계산을 수행 한 후 항상 cameraRight.z를 0으로 설정 한 다음 cameraUp 벡터를 계산했습니다. 이것은 원하는 효과를 주었다. 방금 공유의 생각
codemonkey

1

필요한 것은 전형적인 ArcBall 카메라입니다. 기본적으로 대상 위치를 유지하고 해당 대상을 중심으로 "구형"으로 카메라를 움직일 수있는 카메라입니다.

그것은 XNA에 있지만 IIRC는 이전 에이 구현을 사용했으며 꽤 잘 작동했습니다.

http://roy-t.nl/index.php/2010/02/21/xna-simple-arcballcamera/


이 구현은 오른쪽 벡터를 따라 직접 이동하는 것으로 보이며 이는 적은 양의 값에 대한 아크 볼과 비슷합니다 . 그는 카메라를 움직이고 싶은 곳처럼 LookAt 지점을 움직이고 있습니다 (가까이 있지만 미묘하게 다릅니다). 나는 Samaursa가 이것을 달성하는 가장 간단한 방법을 제공했다고 생각합니다.
Luke

의견을 보내 주셔서 감사합니다. 이 구현을 "블랙 박스"로 약간 사용했음을 인정해야하지만 아무런 문제가 없습니다. 분명히 MoveCameraRight / MoveCameraForward 메소드에 대해 이야기하고 있었습니까? 이러한 방법은 카메라를 패닝하기 위해 추가되었지만 Arcball 인터페이스의 일부는 아닙니다. 대상 주위에서 카메라를 회전하려면 Yaw 또는 Pitch 속성을 변경하기 만하면됩니다.
David Gouveia

죄송합니다. 패닝 방법입니다. 요와 피치가 바뀔 때 그가 매트릭스에 더티 플래그를 어떻게 설정했는지 알지 못했습니다.
Luke

0

다음은 점을 중심으로 회전하는 코드입니다.

float distance;      // Straight line distance between the camera and look at point

// Calculate the camera position using the distance and angles
float camX = distance * -sinf(camAngleX*(M_PI/180)) * cosf((camAngleY)*(M_PI/180));
float camY = distance * -sinf((camAngleY)*(M_PI/180));
float camZ = -distance * cosf((camAngleX)*(M_PI/180)) * cosf((camAngleY)*(M_PI/180));

// Set the camera position and lookat point
gluLookAt(camX,camY,camZ,   // Camera position
          0.0, 0.0, 0.0,    // Look at point
          0.0, 1.0, 0.0);   // Up vector

1
기본적으로 내가 처음 한 방식입니다. 이런 식으로하는 데는 많은 문제가 있습니다 (적어도 나에게는). 기본적으로이 구현은 약 2 개의 고정 축만 회전합니다. 거의 북극 까지 회전한다고 가정 해 봅시다 . 그런 다음 오른쪽으로 돌 립니다. 전 세계 에서 카메라의 올바른 벡터를 따르지 않고 작은 원으로 회전하는 것을 발견 할 수 있습니다.
Luke

이제 언급했듯이 문제를 보는 두 가지 방법이 있습니다. 내 응용 프로그램에서 나는 ArcBall 카메라를 사용하여 바다의 대상 섬을 중심으로 회전했으며 3 축의 자유 축을 사용하면 섬이 거꾸로 보이거나 옆으로 보이는 것처럼 잘못 보일 것입니다.
David Gouveia

카메라 각도는 어떻게 얻습니까?
rafvasq

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.