Info

해당 글에서는 구면좌표계를 입력으로 받고 이를 직교 좌표계로 바꾸어 카메라의 움직임을 구현하는 방법을 다룬다.

구면좌표계 란?

이미지와 같이, , 와 같은 각도와 반지름 r로 지점 P를 정의하는 좌표계를 의미한다.

사용의 이유

  1. 구현이 간단하다.
  2. 모델 중심적 시야를 가진다.

직교좌표계 변환

위 이미지를 통해서 간단하게 유도할 수 있다. 코드에서는 DirectX가 ‘왼손 좌표계’를 사용함에 따라서 이미지와 정확히 들어맞지는 않고 각도의 방향이 반대이다.

구현

void OnMouseMove(int dx, int dy)
    {
        mTheta += XMConvertToRadians(0.25f * static_cast<float>(dx));
        mPhi += XMConvertToRadians(0.25f * static_cast<float>(dy));
 
        mPhi = Clamp(mPhi, 0.1f, XM_PI - 0.1f);
    }
    
void Update()
    {
        float x = mRadius * sinf(mPhi) * cosf(mTheta);
        float z = mRadius * sinf(mPhi) * sinf(mTheta);
        float y = mRadius * cosf(mPhi);
 
        XMVECTOR pos = XMVectorSet(x, y, z, 1.0f);
        XMVECTOR target = XMVectorZero();
        XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
 
        XMMATRIX view = XMMatrixLookAtLH(pos, target, up);
        XMStoreFloat4x4(&mView, view);
    }

코드를 살펴보면 Clamp로 범위를 제한한 부분이 있는데, 연산시 0이 되거나 up direction과 dependence 해질 경우, cross product가 0이 나오는 등 문제가 발생하여 그렇게 하였다.

카메라가 y축을 기준으로 만큼 회전하는 문제인데, 구체적 이유는 모르겠다.