2012-02-02 2 views
5

방향을 변경하려고하면 내 카메라가 한 지점을 중심으로 회전합니다. 카메라를 Y 축에서 30도 각도로 회전 시키면 카메라가 오른쪽으로 30도 보인 대신 카메라가보고 있던 지점을 중심으로 회전합니다.왜이 카메라로이 카메라로 회전합니까?

o is the camera, A and B are 3D models. The lines show line-of-sight. 
This is what I expect: 
    A B 
    | >/
    |/
    |/
    |/ 
    o 

This is what actually happens: 
    A B 
    |\ 
    | \ 
    | \ 
    | > \ 
      o 

이제는 카메라를 움직이려면 그 양의 역수로 세계를 움직여야합니다. 따라서 Z 축에서 +1을 움직이려면 Z 축에서 세계를 -1로 변환합니다. 저는 방위를 표현하기 위해 쿼터니언을 사용하기 때문에 카메라 쿼터니온의 역함수를 사용합니다. 방정식은 항상 단위 쿼터니언이므로 역수를 계산하는 대신 공액을 사용하여 최적화하여 올바른 양만큼 월드를 회전시킵니다. 여기

내가 q는 반전 사원 수있는 매트릭스로 사원 수로 변환하는 방법입니다

[... ... ... -x] 
|... ... ... -y| 
|... ... ... -z| 
[0  0  0  1] 

그리고 마지막으로 : 그 후

[1 - 2 * (q.y * q.y + q.z * q.z) 2 * (q.x * q.y - q.w * q.z)  2 * (q.x * q.z + q.w * q.y)   0] 
|2 * (q.x * q.y + q.w * q.z)  1 - 2 * (q.x * q.x + q.z * q.z) 2 * (q.y * q.z - q.w * q.x)   0| 
|2 * (q.x * q.z - q.w * q.y)  2 * (q.y * q.z + q.w * q.z)  1 - 2 * (q.x * q.x + q.y * q.y)  0| 
[0         0         0         1] 

, 나는 행렬의 평행 이동 요소를 설정 이를 모델 뷰 매트릭스 스택에 곱한 다음 모든 객체를 렌더링합니다. 나는이 수학이 정확하다고 확신하지만 기대했던 결과를 산출하지 못합니다. 분명히 앞으로와 오른쪽 벡터는 문제이므로 내 유일한 질문은 왜 그들이 틀렸는가와 내가 예상 한 결과를 얻고 싶다면 어떻게 설정해야 하는가입니다. 감사.

편집 : this guy's quaternion camera class에서 해결책을 찾았습니다. 먼저 i가했던 것처럼 회전 행렬을 만들지 만 첫 번째, 두 번째 및 세 번째 열 (각각 xa, ya 및 za)에서 행렬의 열 벡터를 가져옵니다. 이어서이 같은 행렬의 병진 성분 세트 : 다음, 생성 행렬은 모델 뷰 매트릭스 스택으로 곱해질 수

[... ... ... -xa.dotProduct(cameraPos)] 
|... ... ... -ya.dotProduct(cameraPos)| 
|... ... ... -za.dotProduct(cameraPos)| 
[... ... ... ...      ] 

을하고 완벽하게 작동한다.

+0

해결책을 편집하여 수락하십시오. 그것이 우리가 여기에서 해결 된 질문을 표시하는 방법입니다. 또한 나는 당신이 무슨 일이 일어나는지에 대해 약간의 설명을 할 자격이 있다고 생각합니다. 나는 이것에 대한 답을 쓸 것이다. – datenwolf

답변

1

편집 :이 남자의 쿼터니언 카메라 클래스에서 해결책을 찾았습니다. 먼저, 전에 수행했던 것처럼 회전 행렬을 구성하지만 그 다음에 열 행렬의 첫 번째, 두 번째 및 세 번째 열 (xa, ya 및 za 각각)의 행렬 벡터를 사용합니다. 그럼 이 같은 매트릭스 병진 성분 세트 : 다음, 생성 행렬은 모델 뷰 매트릭스 스택으로 곱해질 수

