티스토리 뷰

Game/MMD

Aligned (Rigidbody + Bone ) motion

newpolaris 2017. 10. 12. 19:48

Version 2.1 은 Softbody 까지 지원하네.

bullet softbody 자체가 메롱인 상태라 우선 PMD 에서도 쓰였던

rigid body 를 추가해보기로 하였다.

95% 이상의 멤버가 그대로 계승되었기에 parsing 자체는 쉬웠다.

Viewer:

Joint 가 없어서 머리랑 몇부분이 떨어 졌지만 위치는 맞다

그런데,

물리 연산 가한것도 아니고 그냥 rigidbody 에 적용만했을 뿐인데

수정하니 이제, bone을 따라가는건 잘된다.

joint가 없어서 물리에 영향받는 나머지들은 땅에 떨어진다.

물리에 영향만 받는 개체는 또한 쉽다

그냥 skinning 하고 연동만 시키면 됨

문제는 물리랑 모션이랑 같이 영향을 받는 본이다

모션은 local 을 update 하고 물리는 world 기준으로 update 한다

정해진 방법은 없고 결국 구현에 따라 마음대로다.

찾다가 찾은 유일한 링크

http://d.hatena.ne.jp/ousttrue/20100424/1272126923

PMD 에서는,

motion > physics > physics 의 bone rotation 만 반영이라고 한다

skinning matrix 즉 offset 으로 해당 내역을 구현하여

position 을 덮어 쓰도록 하니,

skinning * toRoot = Pose 로 변환하도록 했는데 아래와 같이 이상하게 나온다.

https://www.youtube.com/watch?v=t2Ocqga5efE

이 상태로 2틀 헛짓하다가 일본어로 검색하니,

분석 글을 찾았다.

http://ch.nicovideo.jp/rgb/blomaga/ar956391

MikuMikuDance의 readme.txt를 보면 

"물리"의 "본 위치 맞춤 '은'물리 '의 강체에 연결된 조인트의 위치는 뼈의 위치에서 어긋나는 경우가 있으므로 그것을 강제로 본의 위치에 맞추는 방법입니다. 
본 위치에서 관절이 어긋나는 경우 모델의 파탄이 일어나는 경우에만 사용하십시오 (사용 계산이 늦어지는 것과 움직임이 부자연스러워집니다)

와 있습니다. 과연 몰라요 상태입니다. 

일어를 아직 못 읽는게 뼈아프다.

모델을 이동하면 강체가 뼈의 위치에서 진행 방향으로 어긋나있는 것을 알 수 있습니다. 
오른쪽은 강체의 위치는 진행 방향으로 어긋나 있지만, 우유 (조인트)의 위치를 뼈의 위치에 맞추는 사양에 어긋나 있지 않습니다 (readme.txt에 따르면 뼈의 위치에서 진행 방향으로 어긋나 조인트를 본 위치에 맞게 있는데, 조인트는 표시되지 않기 때문에 보이지 않는). 

프로그램의 수는 전혀 모르기 때문에 마음대로 생각 했습니다만, "물리학 + 본 정렬"의 강체는 "조인트의 위치의 차이를 뼈의 위치에 맞추기 → 조인트의 이동을 없었던 것으로하고 본의 위치에 맞추기 "즉, 강체의 이동을 조인트에 전달되지 않도록하는 것이 아닐까 생각한 나름입니다. 
MMD는 관절의 움직임은 보이지 않기 때문에 강체의 움직임을보고 판단 할 수 밖에 없습니다. 결과적으로 까다로운 이동이 뼈에 전달되지 않도록 보이고있는 것이라고 생각합니다. 

달리 그 1 : 「물리」의 경직은 진행 방향으로 어긋나 "물리학 + 본 정렬"는 진행 방향으로 어긋나 강체의 위치를 무시하고 관절 뼈의 위치로 이동

즉, 원래 motion 기준으로 뼈를 복귀 시키는게 아니고,

joint를 설정해 distance를 0으로 둬도 결국 bone에 반영시키면 아래와 같이

뼈 사이가 겹치거나 벌어진다.

벌어질 경우 표면이 늘어난 것처럼 보이는데 이것을 제거한다는 것.

극단적으로, 위에 싸이트의 동영상 처럼 rigid body 만 떨어트려 놓으면

이 옵션은 그것을 뼈가 가능한 위치로 보정한다.

(정상 상황이라면 joint 가 +- 약간만 허용하지만)

그러면, 뼈가 가능한 위치로 pose matrix를 구성하려면 어떻게 해야하나?

결과적으로 다른 소스에서 언급한 것 처럼,

위치는 pose 껄 사용하고 rotation 만 사용하면 된다.

말은 이렇게 되는데, 길게 설명하면,

(joint 가 0인 경우)

rigid body의 offset으로 위치하는 뼈의 시작점이 실제 position과 차이가 난다면,

그것을 보정해야하는데, 그 시작점은 m_Pose에 담겨있다.

그 부모가 static rigid body 라면 m_Pose_c = m_Pose_p * m_local_Pose_c 에서 계산되었을 것이고,

그 부모가 non-static rigid body 라면 갱신된 m_Pose_p 로 다시 계산한다. (이 고정이 updateTransform )

rigid는 그 오차 만큼 보정해서 더하면 되는데,

이 과정은 그냥, origin 을 m_Pose_c 의 translate 로 바꾼후에 이건 m_Pose_c 의

새로운 값으로 설정하고,

rigid body 값은 새로운 걸로 update 하면 된다 (소스에선 빠졌다)

if (m_Type != kStaticObject && m_BoneRef.m_Instance != nullptr)
{
    btTransform centerOfMassTransform = m_Body->getCenterOfMassTransform();
    btTransform tr = centerOfMassTransform * m_InvTrans;
    if (m_Type == kAlignedObject)
    {
        m_BoneRef.UpdateTransform();
        tr.setOrigin( Convert(m_BoneRef.GetTransform().GetTranslation()) );
    }
    m_BoneRef.SetTransform( tr );
}

물리 설정 관련 해설 http://ch.nicovideo.jp/q_ku/blomaga/ar679314 http://ch.nicovideo.jp/rgb/blomaga/ar961060

'Game > MMD' 카테고리의 다른 글

Tone mapping (5)  (0) 2017.10.17
MMD 구현 중 정리  (0) 2017.10.14
Effect  (0) 2017.10.08
Tone mapping (4)  (0) 2017.10.08
Bloom (1)  (0) 2017.10.07
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크