언리얼엔진을 통한 드론을 구현하던 중, 마우스 X,Y에 대한 값을 입력받아 각각 Yaw와 Pitch를 회전하는 로직을 구현했습니다.

해당 방식에서는 bUseControllerRotationYaw,Pitch = true를 설정하여 컨트롤러 입력에 따른 Pawn이 회전 할 수 있도록 AddActorLocalRotation() 함수를 사용하였습니다.

제가 의도한 결과는 마우스 입력에 따른 Pawn이 각각 Pitch,Yaw만 움직이게 하는것입니다.

 

그러나 실행 결과는 Roll이 값이 같이 회전하는 문제가 발생하여 이러한 문제가 어떤것인지 학습하였습니다.

학습 결과 이러한 현상을 짐벌 락(Gimbal Lock)이라고 할 수 있으며, 이러한 문제가 발생한 이유에 대해 알아보았습니다.

 

이번 포스팅에서는 오일러 각과 짐벌 락, 해결방법 등에 대해 알아보겠습니다.

 

오일러각

Euler - Wikipedia

  • 3D회전을 세가지 축(X,Y,Z)을 기준으로 나눠서 표현하는 방식
  • 언리얼 엔진 내부에서 최종 업데이트시 행렬을 사용하는 것을 직관적이고 효율적으로 사용하기위해
    • 기존의 회전 행렬은 추가 데이터 요구 및 계산량이 많다.
  • Roll  (X축 회전)
  • Pitch(Y축 회전)
  • Yaw (Z축 회전)
  • X,Y,Z 세가지 축을 순서대로 돌린 각도의 정보를 저장하여 3개의 숫자로 표현하는 방식
  • 회전 각도를 숫자 (0~360 / -180 ~ 180)으로 표현하여 직관적이다.
  • 오일러 각의 회전 순서에 따라 다른 결과가 나올 수 있다.

오일러 각의 적용 순서

  • 오일러 각은 한번에 적용되는것이 아닌, 각 표전 기저 벡터 축을 중심으로 독립적으로 일어나는 회전
  • 3가지 축에 적용 순서를 어떠한 순서로 적용할 지에 따라 6가지의 경우의 수가 있다.
    • Yaw -> Pitch -> Roll
    • Yaw -> Roll -> Pitch
    • Pitch -> Roll -> Yaw
    • Pitch -> Yaw -> Roll
    • Roll -> Yaw -> Pitch
    • Roll -> Pitch -> Yaw
  • 언리얼 엔진 : Yaw -> Roll -> Pitch 순서의 각 적용
    • 실제 연산 순서 : Pitch -> Yaw -> Roll
    • FQuat(쿼터니언)은 축과 각도를 한번에 표현하여 회전 순서와 무관하게 정확한 회전 제공
  • 적용 순서에 따라 축이 변경되며, 최종 회전 방향 적용 순서에 따라 결과가 다르다.

 

FRotator : Engine/Source/Runtime/Core/Public/Math/Rotate.h

struct TRotator
{

	// Can't have a UE_REQUIRES in the declaration because of the forward declarations, so check for allowed types here.
	static_assert(std::is_floating_point_v<T>, "TRotator only supports float and double types.");

public:
	using FReal = T;

	/** Rotation around the right axis (around Y axis), Looking up and down (0=Straight Ahead, +Up, -Down) */
	T Pitch;

	/** Rotation around the up axis (around Z axis), Turning around (0=Forward, +Right, -Left)*/
	T Yaw;

	/** Rotation around the forward axis (around X axis), Tilting your head, (0=Straight, +Clockwise, -CCW) */
	T Roll;

 

언리얼 엔진의 실제 연산 순서 : Engine/.../Math/UnrealMath.cpp

template<typename T>
UE::Math::TRotator<T> UE::Math::TRotator<T>::MakeFromEuler(const UE::Math::TVector<T>& Euler)
{
	return UE::Math::TRotator<T>(Euler.Y, Euler.Z, Euler.X);
}



 

 

 

짐벌락

짐벌(Gimbal)

Gimbal - Wikipedia

  • 물체가 회전하도록 중심축을 가진 구조물
  • 3차원 공간에 놓인 강체의 방향은 오일러 각도를 사용하여 세번의 회전을 통해 얻을 수 있다.

 

짐벌락(Gimbal Lock)

  • 오일러 각을 사용한 회전 중 두 개 또는 세개의 축이 겹치게되어 회전각이 소실되는 상황
  • 특정 방향으로 회전하려고 할 때 의도하지 않은 회전이 발생하거나, 특정 방향으로의 회전이 불가능해지는 문제
  • 고리가 다른 고리에 자식으로 붙어있는 관계이기때문에 각 축은 서로 종속적이다.

 

짐벌락 발생 예시

  1. 초기상태 (Yaw 30, Pitch 45, Roll 0)
  2. Pitch += 90 회전 (Yaw 0, Pitch 90, Roll 0) -> Yaw Roll 축이 겹쳐진 짐벌락 발생
    1. X축과 Z축이 동일한 평면에 놓이게 된다.
  3. Yaw / Roll 적용
    1. Z축과 Y축이 같은 축을 기준으로 회전
    2. 회전 방향이 원화는 회전을 표현하지 못하거나, 왜곡된다.

 

해결방법

  • Pitch 제한
    • 값을 +- 90 범위로 제한하여 짐벌락 상황을 제외하는 방어코드 작성
  •  쿼너니언(Quaternion)
    • FQuat
    • 오일러 각처럼 순차적으로 회전을 적용하지 않는다.
    • 회전 축(Vector3)과 각도(Scalar)를 단일 벡터로 표현하므로, 회전 순서에 영향을 받지 않는다.
  • 행렬 (Matrix)
    • FMatrix, FTransform
    • 회전 순서를 적용하지 않고, 모든 회전을 동시에 처리
    • 새로운 회전의 대한 연산은 기존행렬과 곱셈으로 누적
    • 회전이 축에 독립적으로 표현되어 정렬로 인한 문제 발생하지 않음

 


출처

 

https://daekyoulibrary.tistory.com/entry/%EA%B2%8C%EC%9E%84-%EC%88%98%ED%95%99-18-%EC%98%A4%EC%9D%BC%EB%9F%AC-%EA%B0%81Euler-angle

 

[게임 수학] #18 | 오일러 각(Euler angle)

*인프런  강의를 듣고 공부한 글입니다.   1. 회전 행렬 구현에서의 문제점3차원 공간에는 세 개의 표준 기저 벡터 \(e_1\), \(e_2\), \(e_3\) 가 존재합니다. 이 세 개의 기저 벡터를 통해 회전을 구현

daekyoulibrary.tistory.com

https://continue96.tistory.com/138

 

게임 수학 | 3부 3차원 콘텐츠 제작 | 10장 3차원 공간

10장 3차원 공간: 입체 공간의 생성10.1 3차원 공간의 설계3차원 공간 좌표계는 두 가지로 구분한다.오른손 좌표계(right-handed coordinate system)왼손 좌표계(left-handed coordinate system) 3차원 공간 좌표계를

continue96.tistory.com

 

'Unreal Engine > Etc' 카테고리의 다른 글

UE5 - Destructible Mesh(Dynamic Mesh Component)  (0) 2024.12.27

+ Recent posts