Super Kawaii Cute Cat Kaoani [Blender] blender에서 skeleton joint orientation 구하기

연구/Blender

[Blender] blender에서 skeleton joint orientation 구하기

치킨고양이짱아 2024. 2. 16. 20:23
728x90
728x90

1) parent joint에 대해 표현된 joint orientation

obj = bpy.data.objects['원하는 오브젝트 이름']
pb = obj.pose.bones['원하는 posebone이름']

rotation_matrix = (pb.bone.matrix_local @ matrix_basis @ pb.bone.matrix_local.inv()).to_3x3()

위의 코드를 거치면 blender 상에서 joint의 orientation을 구할 수 있다.

opengl 상에서의 orientation을 구하고 싶다면,

def blender_to_opengl(mb):
    mb = np.array(mb)
    mo = np.array([
        [mb[0, 0], mb[0, 2], -1 * mb[0, 1]],
        [mb[2, 0], mb[2, 2], -1 * mb[2, 1]],
        [-1 * mb[1, 0], -1 * mb[1, 2], mb[1, 1]] 
    ])

    return Matrix(mo)

위의 함수를 사용해서

rotation_matrix = blender_to_opengl(rotation_matrix)

위의 같이 변환해주면 우리가 평소에 쓰는 축에서의 joint orientation을 구할 수 있다.

 

2) global joint orientation

obj = bpy.data.objects['원하는 오브젝트 이름']
pb = obj.pose.bones['원하는 posebone이름']

rotation_matrix = obj.matrix_world.to_3x3() @ pb.matrix.to_3x3() @ pb.bone.matrix_local.to_3x3().inverted()

마찬가지로 아까 정의해두었던 함수를 사용하여

rotation_matrix = blender_to_opengl(rotation_matrix)

위와 같이 변환해주면 우리가 평소에 사용하던 축에서의 global orientation을 구할 수 있다.

 

<참고>

위의 식들은

obj = bpy.data.objects['원하는 오브젝트 이름']
pb = obj.pose.bones['원하는 posebone이름']

일때

(pb.parent.bone.matrix_local.inv() @ pb.bone.matrix_local).inv() @ (parent.matrix.inv() @ bone.matrix) = pb.matrix_basis

가 성립한다는 사실을 사용하여 유도하였다. 각각의 의미를 좀 더 자세히 알고 싶다면 아래의 포스트를 참고하면 도움이 될 것이다.

https://chickencat-jjanga.tistory.com/174

 

[Blender] matrix, matrix_basis, matrix_local, matrix_world관계

blender에서는 다양한 종류의 matrix를 사용하고 있다. Posebone.matrix, Posebone.matrix_basis, bone.matrix_local...등 다양한 종류의 matrix가 등장하는데..각각의 의미와 이들간의 관계에 대해서 알아보자. Posebone.m

chickencat-jjanga.tistory.com

728x90
728x90