Sunday, February 9, 2020

Dynamic Bone


DynamicBone

초기 설정
루트로 설정한 게임 오브젝트의 자식들을 모두 순회하면서 파티클들을 등록한다. 여기서 사용하는 파티클이라는 용어는 물리를 적용할 요소를 뜻한다.

현재 게임 오브젝트의 월드 위치를 저장하고 부모에 상대적인 localPosition, localRotation을 저장하고 있다. 이것들은 모두 m_InitLocalPosition, m_InitLocalRotation에 저장된다. 이 초기 위치와 회전들은 이후에 파티클들을 리셋 될 때 재사용된다. (물리 LOD가 적용되거나 특정 파라미터 값들이 수정되었을 때 리셋된다.)

물리 LOD
물리 시뮬레이션을 적용할 오브젝트가 지정된 오브젝트로부터 너무 멀리 떨어져 있으면 물리 시뮬레이션을 생략한다. 물리 LOD와 같은 개념이다.

UpdateDynamicBones(float t)
이 함수에서는 주어진 시간 t동안 얼만큼 물리 시뮬레이션 돌려야 하는지 결정하고, 결정된 횟수만큼 물리 시뮬레이션을 돌린다. 이때 m_UpdateRate가 사용되는데 기본적으로 60으로 되어 있다. 1 / 60값으로 t를 나누어 얼만큼 물리 시뮬레이션 돌려야 하는지 결정하는데 이 횟수를 최대 3회로 제한한다.

횟수가 결정되고 나면 UpdateParticles1(), UpdateParticles2()를 호출함으로써 물리 시뮬레이션 한다.

Verlet 적분
속도를 사용하지 않고 가속도와 이전 위치 만으로 다음 위치 값을 얻어낼 수 있는 방법.
xi+2=2xi+1xi+aiΔt2

식에서 알 수 있듯이 현재 위치를 i+1이라고 하면 이전 위치 xi와 가속도 ai만으로 i+1의 다음 위치 i+2의 위치를 알 수 있다. DynamicBone은 이 방법을 사용해 물리 시뮬레이션 한다.

UpdateParticles1()
중력을 적용하고 (그런데 반대로 한다.) m_Force를 적용한다. (바람과 같은 힘을 적용하고 싶을 때 사용) 내부적으로 물리 시뮬레이션은 Verlet Integration을 사용한다. 모든 파티클들에 동일한 이동(루트 오브젝트의 이동)을 적용한다.

UpdateParticles2()
이 함수에서는 여러가지 작업을 차례차례 처리한다. 가장 먼저 기본 모양을 유지하는 코드가 있다. (keep shape 부분)

모양 유지
파티클의 초기 위치(로컬 좌표계에서의 위치)로부터 월드 공간에서의 위치를 얻고 restPos에 담는다. 그리고 restPos – p.m_Position을 통해 현재 파티클에서 초기 위치로의 방향을 얻는다. 이 벡터를 현재 파티클에서 m_Elasticity 비율값을 사용해 원래 위치로 돌아가는 처리를 진행한다.

한 가지 특별한 사항은 월드 공간에서의 위치를 얻기 위해 사용하는 행렬 m0을 사용할 때 위치 값을 아래와 같은 코드로 사용한다는 점이다.

m0.SetColumn(3, p0.m_Position); // m_Position UpdateParticle1에서 업데이트 된 후의 월드 공간 위치

이것은 p0.m_Position 이며 UpdateParticle1 함수에서 업데이트 되고 난 후의 위치다. 현재 게임 오브젝트의 변환에는 아직 이동이 적용되지 않았으므로 이동을 업데이트하기 위해 SetColumn 함수를 사용해 이동을 업데이트 한다. 그 이후에 이 행렬을 사용해 자식 게임 오브젝트의 로컬 위치를 월드 공간으로 변환하여 restPos(되돌아갈 위치)를 얻는다.

충돌 처리
파티클의 이동에 있어 다른 오브젝트와 충돌 처리를 할 필요가 있다. DynamicBoneColliderBaseCollide 함수를 사용해 파티클 위치를 조정한다.

각 고정
물리 시뮬레이션은 특정 축에서만의 움직임으로 강제할 수 있다. 특별히 관심 있는 부분은 아니므로 생략.

거리 유지
Vector3 dd = p0.m_Position - p.m_Position;
float leng = dd.magnitude;
if (leng > 0)
p.m_Position += dd * ((leng - restLen) / leng);

파티클을 변환에 적용하기
파티클 업데이트에서 변경된 위치로 게임 오브젝트들의 위치를 업데이트 한다. 이때 사용되는 회전은 부모에서 자식의 방향으로 회전한다.


No comments:

Post a Comment

Task in UnrealEngine

 https://www.youtube.com/watch?v=1lBadANnJaw