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


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.