Blenderでワールドマトリクスからオブジェクトの軸方向を取得
2.79.6での検証です。2.8はまだ・・・
また、ボーンの扱いは特殊らしい?ので、未検証です。
取得対象
移動と回転をさせたキューブについて、各軸の方向を取得する方法の紹介です。
ワールドマトリクスとは
オブジェクトに親子関係がある場合、各オブジェクトのlocation, rotation, scaleへは、親との相対的な値が入っています。それに対し、親子関係を無視した(親子関係を解消した場合に相当する)状態を表すものをワールドマトリクスといいます。これを利用して、オブジェクトのXYZ軸がどの方向を向いているのかが取得できます。
ワールドマトリクスを取得するには以下のコードを実行します("Cube"の例)。
import bpy # Cubeのオブジェクトを取得 obj = bpy.data.objects["Cube"] # Cubeのワールドマトリクスを取得 matrix_world = obj.matrix_world # 取得したマトリクスを表示 print(matrix_world)
表示結果はシステムコンソールに表示されるので、確認するにはToggle System Console(システムコンソール切替)を押しておく必要があります。
マトリクスの読み方
Blenderのマトリクスは、左端の縦(一列目)がX軸の方向を表します。同様に二列目がY軸、三列目がZ軸の方向を表します。
それぞれ上から順に、原点から見た各軸のx, y, zの座標を示します。
例えばこのキューブのX軸の向きは、原点から見て
x=0.7272, y=-0.6838, z=-0.0602
の方向を向いたベクトルと並行だということになります。
なお、四列目は位置のワールド座標を表しており、
x=1.5527, y=-0.5653, z=3.1395
の場所にこのキューブがあることを示しています。
マトリクスの一番下の行は、とりあえず無視してください。
プログラム上で取得しやすくする
マトリクスは横の一行ごとに抽出することができ、 以下のコードを実行すると各列を抜き取れます。
import bpy obj = bpy.data.objects['Cube'] matrix_world = obj.matrix_world print(matrix_world) print(matrix_world[0]) # 最初の行を取得して表示 print(matrix_world[1]) # 2行目を表示 print(matrix_world[2]) # 3行目を表示 print(matrix_world[3]) # 最後の行を表示
ところが、Blenderでは各軸の情報が縦に並んでいるため、この方法では軸の情報が取得できません。
例えば二行目は、各軸の向きと位置のうち、y座標を並べたものが表示されてしまいます。
そこで以下のコードで、マトリクスの縦と横を入れ替えます
import bpy obj = bpy.data.objects['Cube'] matrix_world = obj.matrix_world print('---matrix_world---') print(matrix_world) # 縦と横を入れ替える(transpose) transposed_matrix = matrix_world.transposed() print('---transposed---') print(transposed_matrix) # 縦と横を入れ替えたマトリクスを表示
今回は軸の方向を調べるのが目的なので、四列目と四行目は不要になります。次のコードは縦横を入れ替えたマトリクスを三行三列だけにして、各行を表示させています。
import bpy obj = bpy.data.objects['Cube'] matrix_world = obj.matrix_world # 縦と横を入れ替える(transpose) transposed_matrix = matrix_world.transposed() print('---transposed---') print(transposed_matrix) # 縦と横を入れ替えたマトリクスを表示 # 3行3列に絞る(4行目、4列目を捨てる) transposed_3x3 = transposed_matrix.to_3x3() print('---transposed 3x3---') print(transposed_3x3) # 3行3列にしたマトリクスを表示 # 各行を表示 print(transposed_3x3[0]) # X軸の方向を表示 print(transposed_3x3[1]) # Y軸の方向を表示 print(transposed_3x3[2]) # Z軸の方向を表示
これで各軸の方向を取得することができました。
確認する
各軸の向きが取得できたので、その向きがあっているかを確認してみます。
下の図は、3つのEmptyを作成して名前を変え、取得した座標を各locationへ入力、それを原点のEmptyの子供にしたものです。
原点の親EmptyをCubeと同じ場所にすることで、Cubeの座標表示と各ロケータの位置が揃うことが確認できます。
あとがき
カメラの向いている方向を取得する必要があり、調べた副産物を記事にしてみました。
カメラの視線方向は取得したZ軸の方向に対して、各xyz座標値に-1を掛けた向き(=Z軸のマイナスの向き)になります。
今回の例では、"Cube"の代わりに"Camera"だったとして、取得したZ軸の向きが
x=-0.2276, y=-0.3230, z=0.9186
でしたので、カメラの視線方向は
x=0.2276, y=0.3230, z=-0.9186
となります。
Mayaでは「カメラの視線方向を取得」というそのものな命令があるのですが、Blenderでは見当たらなかったので入り用でしたらご参照ください。(ひょっとしたらあるのかも・・・)
あと、Mayaでワールドマトリクスを取得した場合、今回の「縦と横を入れ替えたマトリクス」と同等のものが取得されます。Blenderのように各軸の向きを縦並びにするケースをcolumn-major order、Mayaのように横並びにするものをrow-major orderと呼ぶそうで、アプリケーションによって違いがあるようです。
カメラの視線方向はBlenderもMayaも「マイナスZ方向」なのは変わりません。なぜマイナスなのだろう・・・