게임을 모작하게 되어서 Assimp라이브러리로 모델들을 추출했는데 원하는 애니매이션들이 없어서 직접 만들게 되었고 그 과정을 최대한 간략하게 개념과 함께 정리했다.
당연히 기초적인 수준의 애니매이션을 만들었고 기초 지식만을 가지고 응용했다.
아래 설명하는 방식은 절대 정답이 아니고 그냥 헤딩해서 터득한 방법과 시행착오들을 '흐름만'정리 해 두었다.
코드에 대한 자세한 설명이나 Imgui, Assimp설명은 없다. (너무 길고 힘들다 ㅠ)
애니매이션의 기초적인 지식이 없으면 이해하기 힘들다.
고려대 그래픽스 강의에서 애니매이션을 꼭 듣기 바라고 내가 쓴 글인 https://cjbworld.tistory.com/75 도 같이 보자 ㅎㅎ;;
그냥 이사람은 이런 흐름으로 했구나 정도로 읽어주길 바란다.
흐름 정리
우선 본인은 Assimp라는 외부 라이브러리로 .fbx파일을 로드했고 로드한 뼈의 정보를 tinyxml2이라는 라이브러리로 XML로 파싱했다.
XML로 파싱한 데이터를 다시 imgui로 읽어서 GUI형태로 쉽게 볼 수 있게 했고 원하는 뼈를 선택하면 선택한 뼈의 Local 데이터 정보들을 수정할 수 있게 하였다. 즉 Scale, Rotaion, Translation들을 imgui로 애니매이션 툴을 만든 것이다.
당연히 본인의 애니매이션 툴은 허접하다.
먼저 아래 모델 .fbx를 Assimp로 데이터들을 읽어준다.
그럼 이제 뼈의 데이터들은 아래와 같이 XML파싱을 하고 이 데이터를 프로젝트에서 다시 읽어 들일 준비를 한다.
imgui에서 xml데이터를 읽어 들여서 gui형태로 본 모습이다. 위의 xml에 있는 1202_Right, muzzle등등 제대로 읽어들인 것이 확인 되었다.
본인은 아래처럼 원하는 뼈를 imgui에서 선택할 수 있는 기능을 만들었고, 선택한 뼈의 SRT를 조절할 수 있도록 imgui로 애니매이션 툴을 만들었다.
아래는 나의 아주 간략한 애니매이션 툴 핵심 기능이 담긴 부분이다.
CurrentModel의 이름을 띄워주고 선택한 뼈의 개수, 선택한 뼈의 이름을 보여주고 KeyFrame을 원하는 시간(거리)에 넣고 이때까지 넣은 데이터를 저장하고 불러오는 기능 까지 들어가 있다.
이제 조금더 구체적인 과정을 보도록 하자.
애니매이션 제작 과정
xml파싱
(본인이 직접 만든 것을 정리한 글이라 뭔말인지 모르는 부분이 나오면 그냥 넘어가고 핵심만 보도록 하자)
사실 애니매이션이 들어간 모델을 Assimp로드하려면 Assimp로드하는 방법부터 알아야 하긴 하는데 이거 설명하려면 한 세월이기 때문에 이거는 건너뛰겠다.
XML파싱 부터 어떻게 하는지 ARABOZA
사실 XML파싱 혼자서 제대로 해본적이 없어서 이부분 부터 조금 난감 하긴했는데, Assimp로 모델 로드하고 뼈의 데이터들을 읽어 들일 때 '재귀' 적으로 읽어 들였기 때문에 똑같이 진행했다. 난감했던 부분은 데이터의 구조를 어떻게 효율적으로 저장할지가 고민이었다.
특정 모델의 애니매이션 개수가 IDLE, WALK가 있다고 하자.
각 애니매이션을 움직이는 뼈들의 정보가 있을 것이다. 뼈를 Channel이라 부르겠다. 이 Channel들의 집합을 ChannelInfo라 하자( ChannelInfo끼리 뼈의 교집합이 발생할 수 있다. ). 각 Channel(뼈)는 ChannelName(뼈 이름), 인덱스(실제 어떤 뼈에 해당하는지), KeyFrameCount와 같은 정보를 가지고 있다.
느낌적인 느낌으로 실제 모델의 뼈 정보들이 0~10번까지 있다고 치자, IDLE은 0~3번까지 쓰고 WALK는 1~6번까지 쓰는 느낌이다. 그래서 ChannelInfo끼리 교집합이 발생할 수 있는 것이다.
(뭔말인지 모르겠으면 넘어가자, 본인도 처음 공부할 때 뭔말인지 1도 몰랐다. 사실 XML파싱보다 애니매이션이 어떻게 동작하는지 부모 행렬에 대한 이해가 더 중요한듯 하다.)
쨋든 위에서 설명한 구조대로 데이터들을 재귀함수로 읽어서 XML파싱을 하면 아래와 같이 된다.
재귀로 탐색하는 이유는 뼈의 구조가 재귀적으로 구성되어 있기 때문이다. 당장 유니티 엔진을 켜서 유니티 짱이라는 기본 모델의 뼈만 봐도 재귀적으로 데이터를 읽는게 유리 해보인다.
이후 imgui로 xml파싱한 것을 다시 재귀적으로 읽어 들여서 렌더링 해주면 아래 부분까지 된 것이다.
키 프레임 사입 및 저장
여기서 말하는 '키 프레임'은 특정 뼈(A)가 가지는 SRT 정보들을 말한다.
그럼 예를 들어보도록 하자. 0번 키프레임이 있는데 이 0번 키프레임의 정보는 항등행렬이라 하자. 주대각 성분이 1인 행렬
1번 키 프레임의 SRT정보가 만약 Scale이 1이고(항등), Rotaion은 없으며(항등), Translation만 x축으로 1만 큼 움직인다고 치자.
즉, A라는 뼈가 가지는 키프레임은 2개이고 2개의 키프레임을 '재생' 시키는 것을 '애니매이션'(S)이라 한다. (본인 피셜)
S라는 애니매이션은 A라는 뼈에 접근해 두개의 키 프레임을 보간하여 보간한 값을 모델의 SRT에 적용시켜 '움직이는 것'처럼 보이게 하는것이다.
진짜 간략하게 그림으로 그리면 아래와 같다. 팔 뼈라고 생각하자. 0번 키프레임 정보에서 1번 키프레임 정보로 행렬 데이터를 보간하는 것이다.
보간하는 방법은 정말 여러가지가 있지만, 본인은 '선형보간'으로 키프레임 사이를 보간 하였다.
본인인 필요한 애니매이션이 IDLE, WALK였다. 게다가 모작하는 게임도 1인칭 FPS게임이라 애니매이션 제어가 다른 모작 게임보다 쉬웠는데 그 이유가, 거의 가장 최상단의 부모 뼈의 Rotaion만 잘 조절하면 '가만히 있는 듯 한' 느낌과 '걷는 듯한 느낌을 줄 수 있었기 때문이다'
이렇게 할 수 있었던 이유가 우선 '자식의 World 행렬 * 부모의 World행렬 곱하면 자식의 좌표는 부모를 기준으로한 좌표계가 된다.'라는 이해가 조금 있었기 때문에 본인이 로드한 모델의 거의 최상단 부모 뼈를 잡아서 Rotation을 조절한 키프레임을 만들어보자~ 라는 생각 까지 이어질 수 있었던거 같다.
여기서 0번 키프레임 정보를 저장하고 왼쪽으로 HOME이라는 최상단 뼈의 Rotation Y값을 살짝 돌려서 아래와 같이 만들어주고
이상태에서 다시 오른쪽으로 살짝 돌려서 아래와 같이 키프레임 정보를 셋팅해준다.
이제 이렇게 저장한 데이터를 실제 게임 프로젝트에서 불러들여서 확인해보면 아래와 같다.
충분히 걷는 듯한 느낌을 주는 거같다.
다른 간단한 애니매이션도 이런식으로 만들 수 있지만, 복잡하고 정교한 애니매이션은 사실 힘들다.
그래서 애니매이터가 있는 것이고...
쨋든 이렇게 엄청엄청 짧게 본인이 애니매이션 만든 흐름을 정리 해보았다.
물론 처음 공부하는 사람은 이 글 가지고만 애니매이션 만들 수 도 없고 이해도 하기 힘들것이다.
본인도 헤딩 엄청해서 겨우겨우 이정도 만든듯 하다.
그래도 다들 화이팅 ㅎㅎ
'컴퓨터 그래픽스 > DirectX' 카테고리의 다른 글
절두체 컬링 (Frustum Culling) (0) | 2024.12.10 |
---|---|
NavMesh 만들기 (2) | 2024.12.07 |
[Animation] 스키닝 애니매이션이란? (Skinning Animation) (1) | 2024.11.10 |
View Spcae Matrix 만들기 (0) | 2024.07.31 |
[DX] 렌더링 파이프 라인 (2) | 2023.11.30 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!