SlideShare uma empresa Scribd logo
1 de 195
Baixar para ler offline
M2 프로젝트의
절차적
캐릭터리깅시스템                                            NEXON devCAT 김주복, 김충효




                                     Ⓒ 2010 NEXON Corporation & devCAT Studio. All Rights Reserved
M2 team, Game Development Team for Project W in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dungeon | Project W is produced by Kim, Dungeon
twitter.com/eiaserinnys   김주복
애니메이션프로그래밍10년차
2001   무선사업팀 도트디자이너
2001   마비노기팀 리드 프로그래머
2003   마비노기 프로그래밍팀 팀장
2005   그룹웨어 개발팀 팀장
2006   W팀 테크니컬 디렉터
2008   개발3본부 3실 실장
2009   마비노기 2 개발 디렉터
2010   신규개발3본부 1실 실장
넥슨 신규개발 3본부

김충효
                                           2001년 입사 / 마비노기1 프로젝트 합류
                                           2006년 마비노기2 프로젝트 합류
                                           2010년 현재 M2팀 팀장 / 넥슨 아트 직군장




                                Ⓒ 2010 NEXON Corporation & devCAT Studio. All Rights Reserved
M2 team, Game Development Team for Project W in The 3rd Development Division in NEXON Corp. M2 team Director is Kim, Dungeon | Project W is produced by Kim, Dungeon
모델링
애니메이팅
리깅
스크립팅…




                                 Ⓒ 2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Project W in The 3rd Development Division in NEXON Corp. M2 team Director is Kim, Dungeon | Project W is produced by Kim, Dungeon
캐릭터의
Deformation
시간의 흐름에 따른
실루엣의 변화가
바로 애니메이션이다
라고 해도 과언이 아님…
3D 캐릭터를
애니메이션 시킨다는 것은

표면의 Vertex를
움직인다는 것이다
어떤 수단을 사용해도 상관 없다.
버텍스를 움직여서 표면 실루엣을 변화시키는 모든 방법이
캐릭터를 애니메이션 시키는 방법이 된다.
캐릭터 디포메이션의 방법
   캐릭터 애니메이션의 방법
일반적인 3D 캐릭터
Skeletal Animation
골격 구조의 뼈대를 움직여서 캐릭터를 변형시킨다.
물론 뼈 없이
애니메이션을 시킬 수
있지만…
Vertex Morph 를 활용한 방법이 대표적
하지만 이것만 가지고는
캐릭터 전체를 움직이기 힘들다.
일반적인 게임 캐릭터에는
(보통)뼈! 만 있다…
Runtime 으로 변형이 일어나야 하기도 하고
애니메이션 데이터가 무한정 커질 수 없기 때문에

일반적인 게임 캐릭터는 Skeletal Animation 을 한다.
뼈대를 다양하게 활용해서 캐릭터의 미세한 변형을 표현하는 것이
현 시대의 일반적인 표현 방법이다.
Surface Model + Skeletal Animation

지긋지긋한…
Skinning !!
Vertex 의 위치가 관절의 위치와 방향을 따라간다.
Skinning 과정을 통해서 어떤 관절에 어느 정도로 따라가게 될 지 결정됨
현 세대 캐릭터의
  표현수준
만들기 난해하다
차세대 수준의 캐릭터가 요구하는 표현 수준이 너무 높다.
노말맵을 비롯한 여러 가지 맵소스도 만들어야 하고
폴리곤의 수도 엄청 많아야 한다.
요즘의 플레이어들은
자비가 없다
과거에는 기술적 한계로 인해 용납되던 것 들이
지금은 결점으로 받아들여진다.
요구 퀄리티가 엄청나게 높아졌다.
적은 수의 관절은
한계가 있다
실루엣의 변형은 거의 전적으로 관절의 움직임에 의존함

원하는 수준으로 실루엣을 변형 시키려면
과거처럼 관절을 아껴서 쓸 수 없다!!
과거와 같은 수준의 관절로는
더 이상 무리
ex) Candy Wrap 현상
어떻게 문제를
해결해 왔는가?
가장 일반적인 방법은
보조 관절의 사용
문제가 일어나는 부분, 혹은 더 잘 표현하고 싶은 부분에
임의로 관절을 더 설치한다.
해당 관절을 수동으로 움직이거나,
주요 관절의 움직임에 자동으로 반응하게 해서
더 좋은 퀄리티의 실루엣을 얻는다.
예시)      트위스트 관절
Candy Wrap 현상을 막는 대표적인 방법
보통 손이나 발목 관절 등의 회전에 따라 자동으로 동작한다.
예시)   상완 이두근 관절
선택의 여지 없음
보조 관절을 사용하지 않고
5000 tri 이상의 차세대급 캐릭터를
원하는 대로 아름답게 표현할 방법이 없다.
그 동안
문제가 없었을까?
보조 관절의 증가는?

애니메이션
데이터 규모의 증가
보조 관절이 많으면
그만큼 많은 데이터를 익스포트 해야 한다.
또한, Pre-Baked 라는 것은

데이터의 유연성 감소
프레임워크의 변화에 유연하게 대응하기 힘들고
절차적인 애니메이션에 반응하기 어렵다.
끔찍한 경우 1

보조 관절의 동작이
변했다면?
트위스트 관절이나
기타 근육을 표현하는 관절의 동작이
만족스럽지 않아서

동작을 조금 고쳤어요…
끔찍한 경우 2

보조 관절의 수가
늘어났다면?
아무래도 어깨 표현이
잘 안 되는 것 같은 판단이 들어서

어깨 부분에 보조 관절을
추가했어요…

물론 캐릭터 메시 스키닝도 다시했지요…
끔찍한 경우 3

의상 별로
서로 다른 보조 관절을
써야 한다면?
MMORPG 이니까 코스튬 퀄리티가 중요함.

의상마다
최상의 퀄리티를 유지할 필요 있음.

각각의 의상에 특화된
보조 관절을 사용하게 된다면?
프로그래머 입장에서는…
보조 관절을 사용하는
캐릭터가 Rag Doll 처리
된다면?
Rag doll 혹은 IK 처리 등으로 인해서
미리 구워진 애니메이션과 다른 동작을 하게 되면
보조 관절은 어떻게 동작해야 하는 거지?
보조 관절과 Pre-Baked Animation

애니메이션 데이터의
증가 뿐만 아니라,
프레임워크 데이터를
변경하기 힘들어짐을
의미한다
보조 관절과 Pre-Baked Animation

프레임워크가
다른 의상 마다
모든 애니메이션을
따로 준비해야 한다
솔직히 이건 말도 안 되는 선택지이다.
보조 관절과 Pre-Baked Animation
말하자면,
애니메이션 데이터가
프레임워크 종속적이
된다는 것이다
캐릭터 릭의 개선을 통해서
퀄리티를 계속 높여가는 것에
커다란 장애 요소가 된다.
결국…
 3D 아티스트로서
내가 갖고자 했던 것
Needs:
미리 구워내지 않아도
클라이언트에서
DCC툴과 동일하게 동작
하는 보조관절이 필요
애니메이션 데이터의 크기 감소와
작업 파이프라인의 유연성의 확보 및
절차적 애니메이션에의 반응성 확보
Objective:

절차적 보조 관절 구현!
클라이언트에서
3ds max 에서 구현한 것과
완전히 동일하게 동작하는 관절을 구현해야 한다!!
목표의 구체화 과정
프로그래머 입장에서는

무엇을 구현해야
DCC툴에서와 같은
퀄리티를 낼 수 있는지
알 수 없다
프로그래머들에게는
3ds max는 거대한 블랙박스와 같다.
(아티스트가 칭얼거려서…)
니즈는 확보했는데…
궁극적인 골은 어디?
구체적으로 어떤 것 들을 구현해야 하는지 결정해야 했다.
니즈를 찾았으니,
문제를 구체화 하고 목표를 설정해야 함
일단!
아티스트가 원하는
최적의 상태를
3ds max로 만들자
캐릭터의 누드 메시가
DCC툴에서 최적의 상태로 나올 수 있도록
프레임워크 세팅을 진행
고심 결과,
작업 진행은 당연히
여성 캐릭터로…
여성 캐릭터의 누드를 아름답게 연출할 수 있을 정도면
남자는 손쉽게 할 수 있을 것이다.
의욕 문제도 있고…
최종적으로
우리가 원하는 상태는
   무엇인가?
그런데…
내가 원하는 상태?
나도 잘 모르겠다만…
어디가 어려운지는 안다
나도 근육 같은 것 세팅해본 경험 별로 없다…
경험적으로 어떤 부분의 스키닝이 잘 안 되는지는 알고 있다.
나를 항상 괴롭혀온…
전통적으로 어려운 곳
매력 포인트라서…
더 잘 해보고 싶은 곳
스키닝 방식이 바뀌지 않는 한…
트위스트가 필요한 곳
어렵지는 않지만…
후속 조치가 필요한 곳
특히 어깨!!! 부분은
Candy Wrap 현상이
가장 심하게 일어난다
3축으로
자유도를 갖는 관절은
스키닝하기 까다롭다
현실에서의 어깨 표면이
어떤 식으로 움직이는지
연구 진행
피부의 변형을 이해하는 것은
관절의 움직임을 이해하는 것 과는 또 다른 영역이다.
궁극적으로 피부 실루엣의 변형을 묘사해야 함
피부 접히는 부분의
특이한 형태에도 주목
연구 결과를 바탕으로…
어깨 관절 리깅
스키닝을 하지는 않지만
올바르게 동작하는 데
필요한 관절도 있다…
피부를 변형시키는 데 직접 관여하지는 않지만
관절들의 최종 위치를 계산하기 위해서는
나름대로 동작을 할 필요가 있는 관절들
리깅에 사용된
3ds max의 주요 기능
주요 기능
ExposeTM
Expose Transform Matrix (Helper)
특정 관절의 현재 상태를 알아낼 수 있다.

Local/World Position (관절의 위치)
Local/World Euler Angle (관절의 회전)
Distance (두 관절 사이의 거리)
 :
주요 기능
Position Constraint
특정 관절의 위치를 그대로 따라가거나,
둘 이상의 관절들의 위치를
적당히 내분하는 지점에 위치하게 된다.
주요 기능
LookAt Constraint
이름 그대로…
특정 관절(들)의 위치를 계속 쳐다본다.
Upnode 를 잘 활용해야 함.
주요 기능
Rotation List
둘 이상의 Rotation Controller 의 계산 결과를
특정 비율로 나눠서 적용할 수 있다.
주요 기능
Reaction Controller
Master 가 되는 “무엇”의 변화에 따라
Slave 가 되는 “무엇”의 상태를 결정할 수 있다.


  Master



                                 Slave
리깅 사례
핵심 관절
Shoulder 1
Shoulder 2
삼각근의 다양한 변형 및 부풀어 오름에 대응하기 위한 관절
핵심 관절
Shoulder 1
Shoulder 2
삼각근의 다양한 변형 및 부풀어 오름에 대응하기 위한 관절
Shoulder 동작의
기본 아이디어
팔의 회전이 어떤 상태이냐에 따라
어깨의 위치와 방향이 결정된다.
Shoulder 1 의 동작

 팔 관절   ExposeTM         Shoulder 1
        Local Rotation     Position
                          Reaction Controller

                           Rotation
                          LookAt Constraint
                                  Up Node




                          Up Node
                           Position
                          Reaction Controller
Shoulder 2 의 동작

 팔 관절   ExposeTM         Shoulder 2
        Local Rotation     Position
                          Reaction Controller

                           Rotation
                          Reaction Controller
승모근
Trapezius
아름다운 목 라인과 어깨 라인을 서포트
승모근 동작의
기본 아이디어
어깨와 목을 연결한 선 위에 위치한다.
어깨 쪽을 계속 바라보고 있다.
척추 방향으로 정렬되어있다.
상박 트위스트 관절의
기본 아이디어
항상 Upper Arm 관절의 길이 방향으로 정렬되어 있다.
Upper Arm 관절의 회전 정도와
Shoulder 관절의 회전 정도를 적당히 분배한다.
상박 트위스트 관절의
동작
Upper Arm 의 Upnode 방향과
Shoulder 의 Upnode 방향을
일정 비율로 섞었다.
흉근과 견갑골 동작의
기본 아이디어
LookAt Constraint를 활용한 단순한 동작.
대신 부모 관절의 움직임으로 인해 복잡한 움직임을 보임.

 흉근                       견갑골
DCC툴에서의
최종 리깅 결과
최종 어깨 실루엣
최종 어깨 실루엣
최종 어깨 실루엣
절차적 리깅 시스템으로…
새로운 아이디어를 실현
간단한
구현 방법
ExposeTM 으로 측정하고,
Reaction Controller 로 결정한다.
여성 누드 캐릭터가
충분히 만족스러운 상황이라고 판단!!
대략적인 구현 목표 추출
Reaction Controller
LookAt Constraint
Position Constraint
Orientation Constraint
Expression Controller
Wire Parameter
ExposeTM
  :

조금 많은가?
목록이 많다 어쩌다 해도
결국 다 구현하긴 했다
Reaction Controller
LookAt Constraint
Position Constraint
Orientation Constraint
Expression Controller
Wire Parameter
ExposeTM
  :
시연
절차적 리깅 시스템의 구현


                                     Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                          devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
3DS MAX컨트롤러의 구현 사례
디펜던시와 계산 순서 문제
최 적 화                                                                              관 련                                                           이 슈
월드       트랜스폼                      문제             |     스케일을                     가진             트랜스폼                      문제            |      실수            계산             성능


퍼포먼스 및 장단점 분석, 결론

                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
3DS MAX컨트롤러의 구현 사례
디펜던시와 계산 순서 문제
최 적 화                                                                              관 련                                                           이 슈
월드       트랜스폼                      문제             |     스케일을                     가진             트랜스폼                      문제            |      실수            계산             성능


퍼포먼스 및 장단점 분석, 결론

                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
3DS MAX의 컨트롤러는 IReactor란 이름으로 구현되어 있다

공통 인터페이스
// 실제 인터페이스와 일치하지 않는 것에 주의
class IReactor {
public:
       virtual void Preprocess() = 0;

     virtual void Process(const ProcessOption&) =0;

     virtual const ReactorResult& GetResult() const = 0;
};
PositionConstraint는 본을 타겟 본들의 가중 평균에 놓는다

위치를 블렌딩한다
아들이 아버지와 어머니,
                   어느 쪽에도 치우치지 않는
                 중간적인 위치를 견지하고 있다




<어른의 인형 놀이> 중
   M2 PSM, 한상원
첫번째로 접하는 컨트롤러이니만큼 구현이…