[... ... ... -xa.dotProduct(cameraPos)] 
|... ... ... -ya.dotProduct(cameraPos)| 
|... ... ... -za.dotProduct(cameraPos)| 
[... ... ... ...      ] 

을하고 완벽하게 작동한다.

예, 이것은 제가 제안한 것일뿐입니다. 조금 다릅니다. OpenGL에는 카메라가 없다는 것을 이해해야합니다. 대신에 반대 방향으로 월드를 움직여야하므로 역변환 행렬을 찾아야합니다.

카메라가 회전하고 움직입니다. 이것은 일을 아주 간단하게 만듭니다. 평행 이동은 반대 부호가있는 동일한 벡터이고, 회전 행렬의 역함수는 전치 행렬입니다 (열 및 행 교환). 이제는 OpenGL과 같은 균일 변환 행렬을보고하는 단계들을 사용

R t 
0 1 

좌상 3 × 3 회전 부분의 최 우측 열은 변환 벡터이다. 나머지는 이미 너 자신이라고 생각해.

0

솔직히 말해서, 모듈 - 뷰 행렬에 곱할 행렬을 찾으려고하면 실제로는 복잡하고 오류가 발생하기 쉽습니다. 혼란과 특별한 경우가 많이 있습니다. 예를 들어 90도 위로 볼 경우 두 축이 동일 해집니다. 논리적 인 문제는 다음과 같습니다. 머리를 뒤로 젖히면 맨 위 지점을 지나치므로 위쪽 벡터가 반전되어야합니다. 맞습니까? 그러나 0.0001도를 놓친다면 어떨까요? 그때 당신은 당신의 위로 벡터가 여전히 올라가고 있도록 그 지점을 돌아서 머리를 돌릴 수 있어야합니다.

내 의견으로는, 최선의 방법은 다른 관점에서 문제에 접근하는 것입니다. 의 두 가지 사례를 가정 해 봅시다 : 거꾸로 불가능

  • 을 :
    • 는 방향 카메라 위치와 위도/경도에 대한 포인트를 유지합니다. 간단한 sin/cos 연산을 사용하면 방향 벡터를 얻을 수 있습니다. 카메라 위치 외에도
      • , 모두 최대 및 대상 벡터 유지 : 귀하의 최대 벡터 (0, 1, 0)
      • 켜기 단순히 위도와 경도 거꾸로 가능
    • 변화이다.
    • 선회 할 때 right = target x up을 계산 한 다음 대상을 x * right + y * up으로 변경하십시오.
    • 그런 다음 대상 벡터를 정규화하고 새 값을 계산해야합니다. 그래도 많은 경우에 을 처리 할 수 ​​있습니다. 이 모든 후

, 당신은 단순히 gluLookAt를 호출합니다.

+0

"솔직히 말하면, 모듈 - 뷰 매트릭스에 곱하는 행렬을 찾기 위해 노력하는 것은 실제로 복잡하고 오류가 발생하기 쉽습니다." 아니, 그렇지 않아. 행렬은 상대 좌표 방향을 생각하는 가장 명백한 방법입니다. 처음 세 열은 변형 된 좌표계의 기본 벡터 중 하나입니다. 네 번째 열은 상대 번역입니다. 보기 및 대상 벡터에서 카메라 매트릭을 기록한 다음 그 사이의 모든 삼각법을 사용하는 것이 훨씬 쉽습니다. – datenwolf

+0

나는 그것을 안다. 제가 말하고자하는 것은, 예를 들어 다음 프레임까지 3 가지 다른 종류의 움직임 (예를 들어, 움직이고, 뒤틀리고 말하기)이 있다면, 위치/위도/경도로 그렇게하고 마침내 행렬로 변환하는 것이 훨씬 쉽습니다. 각각의 연산을 이전 행렬에 적용하려고 시도하는 것보다. – Shahbaz