myara CG blog

CG Design Blog. Thoughts, experiments and experiences.

Maya | 回転値を方向値に変更

回転値を0にして、方向値(Orient) だけでジョイントの向きを設定しないといけない作業がありました。そして、Y軸は外側に向かせないといけない条件。

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)

Comments

勘違いでしたらすみません
RotateだけFreezeするんではダメですか?
一応LocalRotationAxisの見た目を損なわずJointOrientにのみ数値が入りますが

  • 2017/08/10(木) 16:33:53 |
  • URL |
  • DC #lGNLab/U
  • [ Edit ]

Re: No title

> 勘違いでしたらすみません
> RotateだけFreezeするんではダメですか?
> 一応LocalRotationAxisの見た目を損なわずJointOrientにのみ数値が入りますが

記事を書いた時に少し混乱してしまったようが、その通りです。
回転値を0にして、ジョイントオリエントだけにしたい場合はこれでいけます。

しかし、ジョイントオリエントを0にして、回転値のみにしたい場合はうまく行かないですね。
ジョイントオリエントをフリーズするだけではオリエント値が0になり、回転値がそのままになってしまい、ジョイントの方向が変わってしまいます。

実はあの時に2つのプロジェクトが走っていて、一つはオリエントだけにしないといけない。
でもう一つはオリエント0で回転値のみにしないといけない。

  • 2017/08/10(木) 17:05:22 |
  • URL |
  • myara #-
  • [ Edit ]

なるほど、そういうことでしたか。
私もJointOrientを使えない仕様のときにはスクリプトを作りました
スクリプトと言ってもRotateをフリーズして値をOrientにコピーするだけでしたが……
記事参考にさせていただきます

  • 2017/08/16(水) 19:58:05 |
  • URL |
  • DC #lGNLab/U
  • [ Edit ]

Comment is pending approval.

Comment is pending administrator's approval.

  • 2017/08/16(水) 19:58:25 |
  • |
  • #
  • [ Edit ]

Post a comment


Only the blog author may view the comment.

Trackbacks

Trackbacks URL
http://myara.blog.fc2.com/tb.php/209-09708f9e
Use trackback on this entry.