DirectX에선 다음과 같이 보통 왼손 좌표계(Left hand coordinate system)을 사용한다.
우리가 정면을 바라보는 곳이 +z 방향, 오른쪽으로 방향을 틀면 +x 방향, 고개를 위로 들면 +y 방향이다.
우리가 원점에서 노란색 화살표처럼 z축을 바라보고 있다고 가정해보자. 여기서 이동은 하지 않고 단순히 몸의 방향만 오른쪽으로 틀면 그만큼 회전한 각도가 생길 것이다. 이때의 회전각이 yaw이다. 즉 yaw는 y축을 기준으로 회전한 각도를 의미한다. 자신의 몸에 세로로 y축이 있다고 가정하고 몸을 회전해보면 이해가 빠를 것이다. 각 축은 서로 직각을 이루므로 z축 방향에서 90도만큼 회전하면 x축과 일치하게 될 것이다. 이때 yaw는 90도를 라디안(radians) 값으로 나타낸 것을 의미한다. 즉 파이/2가 된다.
pitch는 x축을 기준으로 회전한 각도를 의미한다. 위의 좌표계에서 원점에서 z축을 바라보며 서있다고 가정해보자. 고개를 들면 그만큼 회전한 각도가 생긴다. 이 각도를 라디안으로 표현한 것이 pitch이다.
이를 이용해서 pitch와 yaw를 직접 계산해보자. 먼저 yaw를 계산해보자.
위 그림의 원점 O에 서서 z축을 바라보고 있다고 가정하자. 그리고 xz 평면에 존재하는 점(A)을 바라보기 위해 방향을 오른쪽으로 튼다고 생각해보자. 그러면 그만큼의 회전각이 생기는데, 이를 yaw라 하자. xz 평면 위의 점 A의 좌표는 (2, 0, 4)라고 가정하자. 점 A에서 z축에 수직이 되도록 선을 그리고 그 점을 B라고 한다면, 우리는 OAB라는 yaw를 하나의 각으로 가지는 직각 삼각형을 만들 수 있다. 그러면 해당 삼각형의 밑변은 z, 높이는 x가 된다. 이 2개의 길이를 가지고 우리는 yaw를 구할 수 있다.
삼각함수 중 tan가 있다. tan는 각도를 입력으로 받으면 그에 맞는 삼각비 값을 출력으로 준다. 예를 들어 위 삼각형의 yaw를 tan의 입력으로 주면 높이/밑변, 즉 x/z가 된다. 그런데 우리는 반대로 높이와 밑변을 이용해서 각도를 얻어내야 한다. 그러면 tan의 역함수를 이용하면 된다. tan의 역함수는 arctan이다. arctan에 tan의 결과를 주면 각도를 뱉어낸다. 따라서 arctan(x/z)는 yaw가 된다. DirectXMath에서 arctan 함수로 atan과 atan2를 제공해준다.
atan과 atan2의 차이점은 두 가지가 있는데 우선 리턴하는 각도의 범위가 다르다. 그리고 atan은 x/z 1개를 인자로 받고, atan2는 x와 z 2개를 인자로 받는다. 자세한건 찾아보면 나온다. 여기선 atan2를 사용한다.
atan2는 인자 2개를 받는데, 하나는 높이 하나는 밑변이다. 순서는 높이, 밑변이므로 atan2(x, z)의 결과가 yaw가 된다.
이번엔 pitch를 구해보자.
위 그림은 아까의 그림에서 이어진다. 이번엔 아까의 점 A에서 y축으로 3만큼 높아진 C(2,3,4)의 점을 생각해보자. 우리가 점 A를 바라보는 상태에서 고개를 들어 C를 바라보려고 한다. 그럼 그만큼 위로 회전한 각도가 생기는데 이 각을 pitch라 하자. 아까와 마찬가지로 원점 O와 A, C로 직각 삼각형을 만들 수 있다. 밑변은 OA가 되고 높이는 AC가 된다. pitch를 구하기 위해선 atan2에 밑변과 높이를 전달하면 된다. 높이는 y의 값이므로 3을 전달하면 된다. 밑변은 자세히 보면 사실 yaw를 계산했을 때의 삼각형의 빗변과 동일하다.
따라서 아까의 삼각형의 밑변과 높이인 z와 x를 이용하면 빗변의 길이를 구할 수 있게 된다. 피타고라스 정리를 이용하면 루트(x제곱 + z제곱)라는 값이 나온다. 따라서 atan2에 높이 y와 밑변 루트(x제곱 + z제곱)을 전달하면 pitch를 구할 수 있다.
삼각형을 어떻게 구성해야 하는지 헷갈렸는데 다음 글이 도움이 많이 됐다.
'게임 공부 > DirectX' 카테고리의 다른 글
Blend state (0) | 2021.04.03 |
---|---|
Constant buffer - 16바이트 단위로 정렬! (0) | 2021.04.02 |
XMVECTOR 타입 구조 - SSE (0) | 2021.03.20 |
깊이스텐실 Desc 중 깊이 func 값 관련 - D3D11_COMPARISON_FUNC (0) | 2021.03.18 |
[DirectX] Direct3D 11 programming (1) (0) | 2021.03.05 |
댓글