[DIY]흙수저 VR 자작 프로젝트: 사물의 이동과 방향표현
2020. 5. 1. 22:51
프로젝트 글목록
2020/05/01 - [자작/VR] - [DIY]흙수저 VR 자작 프로젝트: 사물의 이동과 방향표현
2019/06/01 - [자작/VR] - [DIY]흙수저 VR 자작 프로젝트: 적외선 카메라 트래킹 실전편
2019/06/01 - [자작/VR] - [DIY]흙수저 VR 자작 프로젝트: 적외선 카메라 트래킹 이론편
2019/05/31 - [자작/VR] - [DIY]흙수저 VR 자작 프로젝트: 기획
(2019년 5월 15일 작성된 게시글입니다.)
개요
룸스케일 트래킹의 최종목표는 정해진 공간 안에 있는 HMD와 컨트롤러의 위치와 방향을 정확하게 나타내는 것입니다. 우선 위치를 표현하는 것은 3차원 좌표계로 쉽게 표현할 수 있습니다. 그렇다면 방향은 어떻게 나타낼 수 있을까요?
오일러 각
오일러 각 또는 오일러 회전은 물체를 x, y, z축을 기준으로 차례대로 회전시켜 방향을 표현하는 것을 말합니다. 예를 들어 (30˚,60˚,30˚)는 x축을 기준으로 30˚회전한 다음 y축으로 60˚회전하고 z축으로 30˚회전한 것을 의미합니다. 오일러 각을 보기 좋게 회전행렬로 표현하면 아래와 같습니다.
적외선 카메라 트래킹 이론편에서 보여드린 그 행렬이 맞습니다. 오일러 각은 현실공간에서 측정하기 쉽다는 장점이 있는데, 저는 카메라의 방향을 입력할 때 직접 측정해서 넣을 것이기 때문에 카메라의 방향을 나타낼 때는 오일러 각을 사용합니다. 하지만 오일러 각은 축의 회전 순서에 따라 표현되는 결과값이 달라지고 짐벌락 문제가 존재하기 때문에 사물(HMD, 컨트롤러)의 방향을 표현하는 데는 사용하지 않기로 했습니다.
쿼터니언
쿼터니언(사원수)은 복소수(a+bi)를 확장한 수 체계입니다. 쿼터니언은 기존의 i에 새로운 허수단위 j, k를 더해 q=w+xi+yj+zk와 같이 씁니다. w는 스칼라부, xi+yj+zk는 벡터부라고 부릅니다. 여기서 벡터부를 분리해 만든 개념이 바로 '벡터'입니다. 그래서 쿼터니언을 q=w+v,v=(x,y,z)와 같이 벡터로 표현하기도 합니다.
쿼터니언으로 방향을 표현하면 짐벌락 문제가 발생하지 않고 오일러 각에 비해 연산이 간단하기 때문에 컴퓨터 그래픽에서 주로 쓰입니다. 또한 VR 드라이버가 기기로부터 전달받는 방향정보도 쿼터니언을 사용하기 때문에 별다른 변환과정 없이 바로 사용할 수 있다는 점도 장점입니다.
쿼터니언 회전
쿼터니언의 장점 중 하나는 한 벡터를 어떤 벡터를 축으로 회전시키는 것이 간단하다는 것입니다. 예를 들어 벡터 N을 벡터 V를 기준으로 θ라디안만큼 회전시켜보도록 하겠습니다.
먼저 쿼터니언을 이용해 회전을 하는 식은 다음과 같습니다.
$$qPq^{-1}$$
P는 회전할 점, q는 회전축과 회전각을 담은 쿼터니언이고 식은 각각 다음과 같습니다.
$$P=0+N$$
$$q'=\cos \frac{\theta }{2}+\sin \frac{\theta }{2}\cdot V$$
$$q=\frac{q'}{|q'|}$$
여기서 q'은 q를 단위 쿼터니언으로 만들기 위해 절댓값으로 나누는 과정입니다. 식을 계산하고 나면 나오는 결과값에서 벡터부가 바로 회전된 벡터입니다.
이렇게 쿼터니언을 이용해 벡터를 회전시킬 수 있습니다.
Rigid 변환 구하기
다시 트래킹으로 돌아와봅시다. HMD의 좌표와 방향을 수학적으로 나타내면 원점에 있는 HMD를 r만큼 회전하고 p만큼 평행이동한 것이 현재 HMD와 일치하면 r과 p는 현재 HMD의 방향과 좌표를 나타낸 것과 같습니다. 이처럼 크기가 변하지 않고 평행이동과 회전만 시키는 것을 Rigid(강체) 변환이라고 합니다.
아래 그림을 봅시다. B는 적외선 카메라를 통해 추적된 HMD 표면 위의 점들의 집합이고 A는 HMD가 원점에 위치했을 때 점들의 집합입니다.
이제 A에서 B로의 Rigid 변환을 구하면 HMD(B)의 현재 좌표와 방향을 알 수 있습니다. Rigid 변환관계를 구하는 방법은 아래 링크의 4.2.2문단을 참고하시기 바랍니다.
링크에서는 오일러 각을 사용하였지만 저는 쿼터니언을 사용할 것이기 때문에 식이 살짝 달라집니다. 따라서 우리가 사용할 식은 아래와 같습니다.
$$B=(q_2\cdot q_1)A(q_2\cdot q_1)^{-1} + (C_b - C_a)$$
Ca와 Cb는 각각 A와 B의 중점입니다. 이 식에서 q2•q1가 hmd의 방향, Cb - Ca가 좌표가 되겠습니다.
개념만 잘 이해하면 딱히 복잡한 내용도 아니고 크게 비중 있는 부분도 아니라서 빠르게 지나간 감이 없지 않아 있습니다. Rigid 변환과정은 CCL 문제로 그냥 내용을 통채로 생략해버렸는데 링크 내의 설명으로 충분히 이해하실 수 있다고 생각합니다. 다음 포스팅에서는 자바로 추적된 점들을 가지고 물체의 위치와 방향을 알아내는 프로그램을 구현해보도록 하겠습니다.
참고자료
오일러 각 - https://ko.m.wikipedia.org/wiki/오일러_각
쿼터니언 - http://www.galexandria.com/main/gdnet/quaternion-powers
쿼터니언 회전 - https://m.blog.naver.com/youhwan11/221009860134
쿼터니언 곱, 회전 - http://www.galexandria.com/main/gdnet/quaternion-powers
Rigid 변환 - https://darkpgmr.tistory.com/81