너무나 쉬운 컨트롤러
void PositionConstraint::Process(/* 생략 */)
{
      위치 컨스트레인트 타겟 위치를 가중치 합산

      [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산

      T를 이용, 합산 결과를 부모의 로컬 공간으로 이동

      계산된 결과를 저장
}
컨스트레인트 타겟의 위치를 블렌딩한다

1. 목표 지점을 계산
void PositionConstraint::Process(/* 생략 */)
{
      위치 컨스트레인트 타겟 위치를 가중치 합산

      [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산

      T를 이용, 합산 결과를 부모의 로컬 공간으로 이동

      계산된 결과를 저장
}
블렌딩된 위치를 포지션 컨스트레인트가 걸려 있는 본의

2. 로컬 좌표로 변환
void PositionConstraint::Process(/* 생략 */)
{
      위치 컨스트레인트 타겟 위치를 가중치 합산

      [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산

      T를 이용, 합산 결과를 부모의 로컬 공간으로 이동

      계산된 결과를 저장
}
슈도 코드 뿐만 아니라…

실제 코드도 간단
롤 아웃에 있는 뭔가

수상한 옵션은?
Keep Initial Offset 옵션은 포지션 컨트스트레인트 계산 결과와

초기의 어긋남을 보존


        PositionAtConstraint가    Keep initial offset
        걸려 있는 본의                 옵션에 의해서
        바인드 포즈의 위치               이동된 위치
Keep Initial Offset 옵션을 포함하는

     옵셋을 반영한 슈도코드
     void PositionConstraint::Preprocess()
     {
               keep initial offset이 켜진 경우, 포지션 컨스트레인트의
               계산 결과와 바인드 포즈의 차이를 [옵셋]으로 보존해둔다
     }
     void PositionConstraint::Process(/* 생략 */)
     {
               위치 컨스트레인트 타겟 위치를 가중치 합산

            [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산

            T를 이용, 합산 결과를 부모의 로컬 공간으로 이동

            keep initial offset이 켜진 경우, 계산 결과에 [옵셋]을 더한다

            계산된 결과를 저장
     }

40
다른 컨트롤러의 구현 방법에 관련된 사항은

추가 노트에 수록
3DS MAX컨트롤러의 구현 사례
디펜던시와 계산 순서 문제
최 적 화                                                                              관 련                                                           이 슈
월드       트랜스폼                      문제             |     스케일을                     가진             트랜스폼                      문제            |      실수            계산             성능


퍼포먼스 및 장단점 분석, 결론

                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
전통적인 애니메이션 프로그래밍에서 트랜스폼은 순서대로 계산

인덱스 순서대로?
                                0



                1                                 8




        2               5                9                 10




    3       4       6       7       11       12       13        14
하지만 보조 본들은 순서대로 계산된다고 보장할 수 없다

다른 본을 참조하면?
                                0



                1                                 8




        2               5                9                 10




    3       4       6       7       11       12       13        14
좋은 방법이 떠오르지 않으니 일단…

     개별 컨트롤러가 계산?
     void PositionConstraint::Process(/* 생략 */)
     {
              [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산

             위치 컨스트레인트 타겟 위치를 가중치 합산

             T를 이용, 합산 결과를 부모의 로컬 공간으로 이동

             keep initial offset이 켜진 경우, 계산 결과에 [옵셋]을 더한다

             계산된 결과를 저장
     }
     void PositionConstraint::GetDependancy(vector<int>& dependancies)
     {
               dependancies에 위치 컨스트레인트 타겟들을 추가한다
     }
90
이 방법이 그렇게 쉽지가 않다

구현에 따라서 복잡
void LookAtConstraint::Process(/* 생략 */)
{
         [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산

         자신의 위치를 T를 사용해서 부모 공간으로 변환

         쳐다보기 타겟의 위치를 가중치 합산
         T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산

         위쪽 방향 타겟을 T를 사용, 업 벡터를 계산

         앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장
}
void LookAtConstraint::GetDependancy(vector<int>& dependancies)
{
         dependancies에 쳐다보기 타겟들을 추가한다
         dependancies에 업 노드를 추가한다
}
컨트롤러 타입에 따라서 점점 더 복잡해지고

ReactionController?
const ReactorResult
         ReactionControllerBase::Process(/* 생략 */)
{
         정렬된 마스터/슬레이브 리액션 리스트에서 주어진 마스터 값을 넘지 않으면서
         가장 큰 마스터/슬레이브 인덱스를 찾는다

         찾아낸 리액션과 다음 리액션을 보간하여 반환한다
}
void ReactionControllerBase::GetDependancy(vector<int>& dependancies)
{
          foreach (마스터 값 m에 대해서)
                   m.GetDependancy(dependancies);
}
void IReactorExprIDHandler::GetDependancy(vector<int>& dependancies)
{
          익스포즈 노드를 dependancies에 추가한다
          레퍼런스 노드를 dependancies에 추가한다
}
감당해야 할 필요가 없는 복잡한 작업을 감당해야 하는 상황에 이른다

수식에서는…???
class ReactorExpressionBinary {
          void GetDependancy(std::vector<int>&   dependancies);
};
class ReactorExpressionID {
          void GetDependancy(std::vector<int>&   dependancies);
};
class ReactorExpressionFunction {
          void GetDependancy(std::vector<int>&   dependancies);
};
class ReactorExpressionConstant {
          void GetDependancy(std::vector<int>&   dependancies);
};
class ReactorExpressionList {
          void GetDependancy(std::vector<int>&   dependancies);
};
class ReactorExpressionFunction {
          void GetDependancy(std::vector<int>&   dependancies);
};
타이핑도 많아지고 근본적으로 실수하기가 쉽다

저절로 계산할 수 없나?
더미 연산을 통해 리액터가 트랜스폼 데이터를 요구하는 것을 가로채자

후킹을 통한 접근
PositionConstraint

LookAtConstraint             IReactorPoseSource
                             GetWorldTranslation(int boneIndex)
OrientationConstraint        GetWorldRotation(int boneIndex)
                             GetWorldScale(int boneIndex)
PositionReactionController   GetLocalTranslation(int boneIndex)
                             GetLocalRotation(int boneIndex)
RotationReactionController   GetLocalScale(int boneIndex)
                             GetWorldTransform(int boneIndex)
ScaleReactionConstraint
                             …
FloatWireConstraint
0~10번까지 트랜슬레이션, 회전, 스케일을 순서대로 순회한 결과


         PositionConstraint
         9, 10
         OrientationConstraint
         12
         ScaleXYZ
bone11                           ReactorTraversalBuilder :
                                 public IReactorPoseSource
         PositionXYZ
                                 … 10
         LookAtConstraint
         24
         ScaleXYZ
bone12
PositionConstraint
         9, 10
         OrientationConstraint
         12
         ScaleXYZ
bone11                           ReactorTraversalBuilder :
                                 public IReactorPoseSource
         PositionXYZ
                                 … 10
         LookAtConstraint
         24
         ScaleXYZ
bone12
PositionConstraint
         9, 10
         OrientationConstraint
         12
         ScaleXYZ
bone11                           ReactorTraversalBuilder :
                                 public IReactorPoseSource
         PositionXYZ
                                 … 10
         LookAtConstraint
         24
         ScaleXYZ
bone12
PositionConstraint
               9, 10
               OrientationConstraint
               12
               ScaleXYZ
      bone11                           ReactorTraversalBuilder :
                                       public IReactorPoseSource
               PositionXYZ
                                       … 10
               LookAtConstraint
               24
               ScaleXYZ
      bone12




100
PositionConstraint
         9, 10
         OrientationConstraint
         12
         ScaleXYZ
bone11                           ReactorTraversalBuilder :
                                 public IReactorPoseSource
         PositionXYZ
                                 … 10 24
         LookAtConstraint
         24
         ScaleXYZ
bone12
PositionConstraint
         9, 10
         OrientationConstraint
         12
         ScaleXYZ
bone11                           ReactorTraversalBuilder :
                                 public IReactorPoseSource
         PositionXYZ
                                 … 10 24 12
         LookAtConstraint
         24
         ScaleXYZ
bone12
PositionConstraint
         9, 10
         OrientationConstraint
         12
         ScaleXYZ
bone11                           ReactorTraversalBuilder :
                                 public IReactorPoseSource
         PositionXYZ
                                 … 10 24 12
         LookAtConstraint
         24
         ScaleXYZ
bone12
PositionConstraint
         9, 10
         OrientationConstraint
         12
         ScaleXYZ
bone11                           ReactorTraversalBuilder :
                                 public IReactorPoseSource
         PositionXYZ
                                 … 10 24 12 11
         LookAtConstraint
         24
         ScaleXYZ
bone12
자동으로 계산 순서를 구축하기 때문에, 기능을 확장하더라도

안전, 정확한 순서 보장
3DS MAX컨트롤러의 구현 사례
디펜던시와 계산 순서 문제
최 적 화                                                                              관 련                                                           이 슈
월드       트랜스폼                      문제             |     스케일을                     가진             트랜스폼                      문제            |      실수            계산             성능


퍼포먼스 및 장단점 분석, 결론

                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
거의 대부분의 컨트롤러의 계산 과정에서

월드 트랜스폼을 요구
void OrientationConstraint::Preprocess()
{
          keep initial offset이 켜진 경우, 오리엔테이션 컨스트레인트의
          계산 결과와 바인드 포즈의 차이를 [회전 옵셋]으로 보존해둔다
}
void OrientationConstraint::Process(/* 생략 */)
{
          if (로컬 공간 보간 모드)
                     컨스트레인트 타겟의 로컬 회전을 기록
          else // 월드 공간 보간 모드
                     컨스트레인트 타겟을 부모 본의 로컬 공간으로 옮겨서 기록

       가중치 합산하여 회전을 계산한다

       keep initial offset이 켜진 경우, 계산 결과에 [회전 옵셋]을 더한다

       계산 결과를 저장
}
문제는 컨트롤러 계산 결과가 적용되는 과정에서

서브 트리가 무효화
본 수가 무지막지하게 많기 때문에
  모든 월드 트랜스폼을 업데이트하는 것은

  치명적 성능
  문제의 원인



110
최소한으로 월드 트랜스폼을 재계산하기 위해서

조상/후손 리스트 관리
                                     0    1 2 3 4 5 6 7 8 9 10 11 12 13 14



        0                                                   0
        234567
                     1                                 8    9 10 11 12 13 14




        01                                                            08
        34
             2               5                9                 12    13 14




  012                                                                     0 8 12
         3       4       6       7       10       11       13        14
특정 본이 재설정되면 후손 리스트의 월드 트랜스폼만 무효화한다

최소 범위 무효화
                                      0    1 2 3 4 5 6 7 8 9 10 11 12 13 14



         0                                                   0
         234567
                      1                                 8    9 10 11 12 13 14




         01                                                            08
         34
              2               5                9                 12    13 14




   012                                                                     0 8 12
          3       4       6       7       10       11       13        14
특정 본의 월드 트랜스폼이 필요하면 조상 리스트만 검색한다

최소 범위 재계산
                                      0    1 2 3 4 5 6 7 8 9 10 11 12 13 14



         0                                                   0
         234567
                      1                                 8    9 10 11 12 13 14




         01                                                            08
         34
              2               5                9                 12    13 14




   012                                                                     0 8 12
          3       4       6       7       10       11       13        14
메모리 상에서 캐시 관리 문제로 기대보다는 성능 향상이 낮지만

전체 재계산 회피 가능


              …이라고 2009년 상반기엔 생각했었으나…
그때그때 계산하면 L2 캐시 미스로 인해 효율이 낮음

산발적인 접근이 문제



                         랜덤한 위치의 SRT와
                         트랜스폼을
                         여러 단계 찾아가게 됨
                         = L2 캐시 미스
접근하는 메모리 공간이 시간 상에서 연속하도록

재계산을 모아줄 필요

 1. 월드 트랜스폼을 재계산하는 순서를 계산
                 ↓
   2. 개별 리액터 계산에 앞서 모아서 연산
포즈가 월드 트랜스폼을 재계산하는 것을 가로채 기록해두자

후킹을 통한 접근 (2)
                            일반 버전의
                            UpdateBoneWorldTransform




          템플릿 특화 버전의
 UpdateBoneWorldTransform
3DS MAX컨트롤러의 구현 사례
디펜던시와 계산 순서 문제
최 적 화                                                                              관 련                                                           이 슈
월드       트랜스폼                      문제             |     스케일을                     가진             트랜스폼                      문제            |      실수            계산             성능


퍼포먼스 및 장단점 분석, 결론

                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
거의 대부분의 컨트롤러의 계산 과정에서

부모의 역트랜스폼 요구
void OrientationConstraint::Preprocess()
{
          keep initial offset이 켜진 경우, 오리엔테이션 컨스트레인트의
          계산 결과와 바인드 포즈의 차이를 [회전 옵셋]으로 보존해둔다
}
void OrientationConstraint::Process(/* 생략 */)
{
          if (로컬 공간 보간 모드)
                     컨스트레인트 타겟의 로컬 회전을 기록
          else // 월드 공간 보간 모드
                     컨스트레인트 타겟을 부모 본의 로컬 공간으로 옮겨서 기록

       가중치 합산하여 회전을 계산한다

       keep initial offset이 켜진 경우, 계산 결과에 [회전 옵셋]을 더한다

       계산 결과를 저장
}
또한 많은 회전 컨트롤러의 계산 결과로

트랜스폼 → SRT 요구
void LookAtConstraint::Process(/* 생략 */)
{
       [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산

     자신의 위치를 T를 사용해서 부모 공간으로 변환

     쳐다보기 타겟의 위치를 가중치 합산
     T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산

     위쪽 방향 타겟을 T를 사용, 업 벡터를 계산

     앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장
}
매트릭스의 역을 구하는 연산과 SRT (스케일/회전/트랜슬레이션) 분해

두 연산 모두 비싸다



                              PolarDecompose와
       함수 길이만으로도            SpectralDecompose의
       쌀 수가 없는               비싼 두 함수를 거치는
       인버스 트랜스폼                         SRT 분해
연산이 복잡해지는 근본적인 원인은

스케일
R-1   =   RT
      (스케일이 없으면)
SRT(M) =
{
   (1, 1, 1),
   QuaternionFromMatrix(M),
   (M[3][1], M[3][2], M[3][3]
}
                      (스케일이 없으면)
스케일
안 쓰면
되잖아!!!!
아 진짜 애니메이터 여러분 부탁입니다
월드 트랜스폼 무효화와 유사한 형태로

스케일 여부를 관리
애니메이션 플레이어부터 대대적인 수정이 필요하지만

계산량 대폭 절약 가능




          부모 본의 월드 트랜스폼에
             스케일이 없는 경우엔
          아예 인버스를 구하지 않고
        수식을 풀어서 결과만 계산한다
3DS MAX컨트롤러의 구현 사례
디펜던시와 계산 순서 문제
최 적 화                                                                              관 련                                                           이 슈
월드       트랜스폼                      문제             |     스케일을                     가진             트랜스폼                      문제            |      실수            계산             성능


퍼포먼스 및 장단점 분석, 결론

                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
포지션/로테이션/스케일 컨트롤러 계산 과정에서

대량의 실수 연산 요구
특히 심각한 성능상의 영향을 미치는 것은 놀랍게도…

1/sqrt(x)
벡터의 노말라이즈를 비롯, 쿼터니언→매트릭스 변환 등,

많은 곳에서 사용한다




         QuaternionFromMatrix
‘힘내! 너는 이미 이런 상황을 해결할 방법을 알고 있어!’
       ‘네, 저도 이젠 손에 잡힐 듯이 보여요! 강중약약…’


130
이런 상황에서 믿을 수 있는 것은…

Quake III Arena 매직




 위키피디아에도
  등재되어 있다
치명적인 성능 페널티를 피할 수 있는 것은 사실이지만

수식 최적화를 우선해야
3DS MAX컨트롤러의 구현 사례
디펜던시와 계산 순서 문제
최 적 화                                                                              관 련                                                           이 슈
월드       트랜스폼                      문제             |     스케일을                     가진             트랜스폼                      문제            |      실수            계산             성능


퍼포먼스 및 장단점 분석, 결론

                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
벡터의 노말라이즈를 비롯, 쿼터니언→매트릭스 변환 등,

퍼포먼스 차트
pros
물리 시뮬레이션 등, 절차적 애니메이션에 대응이 자유롭다
전체적인 애니메이션 파이프라인의 유연성이 증대된다
기계나 갑옷 등의 움직임을 묘사하는데 매우 유리하다


                               cons
    MMORPG에서 대량의 캐릭터에 사용하기엔 성능 부담이 있다
모델러 혹은 애니메이터가 활용하기 위해 기반 지식이 많이 필요하다
      LOD를 고려하면 스키닝이나 프레임워크 설계가 까다롭다
pros
물리 시뮬레이션 등, 절차적 애니메이션에 대응이 자유롭다
전체적인 애니메이션 파이프라인의 유연성이 증대된다
기계나 갑옷 등의 움직임을 묘사하는데 매우 유리하다


                               cons
    MMORPG에서 대량의 캐릭터에 사용하기엔 성능 부담이 있다
모델러 혹은 애니메이터가 활용하기 위해 기반 지식이 많이 필요하다
      LOD를 고려하면 스키닝이나 프레임워크 설계가 까다롭다
pros
물리 시뮬레이션 등, 절차적 애니메이션에 대응이 자유롭다
전체적인 애니메이션 파이프라인의 유연성이 증대된다

표현 영역을
기계나 갑옷 등의 움직임을 묘사하는데 매우 유리하다


확장하는 측면에서cons
          접근
    MMORPG에서 대량의 캐릭터에 사용하기엔 성능 부담이 있다
모델러 혹은 애니메이터가 활용하기 위해 기반 지식이 많이 필요하다
      LOD를 고려하면 스키닝이나 프레임워크 설계가 까다롭다
실시간 절차적 리깅 기술은

기술의 발전의 귀결


캐릭터 표현의 복잡화 → 실시간 절차적 리깅
절차적 애니메이션
3DS MAX의 절차적
리깅의 복제는 비교적 쉽다
미리미리 준비하여
선진조국 이룩하자
3DS MAX컨트롤러의 구현 사례
디펜던시와 계산 순서 문제
최 적 화                                                                              관 련                                                           이 슈
월드       트랜스폼                      문제             |     스케일을                     가진             트랜스폼                      문제            |      실수            계산             성능


퍼포먼스 및 장단점 분석, 결론
                                                                                                                              QA?
                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
추가 노트
3DS MAX 컨트롤러의 동작과 구현
룩 앳  컨 스 트 레 인 트 |  오 리 엔 테 이 션  컨 스 트 레 인 트
리액션 컨트롤러 | 수식 컨트롤러 & 플롯 와이어 | XYZ & 리스트 시리즈




                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
추가 노트
3DS MAX 컨트롤러의 동작과 구현
룩 앳  컨 스 트 레 인 트 |  오 리 엔 테 이 션  컨 스 트 레 인 트
리액션 컨트롤러 | 수식 컨트롤러 & 플롯 와이어 | XYZ & 리스트 시리즈




                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
LookAtConstraint, 이름 그대로 본이 특정 위치를…

쳐다보도록 만든다
아버지와 어머니는 아들만 바라보고
                 할아버지는 멀리서 가족 모두를 지그시 바라볼 뿐,
                        노령 인구의 소외는 현대 한국 사회의
                          심각한 사회 문제로 떠오르고 있다




<어른의 인형 놀이> 중
   M2 PSM, 한상원
기능 설명이 명료하기 때문에 상대적으로 구현이

비교적 쉬운 컨트롤러?
void LookAtConstraint::Process(/* 생략 */)
{
       [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산

     자신의 위치를 T를 사용해서 부모 공간으로 변환

     쳐다보기 타겟의 위치를 가중치 합산
     T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산

     위쪽 방향 타겟을 T를 사용, 업 벡터를 계산

     앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장
}
자신의 위치를 부모 본의 로컬 공간으로 가져간다

1~2. 원점 계산
void LookAtConstraint::Process(/* 생략 */)
{
       [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산

     자신의 위치를 T를 사용해서 부모 공간으로 변환

     쳐다보기 타겟의 위치를 가중치 합산
     T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산

     위쪽 방향 타겟을 T를 사용, 업 벡터를 계산

     앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장
}
타겟을 월드 상에서 가중치 합산한 후에 부모 본의 공간으로 가져간다

3. 앞 방향 계산
void LookAtConstraint::Process(/* 생략 */)
{
       [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산

     자신의 위치를 T를 사용해서 부모 공간으로 변환

     쳐다보기 타겟의 위치를 가중치 합산
     T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산

     위쪽 방향 타겟을 T를 사용, 업 벡터를 계산

     앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장
}
간단할 것처럼 보이는…

4. 위 방향 계산
void LookAtConstraint::Process(/* 생략 */)
{
       [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산

     자신의 위치를 T를 사용해서 부모 공간으로 변환

     쳐다보기 타겟의 위치를 가중치 합산
     T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산

     위쪽 방향 타겟을 T를 사용, 업 벡터를 계산

     앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장
}
3DS MAX의 업 노드 옵션이 (쓸데없이) 다양하기 때문에

신경 쓸 것이 많다
앞과 위를 구했으니 옆은 외적으로 간단히 계산할 수 있을 거고,

5. 회전으로 만들면 끝?
void LookAtConstraint::Process(/* 생략 */)
{
       [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산

     자신의 위치를 T를 사용해서 부모 공간으로 변환

     쳐다보기 타겟의 위치를 가중치 합산
     T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산

     위쪽 방향 타겟을 T를 사용, 업 벡터를 계산

     앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장
}
이 정도면 다 된 것 같은데 롤 아웃에 아직도 남아있는 뭔가

     수상한 옵션들은?




50
Keep Initial Offset 옵션은 쳐다보기 계산 결과와

초기의 어긋남을 보존



             LookAtConstraint가
             걸려 있는 본
Keep Initial Offset 옵션을 포함하는

최종 슈도 코드
void LookAtConstraint::Preprocess()
{
        keep initial offset이 켜진 경우, 룩 앳 컨스트레인트의
        계산 결과와 바인드 포즈의 차이를 [회전 옵셋]으로 보존
}

void LookAtConstraint::Process(/* 생략 */)
{
        /* 전략 */

       keep initial offset이 켜진 경우, 계산 결과에 [회전 옵셋]을 더한다

       앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장
}
추가 노트
3DS MAX 컨트롤러의 동작과 구현
룩 앳  컨 스 트 레 인 트 |  오 리 엔 테 이 션  컨 스 트 레 인 트
리액션 컨트롤러 | 수식 컨트롤러 & 플롯 와이어 | XYZ & 리스트 시리즈




                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
OrientationConstraint, 본이 컨스트레인트 타겟들의

회전의 평균을 취한다
할아버지의 회전에 따라서
               온 가족이 영향을 받는 것을 알 수 있다
               가족 모델로서 핵가족의 장단에 대해서
                   고민해봐야 하는 시점이 아닐까




<어른의 인형 놀이>
   서플먼트 무비
 M2 PSM, 한상원
룩앳보다 어떤 의미에서는

제일 간단한 컨트롤러?

void OrientationConstraint::Process(/* 생략 */)
{
      컨스트레인트 타겟의 로컬 회전 리스트를 얻는다

      가중치 합산하여 계산하고 기록한다
}|
월드 공간 오리엔테이션 블렌딩 모드가 있기 때문에

그럴 리가 없다…
void OrientationConstraint::Preprocess()
{
          keep initial offset이 켜진 경우, 오리엔테이션 컨스트레인트의
          계산 결과와 바인드 포즈의 차이를 [회전 옵셋]으로 보존해둔다
}
void OrientationConstraint::Process(/* 생략 */)
{
          if (로컬 공간 보간 모드)
                     컨스트레인트 타겟의 로컬 회전을 기록
          else // 월드 공간 보간 모드
                     컨스트레인트 타겟을 부모 본의 로컬 공간으로 옮겨서 기록

       가중치 합산하여 회전을 계산한다

       keep initial offset이 켜진 경우, 계산 결과에 [회전 옵셋]을 더한다

       계산 결과를 저장
}
일단 귀찮지만 LookAtConstraint와

옵셋 보존 계산은 동일
void OrientationConstraint::Preprocess()
{
          keep initial offset이 켜진 경우, 오리엔테이션 컨스트레인트의
          계산 결과와 바인드 포즈의 차이를 [회전 옵셋]으로 보존해둔다
}
void OrientationConstraint::Process(/* 생략 */)
{
          if (로컬 공간 보간 모드)
                     컨스트레인트 타겟의 로컬 회전을 기록
          else // 월드 공간 보간 모드
                     컨스트레인트 타겟을 부모 본의 로컬 공간으로 옮겨서 기록

       가중치 합산하여 회전을 계산한다

       keep initial offset이 켜진 경우, 계산 결과에 [회전 옵셋]을 더한다

       계산 결과를 저장
}
프로그래머의 기대를 여지없이 배반해버리는

     트랜스폼 규칙
     void OrientationConstraint::Preprocess()
     {
               keep initial offset이 켜진 경우, 오리엔테이션 컨스트레인트의
               계산 결과와 바인드 포즈의 차이를 [회전 옵셋]으로 보존해둔다
     }
     void OrientationConstraint::Process(/* 생략 */)
     {
               if (로컬 공간 보간 모드)
                          컨스트레인트 타겟의 로컬 회전을 기록
               else // 월드 공간 보간 모드
                          컨스트레인트 타겟을 부모 본의 로컬 공간으로 옮겨서 기록

            가중치 합산하여 회전을 계산한다

            keep initial offset이 켜진 경우, 계산 결과에 [회전 옵셋]을 더한다

            계산 결과를 저장
     }
60
계층 구조가 서로 무관한 본의 회전을 블렌딩하기 위해서 필요

‘보이는 대로’ 블렌딩
                              로컬+15도
                                  회전
                             (최종 30도)
  자식



                                          Local→Local인 경우
        World→World로                      (15 + 15) / 2 = 15도
        OrientationConstraint가            World→World인 경우
  부모    걸려있는 본                            (15 + 30) / 2 = 22.5도,


                                 로컬+15도
                                    회전
추가 노트
3DS MAX 컨트롤러의 동작과 구현
룩 앳  컨 스 트 레 인 트 |  오 리 엔 테 이 션  컨 스 트 레 인 트
리액션 컨트롤러 | 수식 컨트롤러 & 플롯 와이어 | XYZ & 리스트 시리즈




                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
*ReactionManager의 기본적인 개념은

입력→그래프→출력




               때려주고 싶은 마음이
         가슴 깊은 곳부터 샘솟아 오르는
                   비 직관적인 UI
*ReactionManager 구현의 어려운 점은…

입력의 종류가 많다
Local Rotation X/Y/Z
World Rotation X/Y/Z
 Local Position X/Y/Z
World Position X/Y/Z
             Distance
핵심적인 기능은 float→그래프→출력이므로

먼저 입력을 추상화



                                        DistanceEvaluator

                    RotationEvaluator
PositionEvaluator
LocalPosition X/Y/Z, WorldPosition X/Y/Z를 처리하는

PositionEvaluator
const float PositionEvaluator::Process(/* 생략 */)
{
        if (로컬 공간 값을 요구)
               if (부모를 기준으로)
                        return 로컬 트랜슬레이션[지정된 채널]
               else if (레퍼런스 본을 기준으로)
                        레퍼런스 본 트랜스폼 공간으로 변환
                        return 변환된 결과값[지정된 채널]
               else // 레퍼런스가 undefined == 월드 기준
                        return 월드 트랜슬레이션[지정된 채널]
        else
               return 월드 트랜슬레이션[지정된 채널]
}
로컬/월드라고 하면 간단할 것 같은데

특이한 부분?
const float PositionEvaluator::Process(/* 생략 */)
{
        if (로컬 공간 값을 요구)
               if (부모를 기준으로)
                        return 로컬 트랜슬레이션[지정된 채널]
               else if (레퍼런스 본을 기준으로)
                        레퍼런스 본 트랜스폼 공간으로 변환
                        return 변환된 결과값[지정된 채널]
               else // 레퍼런스가 undefined == 월드 기준
                        return 월드 트랜슬레이션[지정된 채널]
        else
               return 월드 트랜슬레이션[지정된 채널]
}
프로그래머가 상상하기 어려운 동작을 요구하는

헬퍼 본 인터페이스
LocalRotation X/Y/Z, WorldRotation X/Y/Z를 처리하는

RotationEvaluator
const float RotationEvaluator::Process(/* 생략 */)
{
        if (로컬 공간 값을 요구)
               if (부모를 기준으로)
                        return 로컬 회전값[지정된 채널]
               else if (레퍼런스 본을 기준으로)
                        레퍼런스 본 트랜스폼 공간으로 변환
                        return 변환된 회전값[지정된 채널]
               else // 레퍼런스가 undefined == 월드 기준
                        return 월드 회전값[지정된 채널]
        else
               return 월드 회전값[지정된 채널]
}
PositionEvaluator와 동일하지만…

     쿼터니언→오일러 XYZ




             쿼터니언 → 매트릭스 변환 식과
             매트릭스 → 오일러 XYZ 분해를
                    결합해서 유도 가능
70
Distance를 처리하는

DistanceEvaluator

const float DistanceEvaluator::Process(/* 생략 */)
{
       if (레퍼런스 본이 유효)
              return 기준 본과 레퍼런스 본의 거리
       else
              return 기준 본과 월드 원점의 거리
}
마스터 입력 이후의 float→그래프→출력 처리는 공통

키 프레임 애니메이션
재생과 동일
const ReactorResult
      ReactionControllerBase::Process(/* 생략 */)
{
      정렬된 마스터/슬레이브 리액션 리스트에서
      주어진 마스터 값을 넘지 않으면서
      가장 큰 마스터/슬레이브 인덱스를 찾는다

      찾아낸 리액션과 다음 리액션을 보간하여 반환한다
}
추가 노트
3DS MAX 컨트롤러의 동작과 구현
룩 앳  컨 스 트 레 인 트 |  오 리 엔 테 이 션  컨 스 트 레 인 트
리액션 컨트롤러 | 수식 컨트롤러 & 플롯 와이어 | XYZ & 리스트 시리즈




                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
FloatWire와 *ExpressionControl은 최후의 수단

수식 계산값을 사용
수식을 사용하는 것 외에는 리액션 컨트롤러와 유사한 난이도

파싱만 하면 간단



      매번 인터프리터 방식으로 계산하면
    성능 문제가 있으므로 AST 구축이 필요
        자세한 구현은 이 강의의 범위를
                벗어나므로 생략
수식에 사용되는 ID의 값은 리액션 컨트롤의 마스터와 거의 동일하다

구현의 재활용 가능



         RotationEvaluator,
        PositionEvaluator를
          수식 계산에 그대로
         다시 사용할 수 있다
추가 노트
3DS MAX 컨트롤러의 동작과 구현
룩 앳  컨 스 트 레 인 트 |  오 리 엔 테 이 션  컨 스 트 레 인 트
리액션 컨트롤러 | 수식 컨트롤러 & 플롯 와이어 | XYZ & 리스트 시리즈




                                      Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved
 M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun
                           devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
PositionXYZ, EulerXYZ, ScaleXYZ은

Float 컨트롤러의 묶음
특별한 구현이 필요하지 않을 것 같은데?

기본값과 변환을 처리
void EulerXYZ::Process(/* 생략 */)
{
      if (상수인가)
             기본값을 보존
             foreach (X/Y/Z 각 축의 컨트롤러에 대해서)
                   결과값[축] = float 컨트롤러를 계산
                   if (컨트롤러가 FloatReactionControl)
                          결과값[축]을 라디안으로 변환
             결과값을 쿼터니언으로 변환
      else
             기본값을 저장
}
PositionList, RotationList, ScaleList은

     컨트롤러의 묶음




80
특별한 구현이 필요하지 않을 것 같은데?

순서대로 누적을 처리
void RotationList::Process(/* 생략 */)
{
      foreach (리스트의 컨트롤러에 대해서)
             [현재] = 컨트롤러의 회전 계산 결과
             if 컨트롤러가 *Constraint이면
                     [누적] = Slerp([누적], [현재], [가중치])
             else
                     [누적] = [누적] * [현재]
}
복제 구현을 마쳤으니…

이제 계산만 하면 된다

void ReactorProcessor::Process()
{
      foreach (모든 본에 대해서)
             if (컨트롤러가 있다면)
                   컨트롤러를 계산한다
}

Mais conteúdo relacionado

Mais procurados

[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기강 민우
 
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019devCAT Studio, NEXON
 
멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)Bongseok Cho
 
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019devCAT Studio, NEXON
 
4. 캐릭터 애니메이션
4. 캐릭터 애니메이션4. 캐릭터 애니메이션
4. 캐릭터 애니메이션MinGeun Park
 
그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기Yongha Kim
 
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술henjeon
 
[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기Sang Heon Lee
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스noerror
 
레퍼런스만 알면 언리얼 엔진이 제대로 보인다
레퍼런스만 알면 언리얼 엔진이 제대로 보인다레퍼런스만 알면 언리얼 엔진이 제대로 보인다
레퍼런스만 알면 언리얼 엔진이 제대로 보인다Lee Dustin
 
작은 레벨 디자인 가이드 01
작은 레벨 디자인 가이드 01작은 레벨 디자인 가이드 01
작은 레벨 디자인 가이드 01용태 이
 
김동건, 구세대 개발자의 신세대 플레이어를 위한 게임 만들기, NDC2011
김동건, 구세대 개발자의 신세대 플레이어를 위한 게임 만들기, NDC2011김동건, 구세대 개발자의 신세대 플레이어를 위한 게임 만들기, NDC2011
김동건, 구세대 개발자의 신세대 플레이어를 위한 게임 만들기, NDC2011devCAT Studio, NEXON
 
게임 프레임워크의 아키텍쳐와 디자인 패턴
게임 프레임워크의 아키텍쳐와 디자인 패턴게임 프레임워크의 아키텍쳐와 디자인 패턴
게임 프레임워크의 아키텍쳐와 디자인 패턴MinGeun Park
 
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019devCAT Studio, NEXON
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규ChangKyu Song
 
What is Game Server ?
What is Game Server ?What is Game Server ?
What is Game Server ?흥배 최
 
스키닝 애니메이션
스키닝 애니메이션스키닝 애니메이션
스키닝 애니메이션sung suk seo
 
NDC2012_마비노기 영웅전 카이 포스트모템_시선을 사로잡는 캐릭터 카이 그 시도와 성공의 구현 일지
NDC2012_마비노기 영웅전 카이 포스트모템_시선을 사로잡는 캐릭터 카이 그 시도와 성공의 구현 일지NDC2012_마비노기 영웅전 카이 포스트모템_시선을 사로잡는 캐릭터 카이 그 시도와 성공의 구현 일지
NDC2012_마비노기 영웅전 카이 포스트모템_시선을 사로잡는 캐릭터 카이 그 시도와 성공의 구현 일지영준 박
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010devCAT Studio, NEXON
 
언리얼4 플레이어 컨트롤러의 이해.
언리얼4 플레이어 컨트롤러의 이해.언리얼4 플레이어 컨트롤러의 이해.
언리얼4 플레이어 컨트롤러의 이해.Wuwon Yu
 

Mais procurados (20)

[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
 
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
 
멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)
 
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
 
4. 캐릭터 애니메이션
4. 캐릭터 애니메이션4. 캐릭터 애니메이션
4. 캐릭터 애니메이션
 
그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기
 
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
 
[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스
 
레퍼런스만 알면 언리얼 엔진이 제대로 보인다
레퍼런스만 알면 언리얼 엔진이 제대로 보인다레퍼런스만 알면 언리얼 엔진이 제대로 보인다
레퍼런스만 알면 언리얼 엔진이 제대로 보인다
 
작은 레벨 디자인 가이드 01
작은 레벨 디자인 가이드 01작은 레벨 디자인 가이드 01
작은 레벨 디자인 가이드 01
 
김동건, 구세대 개발자의 신세대 플레이어를 위한 게임 만들기, NDC2011
김동건, 구세대 개발자의 신세대 플레이어를 위한 게임 만들기, NDC2011김동건, 구세대 개발자의 신세대 플레이어를 위한 게임 만들기, NDC2011
김동건, 구세대 개발자의 신세대 플레이어를 위한 게임 만들기, NDC2011
 
게임 프레임워크의 아키텍쳐와 디자인 패턴
게임 프레임워크의 아키텍쳐와 디자인 패턴게임 프레임워크의 아키텍쳐와 디자인 패턴
게임 프레임워크의 아키텍쳐와 디자인 패턴
 
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규
 
What is Game Server ?
What is Game Server ?What is Game Server ?
What is Game Server ?
 
스키닝 애니메이션
스키닝 애니메이션스키닝 애니메이션
스키닝 애니메이션
 
NDC2012_마비노기 영웅전 카이 포스트모템_시선을 사로잡는 캐릭터 카이 그 시도와 성공의 구현 일지
NDC2012_마비노기 영웅전 카이 포스트모템_시선을 사로잡는 캐릭터 카이 그 시도와 성공의 구현 일지NDC2012_마비노기 영웅전 카이 포스트모템_시선을 사로잡는 캐릭터 카이 그 시도와 성공의 구현 일지
NDC2012_마비노기 영웅전 카이 포스트모템_시선을 사로잡는 캐릭터 카이 그 시도와 성공의 구현 일지
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010
 
언리얼4 플레이어 컨트롤러의 이해.
언리얼4 플레이어 컨트롤러의 이해.언리얼4 플레이어 컨트롤러의 이해.
언리얼4 플레이어 컨트롤러의 이해.
 

Destaque

게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉 공개용
게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉   공개용게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉   공개용
게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉 공개용lswsox
 
한상원, 친아티스트 3D 캐릭터 리깅, NDC2010
한상원, 친아티스트 3D 캐릭터 리깅, NDC2010한상원, 친아티스트 3D 캐릭터 리깅, NDC2010
한상원, 친아티스트 3D 캐릭터 리깅, NDC2010devCAT Studio, NEXON
 
김기용, 캐릭터 애니메이션 제작기, NDC2011
김기용, 캐릭터 애니메이션 제작기, NDC2011김기용, 캐릭터 애니메이션 제작기, NDC2011
김기용, 캐릭터 애니메이션 제작기, NDC2011devCAT Studio, NEXON
 
NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템
NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템
NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템tcaesvk
 
NDC2015 김기용, 온라인 게임 애니메이터의 모바일 적응기(프로젝트 Fm 사례를 통해 보는 애니메이션 감성 표현 기법)
NDC2015 김기용, 온라인 게임 애니메이터의 모바일 적응기(프로젝트 Fm 사례를 통해 보는 애니메이션 감성 표현 기법)NDC2015 김기용, 온라인 게임 애니메이터의 모바일 적응기(프로젝트 Fm 사례를 통해 보는 애니메이션 감성 표현 기법)
NDC2015 김기용, 온라인 게임 애니메이터의 모바일 적응기(프로젝트 Fm 사례를 통해 보는 애니메이션 감성 표현 기법)기용 김
 
이원, MMORPG 스토리텔링의 금기들, NDC2010
이원, MMORPG 스토리텔링의 금기들, NDC2010이원, MMORPG 스토리텔링의 금기들, NDC2010
이원, MMORPG 스토리텔링의 금기들, NDC2010devCAT Studio, NEXON
 
임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013devCAT Studio, NEXON
 
[대구] Contz 홍보자료
[대구] Contz 홍보자료[대구] Contz 홍보자료
[대구] Contz 홍보자료startupkorea
 
임베디드 시스템 설계 - 출입구 게이트
임베디드 시스템 설계 - 출입구 게이트임베디드 시스템 설계 - 출입구 게이트
임베디드 시스템 설계 - 출입구 게이트Repump
 
Did system4
Did system4Did system4
Did system4Km Oh
 
[NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터]
[NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터][NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터]
[NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터]SeungWon Lee
 
마비노기 컨텐츠 분석
마비노기 컨텐츠 분석마비노기 컨텐츠 분석
마비노기 컨텐츠 분석maroyou
 
GDC2011 참관보고서 (공개용)
GDC2011 참관보고서 (공개용)GDC2011 참관보고서 (공개용)
GDC2011 참관보고서 (공개용)Jubok Kim
 
HCI2010 - 온라인 게임과 넥스트 젠 애니메이션
HCI2010 - 온라인 게임과 넥스트 젠 애니메이션HCI2010 - 온라인 게임과 넥스트 젠 애니메이션
HCI2010 - 온라인 게임과 넥스트 젠 애니메이션Jubok Kim
 
전형규, Vertex Post-Processing Framework, NDC2011
전형규, Vertex Post-Processing Framework, NDC2011전형규, Vertex Post-Processing Framework, NDC2011
전형규, Vertex Post-Processing Framework, NDC2011devCAT Studio, NEXON
 
이원, 절차적 지형과 월드 머신, NDC2011
이원, 절차적 지형과 월드 머신, NDC2011이원, 절차적 지형과 월드 머신, NDC2011
이원, 절차적 지형과 월드 머신, NDC2011devCAT Studio, NEXON
 
주변의 임베디드 시스템 찾기 - 지하철 전광판
주변의 임베디드 시스템 찾기 - 지하철 전광판주변의 임베디드 시스템 찾기 - 지하철 전광판
주변의 임베디드 시스템 찾기 - 지하철 전광판Taehoon Kim
 
이원 김한경, 거의 모든 무기의 역사, NDC2013
 이원 김한경, 거의 모든 무기의 역사, NDC2013 이원 김한경, 거의 모든 무기의 역사, NDC2013
이원 김한경, 거의 모든 무기의 역사, NDC2013devCAT Studio, NEXON
 
2015 한양대 직무특강 IT 개발자 이야기
2015 한양대 직무특강 IT 개발자 이야기2015 한양대 직무특강 IT 개발자 이야기
2015 한양대 직무특강 IT 개발자 이야기junghyun choi
 
Character Rigging Animation Tutorial with Custom Rigg Controller
Character Rigging Animation Tutorial with Custom Rigg ControllerCharacter Rigging Animation Tutorial with Custom Rigg Controller
Character Rigging Animation Tutorial with Custom Rigg ControllerGameyan Studio
 

Destaque (20)

게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉 공개용
게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉   공개용게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉   공개용
게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉 공개용
 
한상원, 친아티스트 3D 캐릭터 리깅, NDC2010
한상원, 친아티스트 3D 캐릭터 리깅, NDC2010한상원, 친아티스트 3D 캐릭터 리깅, NDC2010
한상원, 친아티스트 3D 캐릭터 리깅, NDC2010
 
김기용, 캐릭터 애니메이션 제작기, NDC2011
김기용, 캐릭터 애니메이션 제작기, NDC2011김기용, 캐릭터 애니메이션 제작기, NDC2011
김기용, 캐릭터 애니메이션 제작기, NDC2011
 
NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템
NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템
NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템
 
NDC2015 김기용, 온라인 게임 애니메이터의 모바일 적응기(프로젝트 Fm 사례를 통해 보는 애니메이션 감성 표현 기법)
NDC2015 김기용, 온라인 게임 애니메이터의 모바일 적응기(프로젝트 Fm 사례를 통해 보는 애니메이션 감성 표현 기법)NDC2015 김기용, 온라인 게임 애니메이터의 모바일 적응기(프로젝트 Fm 사례를 통해 보는 애니메이션 감성 표현 기법)
NDC2015 김기용, 온라인 게임 애니메이터의 모바일 적응기(프로젝트 Fm 사례를 통해 보는 애니메이션 감성 표현 기법)
 
이원, MMORPG 스토리텔링의 금기들, NDC2010
이원, MMORPG 스토리텔링의 금기들, NDC2010이원, MMORPG 스토리텔링의 금기들, NDC2010
이원, MMORPG 스토리텔링의 금기들, NDC2010
 
임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013
 
[대구] Contz 홍보자료
[대구] Contz 홍보자료[대구] Contz 홍보자료
[대구] Contz 홍보자료
 
임베디드 시스템 설계 - 출입구 게이트
임베디드 시스템 설계 - 출입구 게이트임베디드 시스템 설계 - 출입구 게이트
임베디드 시스템 설계 - 출입구 게이트
 
Did system4
Did system4Did system4
Did system4
 
[NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터]
[NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터][NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터]
[NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터]
 
마비노기 컨텐츠 분석
마비노기 컨텐츠 분석마비노기 컨텐츠 분석
마비노기 컨텐츠 분석
 
GDC2011 참관보고서 (공개용)
GDC2011 참관보고서 (공개용)GDC2011 참관보고서 (공개용)
GDC2011 참관보고서 (공개용)
 
HCI2010 - 온라인 게임과 넥스트 젠 애니메이션
HCI2010 - 온라인 게임과 넥스트 젠 애니메이션HCI2010 - 온라인 게임과 넥스트 젠 애니메이션
HCI2010 - 온라인 게임과 넥스트 젠 애니메이션
 
전형규, Vertex Post-Processing Framework, NDC2011
전형규, Vertex Post-Processing Framework, NDC2011전형규, Vertex Post-Processing Framework, NDC2011
전형규, Vertex Post-Processing Framework, NDC2011
 
이원, 절차적 지형과 월드 머신, NDC2011
이원, 절차적 지형과 월드 머신, NDC2011이원, 절차적 지형과 월드 머신, NDC2011
이원, 절차적 지형과 월드 머신, NDC2011
 
주변의 임베디드 시스템 찾기 - 지하철 전광판
주변의 임베디드 시스템 찾기 - 지하철 전광판주변의 임베디드 시스템 찾기 - 지하철 전광판
주변의 임베디드 시스템 찾기 - 지하철 전광판
 
이원 김한경, 거의 모든 무기의 역사, NDC2013
 이원 김한경, 거의 모든 무기의 역사, NDC2013 이원 김한경, 거의 모든 무기의 역사, NDC2013
이원 김한경, 거의 모든 무기의 역사, NDC2013
 
2015 한양대 직무특강 IT 개발자 이야기
2015 한양대 직무특강 IT 개발자 이야기2015 한양대 직무특강 IT 개발자 이야기
2015 한양대 직무특강 IT 개발자 이야기
 
Character Rigging Animation Tutorial with Custom Rigg Controller
Character Rigging Animation Tutorial with Custom Rigg ControllerCharacter Rigging Animation Tutorial with Custom Rigg Controller
Character Rigging Animation Tutorial with Custom Rigg Controller
 

Semelhante a KGC2010 김주복, 김충효 - M2 프로젝트의 절차적 리깅 시스템

NDC2011 - 카메라 시스템을 통해 살펴보는 인터랙티브 시스템 개발의 문제점
NDC2011 - 카메라 시스템을 통해 살펴보는 인터랙티브 시스템 개발의 문제점NDC2011 - 카메라 시스템을 통해 살펴보는 인터랙티브 시스템 개발의 문제점
NDC2011 - 카메라 시스템을 통해 살펴보는 인터랙티브 시스템 개발의 문제점Jubok Kim
 
Project Anarchy(Vision Engine)으로 게임 툴 만들기! part2
Project Anarchy(Vision Engine)으로 게임 툴 만들기! part2Project Anarchy(Vision Engine)으로 게임 툴 만들기! part2
Project Anarchy(Vision Engine)으로 게임 툴 만들기! part2진상 문
 
역동적인 애니메이션 Ik
역동적인 애니메이션 Ik역동적인 애니메이션 Ik
역동적인 애니메이션 IkKyeongWon Koo
 
LINC3.0 캡스톤디자인 경진대회_로운팀.pptx
LINC3.0 캡스톤디자인 경진대회_로운팀.pptxLINC3.0 캡스톤디자인 경진대회_로운팀.pptx
LINC3.0 캡스톤디자인 경진대회_로운팀.pptxssuser20022f
 
Open jig-ware 6회-오로카세미나pptx
Open jig-ware 6회-오로카세미나pptxOpen jig-ware 6회-오로카세미나pptx
Open jig-ware 6회-오로카세미나pptxJinwook On
 
[NDC_16] 캐릭터 한 달에 하나씩 업데이트 하기 : '최강의 군단' 스킬 개발 툴 포스트 모템과 차기작 '건파이트 맨션' 툴 프리뷰
[NDC_16] 캐릭터 한 달에 하나씩 업데이트 하기 : '최강의 군단' 스킬 개발 툴 포스트 모템과 차기작 '건파이트 맨션' 툴 프리뷰[NDC_16] 캐릭터 한 달에 하나씩 업데이트 하기 : '최강의 군단' 스킬 개발 툴 포스트 모템과 차기작 '건파이트 맨션' 툴 프리뷰
[NDC_16] 캐릭터 한 달에 하나씩 업데이트 하기 : '최강의 군단' 스킬 개발 툴 포스트 모템과 차기작 '건파이트 맨션' 툴 프리뷰승민 백
 
Unity cookbook 9
Unity cookbook 9Unity cookbook 9
Unity cookbook 9Jihun Soh
 
[Paper Review] Image captioning with semantic attention
[Paper Review] Image captioning with semantic attention[Paper Review] Image captioning with semantic attention
[Paper Review] Image captioning with semantic attentionHyeongmin Lee
 
Kgc2013 defense technica_converting_이상윤
Kgc2013 defense technica_converting_이상윤Kgc2013 defense technica_converting_이상윤
Kgc2013 defense technica_converting_이상윤SangYun Yi
 
Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례
Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례
Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례SangYun Yi
 
Project anarchy로 3d 게임 만들기 part_3_움직여라 움직여
Project anarchy로 3d 게임 만들기 part_3_움직여라 움직여Project anarchy로 3d 게임 만들기 part_3_움직여라 움직여
Project anarchy로 3d 게임 만들기 part_3_움직여라 움직여Dong Chan Shin
 
OpenJigWare(V02.00.04)
OpenJigWare(V02.00.04)OpenJigWare(V02.00.04)
OpenJigWare(V02.00.04)Jinwook On
 
[박민근] 3 d렌더링 옵티마이징_4 임포스터_인스턴싱
[박민근] 3 d렌더링 옵티마이징_4 임포스터_인스턴싱[박민근] 3 d렌더링 옵티마이징_4 임포스터_인스턴싱
[박민근] 3 d렌더링 옵티마이징_4 임포스터_인스턴싱MinGeun Park
 
데브루키 IK 1편
데브루키 IK 1편데브루키 IK 1편
데브루키 IK 1편Soochan Park
 
2017 12 09_데브루키_리얼타임 렌더링_입문편(3차원 그래픽스[저자 : 한정현] 참조)
2017 12 09_데브루키_리얼타임 렌더링_입문편(3차원 그래픽스[저자 : 한정현] 참조)2017 12 09_데브루키_리얼타임 렌더링_입문편(3차원 그래픽스[저자 : 한정현] 참조)
2017 12 09_데브루키_리얼타임 렌더링_입문편(3차원 그래픽스[저자 : 한정현] 참조)Sukwoo Lee
 
지능 Baram 보고서
지능 Baram 보고서지능 Baram 보고서
지능 Baram 보고서NAVER D2
 
Agile의 의미와 Agile 계획 수립(Gdc2007)
Agile의 의미와 Agile 계획 수립(Gdc2007)Agile의 의미와 Agile 계획 수립(Gdc2007)
Agile의 의미와 Agile 계획 수립(Gdc2007)Kay Kim
 

Semelhante a KGC2010 김주복, 김충효 - M2 프로젝트의 절차적 리깅 시스템 (20)

NDC2011 - 카메라 시스템을 통해 살펴보는 인터랙티브 시스템 개발의 문제점
NDC2011 - 카메라 시스템을 통해 살펴보는 인터랙티브 시스템 개발의 문제점NDC2011 - 카메라 시스템을 통해 살펴보는 인터랙티브 시스템 개발의 문제점
NDC2011 - 카메라 시스템을 통해 살펴보는 인터랙티브 시스템 개발의 문제점
 
Project Anarchy(Vision Engine)으로 게임 툴 만들기! part2
Project Anarchy(Vision Engine)으로 게임 툴 만들기! part2Project Anarchy(Vision Engine)으로 게임 툴 만들기! part2
Project Anarchy(Vision Engine)으로 게임 툴 만들기! part2
 
역동적인 애니메이션 Ik
역동적인 애니메이션 Ik역동적인 애니메이션 Ik
역동적인 애니메이션 Ik
 
LINC3.0 캡스톤디자인 경진대회_로운팀.pptx
LINC3.0 캡스톤디자인 경진대회_로운팀.pptxLINC3.0 캡스톤디자인 경진대회_로운팀.pptx
LINC3.0 캡스톤디자인 경진대회_로운팀.pptx
 
Devtree illu
Devtree illuDevtree illu
Devtree illu
 
Open jig-ware 6회-오로카세미나pptx
Open jig-ware 6회-오로카세미나pptxOpen jig-ware 6회-오로카세미나pptx
Open jig-ware 6회-오로카세미나pptx
 
[NDC_16] 캐릭터 한 달에 하나씩 업데이트 하기 : '최강의 군단' 스킬 개발 툴 포스트 모템과 차기작 '건파이트 맨션' 툴 프리뷰
[NDC_16] 캐릭터 한 달에 하나씩 업데이트 하기 : '최강의 군단' 스킬 개발 툴 포스트 모템과 차기작 '건파이트 맨션' 툴 프리뷰[NDC_16] 캐릭터 한 달에 하나씩 업데이트 하기 : '최강의 군단' 스킬 개발 툴 포스트 모템과 차기작 '건파이트 맨션' 툴 프리뷰
[NDC_16] 캐릭터 한 달에 하나씩 업데이트 하기 : '최강의 군단' 스킬 개발 툴 포스트 모템과 차기작 '건파이트 맨션' 툴 프리뷰
 
Unity cookbook 9
Unity cookbook 9Unity cookbook 9
Unity cookbook 9
 
Proposal
ProposalProposal
Proposal
 
[Paper Review] Image captioning with semantic attention
[Paper Review] Image captioning with semantic attention[Paper Review] Image captioning with semantic attention
[Paper Review] Image captioning with semantic attention
 
Kgc2013 defense technica_converting_이상윤
Kgc2013 defense technica_converting_이상윤Kgc2013 defense technica_converting_이상윤
Kgc2013 defense technica_converting_이상윤
 
Gametech2015
Gametech2015Gametech2015
Gametech2015
 
Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례
Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례
Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례
 
Project anarchy로 3d 게임 만들기 part_3_움직여라 움직여
Project anarchy로 3d 게임 만들기 part_3_움직여라 움직여Project anarchy로 3d 게임 만들기 part_3_움직여라 움직여
Project anarchy로 3d 게임 만들기 part_3_움직여라 움직여
 
OpenJigWare(V02.00.04)
OpenJigWare(V02.00.04)OpenJigWare(V02.00.04)
OpenJigWare(V02.00.04)
 
[박민근] 3 d렌더링 옵티마이징_4 임포스터_인스턴싱
[박민근] 3 d렌더링 옵티마이징_4 임포스터_인스턴싱[박민근] 3 d렌더링 옵티마이징_4 임포스터_인스턴싱
[박민근] 3 d렌더링 옵티마이징_4 임포스터_인스턴싱
 
데브루키 IK 1편
데브루키 IK 1편데브루키 IK 1편
데브루키 IK 1편
 
2017 12 09_데브루키_리얼타임 렌더링_입문편(3차원 그래픽스[저자 : 한정현] 참조)
2017 12 09_데브루키_리얼타임 렌더링_입문편(3차원 그래픽스[저자 : 한정현] 참조)2017 12 09_데브루키_리얼타임 렌더링_입문편(3차원 그래픽스[저자 : 한정현] 참조)
2017 12 09_데브루키_리얼타임 렌더링_입문편(3차원 그래픽스[저자 : 한정현] 참조)
 
지능 Baram 보고서
지능 Baram 보고서지능 Baram 보고서
지능 Baram 보고서
 
Agile의 의미와 Agile 계획 수립(Gdc2007)
Agile의 의미와 Agile 계획 수립(Gdc2007)Agile의 의미와 Agile 계획 수립(Gdc2007)
Agile의 의미와 Agile 계획 수립(Gdc2007)
 

Mais de Jubok Kim

선형 최소 자승 최적화
선형 최소 자승 최적화선형 최소 자승 최적화
선형 최소 자승 최적화Jubok Kim
 
GDC2013 트렌드리뷰
GDC2013 트렌드리뷰GDC2013 트렌드리뷰
GDC2013 트렌드리뷰Jubok Kim
 
NDC2013 - 심리학으로 다시 보는 게임 디자인
NDC2013 - 심리학으로 다시 보는 게임 디자인NDC2013 - 심리학으로 다시 보는 게임 디자인
NDC2013 - 심리학으로 다시 보는 게임 디자인Jubok Kim
 
GDC2012 트렌드 리뷰
GDC2012 트렌드 리뷰GDC2012 트렌드 리뷰
GDC2012 트렌드 리뷰Jubok Kim
 
NDC2011 - 절차적 지형과 트렌드의 추적자들
NDC2011 - 절차적 지형과 트렌드의 추적자들NDC2011 - 절차적 지형과 트렌드의 추적자들
NDC2011 - 절차적 지형과 트렌드의 추적자들Jubok Kim
 
GDC2011 - Implementation and Application of the Real-Time Helper-Joint System
GDC2011 - Implementation and Application of the Real-Time Helper-Joint SystemGDC2011 - Implementation and Application of the Real-Time Helper-Joint System
GDC2011 - Implementation and Application of the Real-Time Helper-Joint SystemJubok Kim
 
The Art of Project Management #13 일을 추진하는 방법
The Art of Project Management #13 일을 추진하는 방법The Art of Project Management #13 일을 추진하는 방법
The Art of Project Management #13 일을 추진하는 방법Jubok Kim
 
The Art of Project Management #4 좋은 비전 작성하기
The Art of Project Management #4 좋은 비전 작성하기The Art of Project Management #4 좋은 비전 작성하기
The Art of Project Management #4 좋은 비전 작성하기Jubok Kim
 
고대특강 게임 프로그래머의 소양
고대특강   게임 프로그래머의 소양고대특강   게임 프로그래머의 소양
고대특강 게임 프로그래머의 소양Jubok Kim
 

Mais de Jubok Kim (9)

선형 최소 자승 최적화
선형 최소 자승 최적화선형 최소 자승 최적화
선형 최소 자승 최적화
 
GDC2013 트렌드리뷰
GDC2013 트렌드리뷰GDC2013 트렌드리뷰
GDC2013 트렌드리뷰
 
NDC2013 - 심리학으로 다시 보는 게임 디자인
NDC2013 - 심리학으로 다시 보는 게임 디자인NDC2013 - 심리학으로 다시 보는 게임 디자인
NDC2013 - 심리학으로 다시 보는 게임 디자인
 
GDC2012 트렌드 리뷰
GDC2012 트렌드 리뷰GDC2012 트렌드 리뷰
GDC2012 트렌드 리뷰
 
NDC2011 - 절차적 지형과 트렌드의 추적자들
NDC2011 - 절차적 지형과 트렌드의 추적자들NDC2011 - 절차적 지형과 트렌드의 추적자들
NDC2011 - 절차적 지형과 트렌드의 추적자들
 
GDC2011 - Implementation and Application of the Real-Time Helper-Joint System
GDC2011 - Implementation and Application of the Real-Time Helper-Joint SystemGDC2011 - Implementation and Application of the Real-Time Helper-Joint System
GDC2011 - Implementation and Application of the Real-Time Helper-Joint System
 
The Art of Project Management #13 일을 추진하는 방법
The Art of Project Management #13 일을 추진하는 방법The Art of Project Management #13 일을 추진하는 방법
The Art of Project Management #13 일을 추진하는 방법
 
The Art of Project Management #4 좋은 비전 작성하기
The Art of Project Management #4 좋은 비전 작성하기The Art of Project Management #4 좋은 비전 작성하기
The Art of Project Management #4 좋은 비전 작성하기
 
고대특강 게임 프로그래머의 소양
고대특강   게임 프로그래머의 소양고대특강   게임 프로그래머의 소양
고대특강 게임 프로그래머의 소양
 

KGC2010 김주복, 김충효 - M2 프로젝트의 절차적 리깅 시스템

  • 1. M2 프로젝트의 절차적 캐릭터리깅시스템 NEXON devCAT 김주복, 김충효 Ⓒ 2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Project W in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dungeon | Project W is produced by Kim, Dungeon
  • 2. twitter.com/eiaserinnys 김주복 애니메이션프로그래밍10년차 2001 무선사업팀 도트디자이너 2001 마비노기팀 리드 프로그래머 2003 마비노기 프로그래밍팀 팀장 2005 그룹웨어 개발팀 팀장 2006 W팀 테크니컬 디렉터 2008 개발3본부 3실 실장 2009 마비노기 2 개발 디렉터 2010 신규개발3본부 1실 실장
  • 3. 넥슨 신규개발 3본부 김충효 2001년 입사 / 마비노기1 프로젝트 합류 2006년 마비노기2 프로젝트 합류 2010년 현재 M2팀 팀장 / 넥슨 아트 직군장 Ⓒ 2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Project W in The 3rd Development Division in NEXON Corp. M2 team Director is Kim, Dungeon | Project W is produced by Kim, Dungeon
  • 4. 모델링 애니메이팅 리깅 스크립팅… Ⓒ 2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Project W in The 3rd Development Division in NEXON Corp. M2 team Director is Kim, Dungeon | Project W is produced by Kim, Dungeon
  • 6. 시간의 흐름에 따른 실루엣의 변화가 바로 애니메이션이다 라고 해도 과언이 아님…
  • 7. 3D 캐릭터를 애니메이션 시킨다는 것은 표면의 Vertex를 움직인다는 것이다 어떤 수단을 사용해도 상관 없다. 버텍스를 움직여서 표면 실루엣을 변화시키는 모든 방법이 캐릭터를 애니메이션 시키는 방법이 된다.
  • 8. 캐릭터 디포메이션의 방법 캐릭터 애니메이션의 방법
  • 9. 일반적인 3D 캐릭터 Skeletal Animation 골격 구조의 뼈대를 움직여서 캐릭터를 변형시킨다.
  • 10. 물론 뼈 없이 애니메이션을 시킬 수 있지만… Vertex Morph 를 활용한 방법이 대표적 하지만 이것만 가지고는 캐릭터 전체를 움직이기 힘들다.
  • 11. 일반적인 게임 캐릭터에는 (보통)뼈! 만 있다… Runtime 으로 변형이 일어나야 하기도 하고 애니메이션 데이터가 무한정 커질 수 없기 때문에 일반적인 게임 캐릭터는 Skeletal Animation 을 한다. 뼈대를 다양하게 활용해서 캐릭터의 미세한 변형을 표현하는 것이 현 시대의 일반적인 표현 방법이다.
  • 12. Surface Model + Skeletal Animation 지긋지긋한… Skinning !! Vertex 의 위치가 관절의 위치와 방향을 따라간다. Skinning 과정을 통해서 어떤 관절에 어느 정도로 따라가게 될 지 결정됨
  • 13. 현 세대 캐릭터의 표현수준
  • 14. 만들기 난해하다 차세대 수준의 캐릭터가 요구하는 표현 수준이 너무 높다. 노말맵을 비롯한 여러 가지 맵소스도 만들어야 하고 폴리곤의 수도 엄청 많아야 한다.
  • 15. 요즘의 플레이어들은 자비가 없다 과거에는 기술적 한계로 인해 용납되던 것 들이 지금은 결점으로 받아들여진다. 요구 퀄리티가 엄청나게 높아졌다.
  • 16. 적은 수의 관절은 한계가 있다 실루엣의 변형은 거의 전적으로 관절의 움직임에 의존함 원하는 수준으로 실루엣을 변형 시키려면 과거처럼 관절을 아껴서 쓸 수 없다!!
  • 17. 과거와 같은 수준의 관절로는 더 이상 무리 ex) Candy Wrap 현상
  • 19. 가장 일반적인 방법은 보조 관절의 사용 문제가 일어나는 부분, 혹은 더 잘 표현하고 싶은 부분에 임의로 관절을 더 설치한다. 해당 관절을 수동으로 움직이거나, 주요 관절의 움직임에 자동으로 반응하게 해서 더 좋은 퀄리티의 실루엣을 얻는다.
  • 20. 예시) 트위스트 관절 Candy Wrap 현상을 막는 대표적인 방법 보통 손이나 발목 관절 등의 회전에 따라 자동으로 동작한다.
  • 21. 예시) 상완 이두근 관절
  • 22. 선택의 여지 없음 보조 관절을 사용하지 않고 5000 tri 이상의 차세대급 캐릭터를 원하는 대로 아름답게 표현할 방법이 없다.
  • 24. 보조 관절의 증가는? 애니메이션 데이터 규모의 증가 보조 관절이 많으면 그만큼 많은 데이터를 익스포트 해야 한다.
  • 25. 또한, Pre-Baked 라는 것은 데이터의 유연성 감소 프레임워크의 변화에 유연하게 대응하기 힘들고 절차적인 애니메이션에 반응하기 어렵다.
  • 26. 끔찍한 경우 1 보조 관절의 동작이 변했다면? 트위스트 관절이나 기타 근육을 표현하는 관절의 동작이 만족스럽지 않아서 동작을 조금 고쳤어요…
  • 27. 끔찍한 경우 2 보조 관절의 수가 늘어났다면? 아무래도 어깨 표현이 잘 안 되는 것 같은 판단이 들어서 어깨 부분에 보조 관절을 추가했어요… 물론 캐릭터 메시 스키닝도 다시했지요…
  • 28. 끔찍한 경우 3 의상 별로 서로 다른 보조 관절을 써야 한다면? MMORPG 이니까 코스튬 퀄리티가 중요함. 의상마다 최상의 퀄리티를 유지할 필요 있음. 각각의 의상에 특화된 보조 관절을 사용하게 된다면?
  • 29. 프로그래머 입장에서는… 보조 관절을 사용하는 캐릭터가 Rag Doll 처리 된다면? Rag doll 혹은 IK 처리 등으로 인해서 미리 구워진 애니메이션과 다른 동작을 하게 되면 보조 관절은 어떻게 동작해야 하는 거지?
  • 30.
  • 31. 보조 관절과 Pre-Baked Animation 애니메이션 데이터의 증가 뿐만 아니라, 프레임워크 데이터를 변경하기 힘들어짐을 의미한다
  • 32. 보조 관절과 Pre-Baked Animation 프레임워크가 다른 의상 마다 모든 애니메이션을 따로 준비해야 한다 솔직히 이건 말도 안 되는 선택지이다.
  • 33. 보조 관절과 Pre-Baked Animation 말하자면, 애니메이션 데이터가 프레임워크 종속적이 된다는 것이다 캐릭터 릭의 개선을 통해서 퀄리티를 계속 높여가는 것에 커다란 장애 요소가 된다.
  • 35. Needs: 미리 구워내지 않아도 클라이언트에서 DCC툴과 동일하게 동작 하는 보조관절이 필요 애니메이션 데이터의 크기 감소와 작업 파이프라인의 유연성의 확보 및 절차적 애니메이션에의 반응성 확보
  • 36. Objective: 절차적 보조 관절 구현! 클라이언트에서 3ds max 에서 구현한 것과 완전히 동일하게 동작하는 관절을 구현해야 한다!!
  • 38. 프로그래머 입장에서는 무엇을 구현해야 DCC툴에서와 같은 퀄리티를 낼 수 있는지 알 수 없다 프로그래머들에게는 3ds max는 거대한 블랙박스와 같다.
  • 39. (아티스트가 칭얼거려서…) 니즈는 확보했는데… 궁극적인 골은 어디? 구체적으로 어떤 것 들을 구현해야 하는지 결정해야 했다. 니즈를 찾았으니, 문제를 구체화 하고 목표를 설정해야 함
  • 40. 일단! 아티스트가 원하는 최적의 상태를 3ds max로 만들자 캐릭터의 누드 메시가 DCC툴에서 최적의 상태로 나올 수 있도록 프레임워크 세팅을 진행
  • 41. 고심 결과, 작업 진행은 당연히 여성 캐릭터로… 여성 캐릭터의 누드를 아름답게 연출할 수 있을 정도면 남자는 손쉽게 할 수 있을 것이다. 의욕 문제도 있고…
  • 43. 그런데… 내가 원하는 상태? 나도 잘 모르겠다만… 어디가 어려운지는 안다 나도 근육 같은 것 세팅해본 경험 별로 없다… 경험적으로 어떤 부분의 스키닝이 잘 안 되는지는 알고 있다.
  • 45. 매력 포인트라서… 더 잘 해보고 싶은 곳
  • 46. 스키닝 방식이 바뀌지 않는 한… 트위스트가 필요한 곳
  • 48. 특히 어깨!!! 부분은 Candy Wrap 현상이 가장 심하게 일어난다
  • 50. 현실에서의 어깨 표면이 어떤 식으로 움직이는지 연구 진행 피부의 변형을 이해하는 것은 관절의 움직임을 이해하는 것 과는 또 다른 영역이다. 궁극적으로 피부 실루엣의 변형을 묘사해야 함
  • 51.
  • 52.
  • 53.
  • 55.
  • 57. 스키닝을 하지는 않지만 올바르게 동작하는 데 필요한 관절도 있다… 피부를 변형시키는 데 직접 관여하지는 않지만 관절들의 최종 위치를 계산하기 위해서는 나름대로 동작을 할 필요가 있는 관절들
  • 59. 주요 기능 ExposeTM Expose Transform Matrix (Helper) 특정 관절의 현재 상태를 알아낼 수 있다. Local/World Position (관절의 위치) Local/World Euler Angle (관절의 회전) Distance (두 관절 사이의 거리) :
  • 60. 주요 기능 Position Constraint 특정 관절의 위치를 그대로 따라가거나, 둘 이상의 관절들의 위치를 적당히 내분하는 지점에 위치하게 된다.
  • 61. 주요 기능 LookAt Constraint 이름 그대로… 특정 관절(들)의 위치를 계속 쳐다본다. Upnode 를 잘 활용해야 함.
  • 62. 주요 기능 Rotation List 둘 이상의 Rotation Controller 의 계산 결과를 특정 비율로 나눠서 적용할 수 있다.
  • 63. 주요 기능 Reaction Controller Master 가 되는 “무엇”의 변화에 따라 Slave 가 되는 “무엇”의 상태를 결정할 수 있다. Master Slave
  • 65. 핵심 관절 Shoulder 1 Shoulder 2 삼각근의 다양한 변형 및 부풀어 오름에 대응하기 위한 관절
  • 66. 핵심 관절 Shoulder 1 Shoulder 2 삼각근의 다양한 변형 및 부풀어 오름에 대응하기 위한 관절
  • 67. Shoulder 동작의 기본 아이디어 팔의 회전이 어떤 상태이냐에 따라 어깨의 위치와 방향이 결정된다.
  • 68. Shoulder 1 의 동작 팔 관절 ExposeTM Shoulder 1 Local Rotation Position Reaction Controller Rotation LookAt Constraint Up Node Up Node Position Reaction Controller
  • 69. Shoulder 2 의 동작 팔 관절 ExposeTM Shoulder 2 Local Rotation Position Reaction Controller Rotation Reaction Controller
  • 71. 승모근 동작의 기본 아이디어 어깨와 목을 연결한 선 위에 위치한다. 어깨 쪽을 계속 바라보고 있다. 척추 방향으로 정렬되어있다.
  • 72. 상박 트위스트 관절의 기본 아이디어 항상 Upper Arm 관절의 길이 방향으로 정렬되어 있다. Upper Arm 관절의 회전 정도와 Shoulder 관절의 회전 정도를 적당히 분배한다.
  • 73. 상박 트위스트 관절의 동작 Upper Arm 의 Upnode 방향과 Shoulder 의 Upnode 방향을 일정 비율로 섞었다.
  • 74. 흉근과 견갑골 동작의 기본 아이디어 LookAt Constraint를 활용한 단순한 동작. 대신 부모 관절의 움직임으로 인해 복잡한 움직임을 보임. 흉근 견갑골
  • 80. 간단한 구현 방법 ExposeTM 으로 측정하고, Reaction Controller 로 결정한다.
  • 81. 여성 누드 캐릭터가 충분히 만족스러운 상황이라고 판단!! 대략적인 구현 목표 추출 Reaction Controller LookAt Constraint Position Constraint Orientation Constraint Expression Controller Wire Parameter ExposeTM : 조금 많은가?
  • 82. 목록이 많다 어쩌다 해도 결국 다 구현하긴 했다 Reaction Controller LookAt Constraint Position Constraint Orientation Constraint Expression Controller Wire Parameter ExposeTM :
  • 84. 절차적 리깅 시스템의 구현 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 85. 3DS MAX컨트롤러의 구현 사례 디펜던시와 계산 순서 문제 최 적 화 관 련 이 슈 월드 트랜스폼 문제 | 스케일을 가진 트랜스폼 문제 | 실수 계산 성능 퍼포먼스 및 장단점 분석, 결론 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 86. 3DS MAX컨트롤러의 구현 사례 디펜던시와 계산 순서 문제 최 적 화 관 련 이 슈 월드 트랜스폼 문제 | 스케일을 가진 트랜스폼 문제 | 실수 계산 성능 퍼포먼스 및 장단점 분석, 결론 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 87. 3DS MAX의 컨트롤러는 IReactor란 이름으로 구현되어 있다 공통 인터페이스 // 실제 인터페이스와 일치하지 않는 것에 주의 class IReactor { public: virtual void Preprocess() = 0; virtual void Process(const ProcessOption&) =0; virtual const ReactorResult& GetResult() const = 0; };
  • 88. PositionConstraint는 본을 타겟 본들의 가중 평균에 놓는다 위치를 블렌딩한다
  • 89. 아들이 아버지와 어머니, 어느 쪽에도 치우치지 않는 중간적인 위치를 견지하고 있다 <어른의 인형 놀이> 중 M2 PSM, 한상원
  • 90. 첫번째로 접하는 컨트롤러이니만큼 구현이… 너무나 쉬운 컨트롤러 void PositionConstraint::Process(/* 생략 */) { 위치 컨스트레인트 타겟 위치를 가중치 합산 [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산 T를 이용, 합산 결과를 부모의 로컬 공간으로 이동 계산된 결과를 저장 }
  • 91. 컨스트레인트 타겟의 위치를 블렌딩한다 1. 목표 지점을 계산 void PositionConstraint::Process(/* 생략 */) { 위치 컨스트레인트 타겟 위치를 가중치 합산 [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산 T를 이용, 합산 결과를 부모의 로컬 공간으로 이동 계산된 결과를 저장 }
  • 92. 블렌딩된 위치를 포지션 컨스트레인트가 걸려 있는 본의 2. 로컬 좌표로 변환 void PositionConstraint::Process(/* 생략 */) { 위치 컨스트레인트 타겟 위치를 가중치 합산 [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산 T를 이용, 합산 결과를 부모의 로컬 공간으로 이동 계산된 결과를 저장 }
  • 93. 슈도 코드 뿐만 아니라… 실제 코드도 간단
  • 94. 롤 아웃에 있는 뭔가 수상한 옵션은?
  • 95. Keep Initial Offset 옵션은 포지션 컨트스트레인트 계산 결과와 초기의 어긋남을 보존 PositionAtConstraint가 Keep initial offset 걸려 있는 본의 옵션에 의해서 바인드 포즈의 위치 이동된 위치
  • 96. Keep Initial Offset 옵션을 포함하는 옵셋을 반영한 슈도코드 void PositionConstraint::Preprocess() { keep initial offset이 켜진 경우, 포지션 컨스트레인트의 계산 결과와 바인드 포즈의 차이를 [옵셋]으로 보존해둔다 } void PositionConstraint::Process(/* 생략 */) { 위치 컨스트레인트 타겟 위치를 가중치 합산 [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산 T를 이용, 합산 결과를 부모의 로컬 공간으로 이동 keep initial offset이 켜진 경우, 계산 결과에 [옵셋]을 더한다 계산된 결과를 저장 } 40
  • 97. 다른 컨트롤러의 구현 방법에 관련된 사항은 추가 노트에 수록
  • 98. 3DS MAX컨트롤러의 구현 사례 디펜던시와 계산 순서 문제 최 적 화 관 련 이 슈 월드 트랜스폼 문제 | 스케일을 가진 트랜스폼 문제 | 실수 계산 성능 퍼포먼스 및 장단점 분석, 결론 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 99. 전통적인 애니메이션 프로그래밍에서 트랜스폼은 순서대로 계산 인덱스 순서대로? 0 1 8 2 5 9 10 3 4 6 7 11 12 13 14
  • 100. 하지만 보조 본들은 순서대로 계산된다고 보장할 수 없다 다른 본을 참조하면? 0 1 8 2 5 9 10 3 4 6 7 11 12 13 14
  • 101. 좋은 방법이 떠오르지 않으니 일단… 개별 컨트롤러가 계산? void PositionConstraint::Process(/* 생략 */) { [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산 위치 컨스트레인트 타겟 위치를 가중치 합산 T를 이용, 합산 결과를 부모의 로컬 공간으로 이동 keep initial offset이 켜진 경우, 계산 결과에 [옵셋]을 더한다 계산된 결과를 저장 } void PositionConstraint::GetDependancy(vector<int>& dependancies) { dependancies에 위치 컨스트레인트 타겟들을 추가한다 } 90
  • 102. 이 방법이 그렇게 쉽지가 않다 구현에 따라서 복잡 void LookAtConstraint::Process(/* 생략 */) { [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산 자신의 위치를 T를 사용해서 부모 공간으로 변환 쳐다보기 타겟의 위치를 가중치 합산 T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산 위쪽 방향 타겟을 T를 사용, 업 벡터를 계산 앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장 } void LookAtConstraint::GetDependancy(vector<int>& dependancies) { dependancies에 쳐다보기 타겟들을 추가한다 dependancies에 업 노드를 추가한다 }
  • 103. 컨트롤러 타입에 따라서 점점 더 복잡해지고 ReactionController? const ReactorResult ReactionControllerBase::Process(/* 생략 */) { 정렬된 마스터/슬레이브 리액션 리스트에서 주어진 마스터 값을 넘지 않으면서 가장 큰 마스터/슬레이브 인덱스를 찾는다 찾아낸 리액션과 다음 리액션을 보간하여 반환한다 } void ReactionControllerBase::GetDependancy(vector<int>& dependancies) { foreach (마스터 값 m에 대해서) m.GetDependancy(dependancies); } void IReactorExprIDHandler::GetDependancy(vector<int>& dependancies) { 익스포즈 노드를 dependancies에 추가한다 레퍼런스 노드를 dependancies에 추가한다 }
  • 104. 감당해야 할 필요가 없는 복잡한 작업을 감당해야 하는 상황에 이른다 수식에서는…??? class ReactorExpressionBinary { void GetDependancy(std::vector<int>& dependancies); }; class ReactorExpressionID { void GetDependancy(std::vector<int>& dependancies); }; class ReactorExpressionFunction { void GetDependancy(std::vector<int>& dependancies); }; class ReactorExpressionConstant { void GetDependancy(std::vector<int>& dependancies); }; class ReactorExpressionList { void GetDependancy(std::vector<int>& dependancies); }; class ReactorExpressionFunction { void GetDependancy(std::vector<int>& dependancies); };
  • 105. 타이핑도 많아지고 근본적으로 실수하기가 쉽다 저절로 계산할 수 없나?
  • 106. 더미 연산을 통해 리액터가 트랜스폼 데이터를 요구하는 것을 가로채자 후킹을 통한 접근 PositionConstraint LookAtConstraint IReactorPoseSource GetWorldTranslation(int boneIndex) OrientationConstraint GetWorldRotation(int boneIndex) GetWorldScale(int boneIndex) PositionReactionController GetLocalTranslation(int boneIndex) GetLocalRotation(int boneIndex) RotationReactionController GetLocalScale(int boneIndex) GetWorldTransform(int boneIndex) ScaleReactionConstraint … FloatWireConstraint
  • 107. 0~10번까지 트랜슬레이션, 회전, 스케일을 순서대로 순회한 결과 PositionConstraint 9, 10 OrientationConstraint 12 ScaleXYZ bone11 ReactorTraversalBuilder : public IReactorPoseSource PositionXYZ … 10 LookAtConstraint 24 ScaleXYZ bone12
  • 108. PositionConstraint 9, 10 OrientationConstraint 12 ScaleXYZ bone11 ReactorTraversalBuilder : public IReactorPoseSource PositionXYZ … 10 LookAtConstraint 24 ScaleXYZ bone12
  • 109. PositionConstraint 9, 10 OrientationConstraint 12 ScaleXYZ bone11 ReactorTraversalBuilder : public IReactorPoseSource PositionXYZ … 10 LookAtConstraint 24 ScaleXYZ bone12
  • 110. PositionConstraint 9, 10 OrientationConstraint 12 ScaleXYZ bone11 ReactorTraversalBuilder : public IReactorPoseSource PositionXYZ … 10 LookAtConstraint 24 ScaleXYZ bone12 100
  • 111. PositionConstraint 9, 10 OrientationConstraint 12 ScaleXYZ bone11 ReactorTraversalBuilder : public IReactorPoseSource PositionXYZ … 10 24 LookAtConstraint 24 ScaleXYZ bone12
  • 112. PositionConstraint 9, 10 OrientationConstraint 12 ScaleXYZ bone11 ReactorTraversalBuilder : public IReactorPoseSource PositionXYZ … 10 24 12 LookAtConstraint 24 ScaleXYZ bone12
  • 113. PositionConstraint 9, 10 OrientationConstraint 12 ScaleXYZ bone11 ReactorTraversalBuilder : public IReactorPoseSource PositionXYZ … 10 24 12 LookAtConstraint 24 ScaleXYZ bone12
  • 114. PositionConstraint 9, 10 OrientationConstraint 12 ScaleXYZ bone11 ReactorTraversalBuilder : public IReactorPoseSource PositionXYZ … 10 24 12 11 LookAtConstraint 24 ScaleXYZ bone12
  • 115. 자동으로 계산 순서를 구축하기 때문에, 기능을 확장하더라도 안전, 정확한 순서 보장
  • 116. 3DS MAX컨트롤러의 구현 사례 디펜던시와 계산 순서 문제 최 적 화 관 련 이 슈 월드 트랜스폼 문제 | 스케일을 가진 트랜스폼 문제 | 실수 계산 성능 퍼포먼스 및 장단점 분석, 결론 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 117. 거의 대부분의 컨트롤러의 계산 과정에서 월드 트랜스폼을 요구 void OrientationConstraint::Preprocess() { keep initial offset이 켜진 경우, 오리엔테이션 컨스트레인트의 계산 결과와 바인드 포즈의 차이를 [회전 옵셋]으로 보존해둔다 } void OrientationConstraint::Process(/* 생략 */) { if (로컬 공간 보간 모드) 컨스트레인트 타겟의 로컬 회전을 기록 else // 월드 공간 보간 모드 컨스트레인트 타겟을 부모 본의 로컬 공간으로 옮겨서 기록 가중치 합산하여 회전을 계산한다 keep initial offset이 켜진 경우, 계산 결과에 [회전 옵셋]을 더한다 계산 결과를 저장 }
  • 118. 문제는 컨트롤러 계산 결과가 적용되는 과정에서 서브 트리가 무효화
  • 119. 본 수가 무지막지하게 많기 때문에 모든 월드 트랜스폼을 업데이트하는 것은 치명적 성능 문제의 원인 110
  • 120. 최소한으로 월드 트랜스폼을 재계산하기 위해서 조상/후손 리스트 관리 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 0 234567 1 8 9 10 11 12 13 14 01 08 34 2 5 9 12 13 14 012 0 8 12 3 4 6 7 10 11 13 14
  • 121. 특정 본이 재설정되면 후손 리스트의 월드 트랜스폼만 무효화한다 최소 범위 무효화 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 0 234567 1 8 9 10 11 12 13 14 01 08 34 2 5 9 12 13 14 012 0 8 12 3 4 6 7 10 11 13 14
  • 122. 특정 본의 월드 트랜스폼이 필요하면 조상 리스트만 검색한다 최소 범위 재계산 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 0 234567 1 8 9 10 11 12 13 14 01 08 34 2 5 9 12 13 14 012 0 8 12 3 4 6 7 10 11 13 14
  • 123. 메모리 상에서 캐시 관리 문제로 기대보다는 성능 향상이 낮지만 전체 재계산 회피 가능 …이라고 2009년 상반기엔 생각했었으나…
  • 124. 그때그때 계산하면 L2 캐시 미스로 인해 효율이 낮음 산발적인 접근이 문제 랜덤한 위치의 SRT와 트랜스폼을 여러 단계 찾아가게 됨 = L2 캐시 미스
  • 125. 접근하는 메모리 공간이 시간 상에서 연속하도록 재계산을 모아줄 필요 1. 월드 트랜스폼을 재계산하는 순서를 계산 ↓ 2. 개별 리액터 계산에 앞서 모아서 연산
  • 126. 포즈가 월드 트랜스폼을 재계산하는 것을 가로채 기록해두자 후킹을 통한 접근 (2) 일반 버전의 UpdateBoneWorldTransform 템플릿 특화 버전의 UpdateBoneWorldTransform
  • 127. 3DS MAX컨트롤러의 구현 사례 디펜던시와 계산 순서 문제 최 적 화 관 련 이 슈 월드 트랜스폼 문제 | 스케일을 가진 트랜스폼 문제 | 실수 계산 성능 퍼포먼스 및 장단점 분석, 결론 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 128. 거의 대부분의 컨트롤러의 계산 과정에서 부모의 역트랜스폼 요구 void OrientationConstraint::Preprocess() { keep initial offset이 켜진 경우, 오리엔테이션 컨스트레인트의 계산 결과와 바인드 포즈의 차이를 [회전 옵셋]으로 보존해둔다 } void OrientationConstraint::Process(/* 생략 */) { if (로컬 공간 보간 모드) 컨스트레인트 타겟의 로컬 회전을 기록 else // 월드 공간 보간 모드 컨스트레인트 타겟을 부모 본의 로컬 공간으로 옮겨서 기록 가중치 합산하여 회전을 계산한다 keep initial offset이 켜진 경우, 계산 결과에 [회전 옵셋]을 더한다 계산 결과를 저장 }
  • 129. 또한 많은 회전 컨트롤러의 계산 결과로 트랜스폼 → SRT 요구 void LookAtConstraint::Process(/* 생략 */) { [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산 자신의 위치를 T를 사용해서 부모 공간으로 변환 쳐다보기 타겟의 위치를 가중치 합산 T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산 위쪽 방향 타겟을 T를 사용, 업 벡터를 계산 앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장 }
  • 130. 매트릭스의 역을 구하는 연산과 SRT (스케일/회전/트랜슬레이션) 분해 두 연산 모두 비싸다 PolarDecompose와 함수 길이만으로도 SpectralDecompose의 쌀 수가 없는 비싼 두 함수를 거치는 인버스 트랜스폼 SRT 분해
  • 132. R-1 = RT (스케일이 없으면)
  • 133. SRT(M) = { (1, 1, 1), QuaternionFromMatrix(M), (M[3][1], M[3][2], M[3][3] } (스케일이 없으면)
  • 134. 스케일 안 쓰면 되잖아!!!! 아 진짜 애니메이터 여러분 부탁입니다
  • 135. 월드 트랜스폼 무효화와 유사한 형태로 스케일 여부를 관리
  • 136. 애니메이션 플레이어부터 대대적인 수정이 필요하지만 계산량 대폭 절약 가능 부모 본의 월드 트랜스폼에 스케일이 없는 경우엔 아예 인버스를 구하지 않고 수식을 풀어서 결과만 계산한다
  • 137. 3DS MAX컨트롤러의 구현 사례 디펜던시와 계산 순서 문제 최 적 화 관 련 이 슈 월드 트랜스폼 문제 | 스케일을 가진 트랜스폼 문제 | 실수 계산 성능 퍼포먼스 및 장단점 분석, 결론 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 138. 포지션/로테이션/스케일 컨트롤러 계산 과정에서 대량의 실수 연산 요구
  • 139. 특히 심각한 성능상의 영향을 미치는 것은 놀랍게도… 1/sqrt(x)
  • 140. 벡터의 노말라이즈를 비롯, 쿼터니언→매트릭스 변환 등, 많은 곳에서 사용한다 QuaternionFromMatrix
  • 141. ‘힘내! 너는 이미 이런 상황을 해결할 방법을 알고 있어!’ ‘네, 저도 이젠 손에 잡힐 듯이 보여요! 강중약약…’ 130
  • 142. 이런 상황에서 믿을 수 있는 것은… Quake III Arena 매직 위키피디아에도 등재되어 있다
  • 143. 치명적인 성능 페널티를 피할 수 있는 것은 사실이지만 수식 최적화를 우선해야
  • 144. 3DS MAX컨트롤러의 구현 사례 디펜던시와 계산 순서 문제 최 적 화 관 련 이 슈 월드 트랜스폼 문제 | 스케일을 가진 트랜스폼 문제 | 실수 계산 성능 퍼포먼스 및 장단점 분석, 결론 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 145. 벡터의 노말라이즈를 비롯, 쿼터니언→매트릭스 변환 등, 퍼포먼스 차트
  • 146. pros 물리 시뮬레이션 등, 절차적 애니메이션에 대응이 자유롭다 전체적인 애니메이션 파이프라인의 유연성이 증대된다 기계나 갑옷 등의 움직임을 묘사하는데 매우 유리하다 cons MMORPG에서 대량의 캐릭터에 사용하기엔 성능 부담이 있다 모델러 혹은 애니메이터가 활용하기 위해 기반 지식이 많이 필요하다 LOD를 고려하면 스키닝이나 프레임워크 설계가 까다롭다
  • 147. pros 물리 시뮬레이션 등, 절차적 애니메이션에 대응이 자유롭다 전체적인 애니메이션 파이프라인의 유연성이 증대된다 기계나 갑옷 등의 움직임을 묘사하는데 매우 유리하다 cons MMORPG에서 대량의 캐릭터에 사용하기엔 성능 부담이 있다 모델러 혹은 애니메이터가 활용하기 위해 기반 지식이 많이 필요하다 LOD를 고려하면 스키닝이나 프레임워크 설계가 까다롭다
  • 148. pros 물리 시뮬레이션 등, 절차적 애니메이션에 대응이 자유롭다 전체적인 애니메이션 파이프라인의 유연성이 증대된다 표현 영역을 기계나 갑옷 등의 움직임을 묘사하는데 매우 유리하다 확장하는 측면에서cons 접근 MMORPG에서 대량의 캐릭터에 사용하기엔 성능 부담이 있다 모델러 혹은 애니메이터가 활용하기 위해 기반 지식이 많이 필요하다 LOD를 고려하면 스키닝이나 프레임워크 설계가 까다롭다
  • 149. 실시간 절차적 리깅 기술은 기술의 발전의 귀결 캐릭터 표현의 복잡화 → 실시간 절차적 리깅 절차적 애니메이션
  • 150. 3DS MAX의 절차적 리깅의 복제는 비교적 쉽다
  • 152. 3DS MAX컨트롤러의 구현 사례 디펜던시와 계산 순서 문제 최 적 화 관 련 이 슈 월드 트랜스폼 문제 | 스케일을 가진 트랜스폼 문제 | 실수 계산 성능 퍼포먼스 및 장단점 분석, 결론 QA? Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 153. 추가 노트 3DS MAX 컨트롤러의 동작과 구현 룩 앳 컨 스 트 레 인 트 | 오 리 엔 테 이 션 컨 스 트 레 인 트 리액션 컨트롤러 | 수식 컨트롤러 & 플롯 와이어 | XYZ & 리스트 시리즈 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 154. 추가 노트 3DS MAX 컨트롤러의 동작과 구현 룩 앳 컨 스 트 레 인 트 | 오 리 엔 테 이 션 컨 스 트 레 인 트 리액션 컨트롤러 | 수식 컨트롤러 & 플롯 와이어 | XYZ & 리스트 시리즈 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 155. LookAtConstraint, 이름 그대로 본이 특정 위치를… 쳐다보도록 만든다
  • 156. 아버지와 어머니는 아들만 바라보고 할아버지는 멀리서 가족 모두를 지그시 바라볼 뿐, 노령 인구의 소외는 현대 한국 사회의 심각한 사회 문제로 떠오르고 있다 <어른의 인형 놀이> 중 M2 PSM, 한상원
  • 157. 기능 설명이 명료하기 때문에 상대적으로 구현이 비교적 쉬운 컨트롤러? void LookAtConstraint::Process(/* 생략 */) { [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산 자신의 위치를 T를 사용해서 부모 공간으로 변환 쳐다보기 타겟의 위치를 가중치 합산 T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산 위쪽 방향 타겟을 T를 사용, 업 벡터를 계산 앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장 }
  • 158. 자신의 위치를 부모 본의 로컬 공간으로 가져간다 1~2. 원점 계산 void LookAtConstraint::Process(/* 생략 */) { [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산 자신의 위치를 T를 사용해서 부모 공간으로 변환 쳐다보기 타겟의 위치를 가중치 합산 T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산 위쪽 방향 타겟을 T를 사용, 업 벡터를 계산 앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장 }
  • 159. 타겟을 월드 상에서 가중치 합산한 후에 부모 본의 공간으로 가져간다 3. 앞 방향 계산 void LookAtConstraint::Process(/* 생략 */) { [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산 자신의 위치를 T를 사용해서 부모 공간으로 변환 쳐다보기 타겟의 위치를 가중치 합산 T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산 위쪽 방향 타겟을 T를 사용, 업 벡터를 계산 앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장 }
  • 160. 간단할 것처럼 보이는… 4. 위 방향 계산 void LookAtConstraint::Process(/* 생략 */) { [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산 자신의 위치를 T를 사용해서 부모 공간으로 변환 쳐다보기 타겟의 위치를 가중치 합산 T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산 위쪽 방향 타겟을 T를 사용, 업 벡터를 계산 앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장 }
  • 161. 3DS MAX의 업 노드 옵션이 (쓸데없이) 다양하기 때문에 신경 쓸 것이 많다
  • 162. 앞과 위를 구했으니 옆은 외적으로 간단히 계산할 수 있을 거고, 5. 회전으로 만들면 끝? void LookAtConstraint::Process(/* 생략 */) { [월드 공간]→[부모 공간] 변환의 트랜스폼 T를 계산 자신의 위치를 T를 사용해서 부모 공간으로 변환 쳐다보기 타겟의 위치를 가중치 합산 T를 사용, 부모의 로컬 공간으로 이동시켜서 쳐다볼 방향을 계산 위쪽 방향 타겟을 T를 사용, 업 벡터를 계산 앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장 }
  • 163. 이 정도면 다 된 것 같은데 롤 아웃에 아직도 남아있는 뭔가 수상한 옵션들은? 50
  • 164. Keep Initial Offset 옵션은 쳐다보기 계산 결과와 초기의 어긋남을 보존 LookAtConstraint가 걸려 있는 본
  • 165. Keep Initial Offset 옵션을 포함하는 최종 슈도 코드 void LookAtConstraint::Preprocess() { keep initial offset이 켜진 경우, 룩 앳 컨스트레인트의 계산 결과와 바인드 포즈의 차이를 [회전 옵셋]으로 보존 } void LookAtConstraint::Process(/* 생략 */) { /* 전략 */ keep initial offset이 켜진 경우, 계산 결과에 [회전 옵셋]을 더한다 앞과 위로 트랜스폼을 구성한 뒤 쿼터니언으로 변환해서 저장 }
  • 166. 추가 노트 3DS MAX 컨트롤러의 동작과 구현 룩 앳 컨 스 트 레 인 트 | 오 리 엔 테 이 션 컨 스 트 레 인 트 리액션 컨트롤러 | 수식 컨트롤러 & 플롯 와이어 | XYZ & 리스트 시리즈 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 167. OrientationConstraint, 본이 컨스트레인트 타겟들의 회전의 평균을 취한다
  • 168. 할아버지의 회전에 따라서 온 가족이 영향을 받는 것을 알 수 있다 가족 모델로서 핵가족의 장단에 대해서 고민해봐야 하는 시점이 아닐까 <어른의 인형 놀이> 서플먼트 무비 M2 PSM, 한상원
  • 169. 룩앳보다 어떤 의미에서는 제일 간단한 컨트롤러? void OrientationConstraint::Process(/* 생략 */) { 컨스트레인트 타겟의 로컬 회전 리스트를 얻는다 가중치 합산하여 계산하고 기록한다 }|
  • 170.
  • 171. 월드 공간 오리엔테이션 블렌딩 모드가 있기 때문에 그럴 리가 없다… void OrientationConstraint::Preprocess() { keep initial offset이 켜진 경우, 오리엔테이션 컨스트레인트의 계산 결과와 바인드 포즈의 차이를 [회전 옵셋]으로 보존해둔다 } void OrientationConstraint::Process(/* 생략 */) { if (로컬 공간 보간 모드) 컨스트레인트 타겟의 로컬 회전을 기록 else // 월드 공간 보간 모드 컨스트레인트 타겟을 부모 본의 로컬 공간으로 옮겨서 기록 가중치 합산하여 회전을 계산한다 keep initial offset이 켜진 경우, 계산 결과에 [회전 옵셋]을 더한다 계산 결과를 저장 }
  • 172. 일단 귀찮지만 LookAtConstraint와 옵셋 보존 계산은 동일 void OrientationConstraint::Preprocess() { keep initial offset이 켜진 경우, 오리엔테이션 컨스트레인트의 계산 결과와 바인드 포즈의 차이를 [회전 옵셋]으로 보존해둔다 } void OrientationConstraint::Process(/* 생략 */) { if (로컬 공간 보간 모드) 컨스트레인트 타겟의 로컬 회전을 기록 else // 월드 공간 보간 모드 컨스트레인트 타겟을 부모 본의 로컬 공간으로 옮겨서 기록 가중치 합산하여 회전을 계산한다 keep initial offset이 켜진 경우, 계산 결과에 [회전 옵셋]을 더한다 계산 결과를 저장 }
  • 173. 프로그래머의 기대를 여지없이 배반해버리는 트랜스폼 규칙 void OrientationConstraint::Preprocess() { keep initial offset이 켜진 경우, 오리엔테이션 컨스트레인트의 계산 결과와 바인드 포즈의 차이를 [회전 옵셋]으로 보존해둔다 } void OrientationConstraint::Process(/* 생략 */) { if (로컬 공간 보간 모드) 컨스트레인트 타겟의 로컬 회전을 기록 else // 월드 공간 보간 모드 컨스트레인트 타겟을 부모 본의 로컬 공간으로 옮겨서 기록 가중치 합산하여 회전을 계산한다 keep initial offset이 켜진 경우, 계산 결과에 [회전 옵셋]을 더한다 계산 결과를 저장 } 60
  • 174. 계층 구조가 서로 무관한 본의 회전을 블렌딩하기 위해서 필요 ‘보이는 대로’ 블렌딩 로컬+15도 회전 (최종 30도) 자식 Local→Local인 경우 World→World로 (15 + 15) / 2 = 15도 OrientationConstraint가 World→World인 경우 부모 걸려있는 본 (15 + 30) / 2 = 22.5도, 로컬+15도 회전
  • 175. 추가 노트 3DS MAX 컨트롤러의 동작과 구현 룩 앳 컨 스 트 레 인 트 | 오 리 엔 테 이 션 컨 스 트 레 인 트 리액션 컨트롤러 | 수식 컨트롤러 & 플롯 와이어 | XYZ & 리스트 시리즈 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 176. *ReactionManager의 기본적인 개념은 입력→그래프→출력 때려주고 싶은 마음이 가슴 깊은 곳부터 샘솟아 오르는 비 직관적인 UI
  • 177. *ReactionManager 구현의 어려운 점은… 입력의 종류가 많다 Local Rotation X/Y/Z World Rotation X/Y/Z Local Position X/Y/Z World Position X/Y/Z Distance
  • 178. 핵심적인 기능은 float→그래프→출력이므로 먼저 입력을 추상화 DistanceEvaluator RotationEvaluator PositionEvaluator
  • 179. LocalPosition X/Y/Z, WorldPosition X/Y/Z를 처리하는 PositionEvaluator const float PositionEvaluator::Process(/* 생략 */) { if (로컬 공간 값을 요구) if (부모를 기준으로) return 로컬 트랜슬레이션[지정된 채널] else if (레퍼런스 본을 기준으로) 레퍼런스 본 트랜스폼 공간으로 변환 return 변환된 결과값[지정된 채널] else // 레퍼런스가 undefined == 월드 기준 return 월드 트랜슬레이션[지정된 채널] else return 월드 트랜슬레이션[지정된 채널] }
  • 180. 로컬/월드라고 하면 간단할 것 같은데 특이한 부분? const float PositionEvaluator::Process(/* 생략 */) { if (로컬 공간 값을 요구) if (부모를 기준으로) return 로컬 트랜슬레이션[지정된 채널] else if (레퍼런스 본을 기준으로) 레퍼런스 본 트랜스폼 공간으로 변환 return 변환된 결과값[지정된 채널] else // 레퍼런스가 undefined == 월드 기준 return 월드 트랜슬레이션[지정된 채널] else return 월드 트랜슬레이션[지정된 채널] }
  • 181. 프로그래머가 상상하기 어려운 동작을 요구하는 헬퍼 본 인터페이스
  • 182. LocalRotation X/Y/Z, WorldRotation X/Y/Z를 처리하는 RotationEvaluator const float RotationEvaluator::Process(/* 생략 */) { if (로컬 공간 값을 요구) if (부모를 기준으로) return 로컬 회전값[지정된 채널] else if (레퍼런스 본을 기준으로) 레퍼런스 본 트랜스폼 공간으로 변환 return 변환된 회전값[지정된 채널] else // 레퍼런스가 undefined == 월드 기준 return 월드 회전값[지정된 채널] else return 월드 회전값[지정된 채널] }
  • 183. PositionEvaluator와 동일하지만… 쿼터니언→오일러 XYZ 쿼터니언 → 매트릭스 변환 식과 매트릭스 → 오일러 XYZ 분해를 결합해서 유도 가능 70
  • 184. Distance를 처리하는 DistanceEvaluator const float DistanceEvaluator::Process(/* 생략 */) { if (레퍼런스 본이 유효) return 기준 본과 레퍼런스 본의 거리 else return 기준 본과 월드 원점의 거리 }
  • 185. 마스터 입력 이후의 float→그래프→출력 처리는 공통 키 프레임 애니메이션 재생과 동일 const ReactorResult ReactionControllerBase::Process(/* 생략 */) { 정렬된 마스터/슬레이브 리액션 리스트에서 주어진 마스터 값을 넘지 않으면서 가장 큰 마스터/슬레이브 인덱스를 찾는다 찾아낸 리액션과 다음 리액션을 보간하여 반환한다 }
  • 186. 추가 노트 3DS MAX 컨트롤러의 동작과 구현 룩 앳 컨 스 트 레 인 트 | 오 리 엔 테 이 션 컨 스 트 레 인 트 리액션 컨트롤러 | 수식 컨트롤러 & 플롯 와이어 | XYZ & 리스트 시리즈 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 187. FloatWire와 *ExpressionControl은 최후의 수단 수식 계산값을 사용
  • 188. 수식을 사용하는 것 외에는 리액션 컨트롤러와 유사한 난이도 파싱만 하면 간단 매번 인터프리터 방식으로 계산하면 성능 문제가 있으므로 AST 구축이 필요 자세한 구현은 이 강의의 범위를 벗어나므로 생략
  • 189. 수식에 사용되는 ID의 값은 리액션 컨트롤의 마스터와 거의 동일하다 구현의 재활용 가능 RotationEvaluator, PositionEvaluator를 수식 계산에 그대로 다시 사용할 수 있다
  • 190. 추가 노트 3DS MAX 컨트롤러의 동작과 구현 룩 앳 컨 스 트 레 인 트 | 오 리 엔 테 이 션 컨 스 트 레 인 트 리액션 컨트롤러 | 수식 컨트롤러 & 플롯 와이어 | XYZ & 리스트 시리즈 Ⓒ 2008-2010 NEXON Corporation & devCAT Studio. All Rights Reserved M2 team, Game Development Team for Mabinogi in devCAT (The 3rd Development Division in NEXON Corp.). M2 team Director is Kim, Dong-Gun | Project W is produced by Kim, Dong-Gun devCAT Engine team, Engine Development Team for Project W and more. Engine Team Technical Director is Jeon, Hyeong-Kyu
  • 191. PositionXYZ, EulerXYZ, ScaleXYZ은 Float 컨트롤러의 묶음
  • 192. 특별한 구현이 필요하지 않을 것 같은데? 기본값과 변환을 처리 void EulerXYZ::Process(/* 생략 */) { if (상수인가) 기본값을 보존 foreach (X/Y/Z 각 축의 컨트롤러에 대해서) 결과값[축] = float 컨트롤러를 계산 if (컨트롤러가 FloatReactionControl) 결과값[축]을 라디안으로 변환 결과값을 쿼터니언으로 변환 else 기본값을 저장 }
  • 193. PositionList, RotationList, ScaleList은 컨트롤러의 묶음 80
  • 194. 특별한 구현이 필요하지 않을 것 같은데? 순서대로 누적을 처리 void RotationList::Process(/* 생략 */) { foreach (리스트의 컨트롤러에 대해서) [현재] = 컨트롤러의 회전 계산 결과 if 컨트롤러가 *Constraint이면 [누적] = Slerp([누적], [현재], [가중치]) else [누적] = [누적] * [현재] }
  • 195. 복제 구현을 마쳤으니… 이제 계산만 하면 된다 void ReactorProcessor::Process() { foreach (모든 본에 대해서) if (컨트롤러가 있다면) 컨트롤러를 계산한다 }