blender에 한달 가까이 고통받고, bvh load하는 코드까지 뜯어내면서 알아낸
"blender bvh load 관련" 알아낸 사실들을 세세하게 정리하고자 한다. 시작!
1) armature coordinate에서 rest pose에 대한 정보는 matrix_local에 담겨있다!
blender에서 각 pose.bone에 대한 회전값을 생성할때 rest pose에 대해 계산을 하기 때문에 각 bone의 rest pose에 대한 정보가 필요하다. armature coordinate에 대해서 표현된 rest pose는 다음과 같이 확인할 수 있다.
bpy.data.armature["object 이름"].bones[i].matrix_local
pose.bone.matrix에는 armature coordinate에 대해 표현된 posebone의 transformation matrix가 담겨있는데 matrix_local은 character가 rest state일때의 pose.bone.matrix 값이라고 생각하면 된다.
2) bone local coordinate에서 rotation matrix 정보는 matrix_basis에 담겨있다!
(즉 Rest pose에 대해 표현된 bone의 상태)
bone local coordinate에서 rotation 정보는 pose.bone.matrix_basis에 담겨있다. bone local coordinate는 parent joint coordinate라고 생각하면 된다.
하지만 단순하게 bvh file에 적힌 Motion data 값으로 euler 객체를 생성하고 이를 matrix 로 변환한 값이랑은 차이가 있다. 이는 matrix_basis가 어떻게 생성되는지 알면 조금 더 이해가 될 것이다.
matrix_basis = (boneNode coordinate 상에서 rest pose).inv @ (Motion data 값으로 만들어낸 matrix 값) @ (boneNode coordinate 상에서 rest pose)
bone local coordinate 상에서 rest pose matrix의 경우, matrix_local과 같은 경우도 있고 다른 경우도 있다. io_bvh/import_bvh 코드에서 출력해서 확인해보는 것이 가장 정확하다.
나의 경우 io_bvh 코드에서 bvh_node_dict2armature 함수의 마지막 부분에
로 세팅했을 때는 rest pose matrix가 bone의 matrix_local값과 동일했고, 위의 함수 옵션에서 rotation을 True로 줬을 때는 축변환이 일어나면서 matrix_local값과 rest pose matrix값이 달라졌다. 나는 그냥 생각하기 귀찮아서.. rotation옵션을 False로 고정해놓았다..ㅋㅋ
부가적으로 정보를 조금 더 덧붙이자면,
matrix_basis는 boneNode coordinate에 대해 표현된 pose의 transformation matrix이고, root를 제외한 bodyNode의 경우에는 아무리 character가 움직이더라도 parent joint의 위치가 bodyNode coordinate의 원점에 위치하므로 matrix_basis[:3, 3] = [0., 0., 0.]으로 세팅되어있다. 반면에 root bodyNode의 경우에는 armature coordinate에 대해 표현되므로 matrix_basis[:3, :3]의 값은 armature coordinate의 원점으로부터 얼마나 이동하였는지에 대한 값으로 세팅된다.
그냥 하던대로 bvh 파일을 parsing하여 joint의 (parent_local_transformation matrix)을 구성하고
root bodyNode의 경우 matrix_local 값을 가져와 (matrix_local.T) @ (parent_local_transformation matrix) @ (matrix_local) 값을 matrix_basis에 세팅해주고
root bodyNode가 아닌 경우에는
M = <Matrix 4x4 (-0.0000, 1.0000, 0.0000, 0.0000)
(-1.0000, -0.0000, 0.0000, 0.0000)
( 0.0000, 0.0000, 1.0000, 0.0000)
( 0.0000, 0.0000, 0.0000, 1.0000)>
M.T @ (parent_local_transformation_matrix) @ M을 matrix_basis에 세팅해주어 쓰면 될듯하다.
진짜 너무 고생하면서 찾은 정보들인데, 정리해보니 별로 없어 보여서 쫌 그렇지만..
누군가에게 도움이 되길!
Reference)
'연구 > Blender' 카테고리의 다른 글
[Blender] viewport에서 시점 변경 python script로 구현하기 (0) | 2024.01.18 |
---|---|
[Blender] Python script로 음악 재생 및 현재 재생 시점 알아내기 (0) | 2023.10.04 |
blender에서 keyframe들 scaling 시키기 (Timeline 창, 코드 이용) (0) | 2023.07.18 |
Blender bvh load 관련 알아낸 사실 정리 (0) | 2023.03.20 |
Blender에서 python api 사용하기(operator_simple.py 분석) (1) | 2023.03.17 |