Orient Joint は 100% 合わせてくれない(ま、これを100%自動にするのは無理ですね)
?マークでピボットを回転させると Rotate Axis に数値が入ってしまうし、
普通(スクリプトなし)ではどうやって出来るのかは分からないです。
少しずつ、ペアレントを切って、方向を直して、ペアレントしなおして、なんとなーく色々いじてみると出来たりするのですが効率的に最悪です。そして死ぬほどつまらない。
物量も多いから、仕方なくスクリプトを書いてみることにした。
目的は回転を0にして、方向が変わらないようにを方向値を自動に調整。
そうすると、回転で好きな方向に向かせて、自動的に仕様に合わせられます。
で、出来たのはこれです。
Maya | Rotation To Orient (and vice versa) from myara on Vimeo.
やーつまらない動画ですね。説明もないし・・・なんか、すいません。
必要性があるかは分からないですけど、自由に使って下さい。
同じ事をスクリプトなしで出来る方法があれば、是非教えてください。
DOWNLOAD
■使い方
GUIなどないです。作る予定もない。
Script フォルダに入れて、以下のコマンドでボタンを作って:
回転値0方向自動調整:
import mRotOri
mRotOri.main()
方向値0回転値自動調整:
import mRotOri
mRotOri.main(0)
---
これからはちょっとマニアックな話です。
方向が変わらないようにを方向値を自動に調整したいので、
回転値を方向値に足せばいいで。
単純に考えるとそうですが、Euler角はそのまま足すことが出来ないですね。
なので、Matrix に変換して、Matrix で足して、Eulerに戻して、Radiansから角度に戻すという流れかなと思っていましたが、OpenMaya を使えば一発で出来るとこの記事に書いてありました (英語) http://www.akeric.com/blog/?p=1067
オブジェクトの Matrix は getAttr で取得が出来ます。
しかもローカルとグローバルとインバースも。これは便利ですね。
この記事では グローバルマトリックスを使っていますが、今回はローカルの方が必要です。
このMatrix は角度値ではなく、オブジェクトの方向の角度なので、回転値を方向値に足す必要はありません。もう、このMatrix情報をDegreesに変換すれば良いだけです。それだけです。すばらしい。
流れとしては、OMのMMatrixを作って、Matrix情報をMMatrix に入れて、MTransformationMatrixに変換して、euler情報を取得という結構簡単な方法です。
単純だけど、昨日からこのツールを書いているんですね。
このMatrix情報を変換したら後は入れ替えるだけです。
回転を0にして、変換したMatrix情報を方向値として入れなおせばOK。
逆に方向値を0にして、変換した情報を回転値として入れなおすことも可能。
以上
一応コードをここに書いておく:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from maya import cmds
import maya.OpenMaya as om
import math
def getAngle(obj):
# ローカル Matrix 情報の取得
matrixList = cmds.getAttr('%s.matrix'%obj)
# 空 MMatrix を作成:
mMatrix = om.MMatrix()
# Matrix 情報を MMatrix に入れる
om.MScriptUtil.createMatrixFromList(matrixList, mMatrix)
# MMatrix を MTransformationMatrix に
mTransformMtx = om.MTransformationMatrix(mMatrix)
# MTransformationMatrix から Euler 情報を取得 (Radian)
eulerRot = mTransformMtx.eulerRotation()
# Radian から Degrees に変換
angles = [math.degrees(a) for a in (eulerRot.x, eulerRot.y, eulerRot.z)]
return angles
def fixRot(obj, rot0=True):
# 子オブジェクトを取得
children = cmds.listRelatives(obj, c=1)
# マトリックスから変換した角度を取得
newori = getAngle( str(obj) )
# 回転値を0にして、オリエント(方向)を新しい数値に変更
if rot0:
cmds.rotate(0,0,0, obj, objectSpace=True)
cmds.joint(obj, e=True, orientation=newori )
else:
cmds.rotate(newori[0],newori[1],newori[2], obj, objectSpace=True)
cmds.joint(obj, e=True, orientation=[0,0,0] )
# 子がいた場合、ループ。
# 子が居ない場合、方向を0に
if children :
for child in children:
fixRot(child, rot0)
else:
cmds.joint( obj, e=True, orientation=[0,0,0] )
def main(rot0=True):
# 選択を取得して、ループ
sel = cmds.ls(sl=1, type='joint')
for obj in sel:
fixRot(obj, rot0)
# 選択し直す
cmds.select(sel, r=True)