LoginSignup
2
1

More than 1 year has passed since last update.

mayaの環境を構築していく 5日目

Posted at

一番面倒なsetJointOrientの部分が出来たので、UI作りつつ他の機能もさっさか作っていきます。

  • createNode
    エッジループの中心や特定のvtx位置などにjointを作成したい

  • mirrorJoints
    maya標準のmirrorJointだと、1個ずつしかできないので面倒。
    複数に対応させたい

  • mirrorOrients
    左右jointがそろっている状態で、jointOrientを左右揃えたい。

  • mirrorPositions
    左右jointがそろっている状態で、joint位置を揃えたい

といった内容のツールを作成したい

mirrorOrients/mirrorPositions

骨半分いじった後に毎回 削除して mirrorJointsは面倒なので。
特定の点を支点として、特定の軸方向に反転させる処理をmatrixでやってみる。

位置に関しては、支点の位置と軸に対して -1 スケールすれば良いんじゃないかしら。

ひとまず 支点 = 原点という想定でやってみる

def mirrorMatrix(source,mirrorAxis):
    curMatrix = om.MMatrix(cmds.getAttr(source+".worldMatrix[0]"))

    if mirrorAxis == "x":
        mirrorScale = [-1.0,1.0,1.0]
    elif mirrorAxis == "y":
        mirrorScale = [1.0,-1.0,1.0]
    elif mirrorAxis == "z":
        mirrorScale = [1.0,1.0,-1.0]

    mirrorScaleMatrix = om.MTransformationMatrix(om.MMatrix.kIdentity).setScale(mirrorScale,om.MSpace.kWorld).asMatrix()    
    dist_matrix = curMatrix * mirrorScaleMatrix

    return dist_matrix 

dist_matrix = mirrorMatrix("locator1","x")
node = cmds.createNode("joint")
cmds.xform(node, matrix = list(dist_matrix), ws = True)

対称の位置がとれました。
これだけでも十分つかえますが、原点以外が支点となる場合もあるのでオプション追加。
支点が world または 任意のノードを指定できるようにする。

def mirrorMatrix(source,pivot,mirrorAxis):
    curMatrix = om.MMatrix(cmds.getAttr(source+".worldMatrix[0]"))

    if mirrorAxis == "x":
        mirrorScale = [-1.0,1.0,1.0]
    elif mirrorAxis == "y":
        mirrorScale = [1.0,-1.0,1.0]
    elif mirrorAxis == "z":
        mirrorScale = [1.0,1.0,-1.0]

    mirrorScaleMatrix = om.MTransformationMatrix(om.MMatrix.kIdentity).setScale(mirrorScale,om.MSpace.kWorld).asMatrix()

    if pivot == "world":
        pivotMatrix = om.MMatrix.kIdentity
    else:
        pivotMatrix = om.MMatrix(cmds.getAttr(pivot+".worldMatrix[0]"))    

    pivotMatrix_inverse = pivotMatrix.inverse()
    dist_matrix = curMatrix * pivotMatrix_inverse * mirrorScaleMatrix * pivotMatrix

    return dist_matrix

位置は取れたので回転を追加したい。
mirrorJoints のbehaviorのrotationの挙動のみを再現したい。
軸の向きが全て反転されれば良いと考えると、オブジェクト空間でscaleを全部-1 してしまえばどうだろうか

def mirrorMatrix(source,pivot,mirrorAxis):
    curMatrix = om.MMatrix(cmds.getAttr(source+".worldMatrix[0]"))

    if mirrorAxis == "x":
        mirrorScale = [-1.0,1.0,1.0]
    elif mirrorAxis == "y":
        mirrorScale = [1.0,-1.0,1.0]
    elif mirrorAxis == "z":
        mirrorScale = [1.0,1.0,-1.0]

    mirrorScaleMatrix = om.MTransformationMatrix(om.MMatrix.kIdentity).setScale(mirrorScale,om.MSpace.kWorld).asMatrix()

    if pivot == "world":
        pivotMatrix = om.MMatrix.kIdentity
    else:
        pivotMatrix = om.MMatrix(cmds.getAttr(pivot+".worldMatrix[0]"))    

    pivotMatrix_inverse = pivotMatrix.inverse()
    dist_matrix = curMatrix * pivotMatrix_inverse * mirrorScaleMatrix * pivotMatrix

    dist_matrix = om.MTransformationMatrix(dist_matrix).setScale([-1.0,-1.0,-1.0],om.MSpace.kObject).asMatrix()    

    return dist_matrix

image.png

向きはrotation込みであってそう。
スケールに -1 が入ってしまっているのでちょっと気持ち悪いので、最終的にworld空間でのスケールを1に戻す。

def mirrorMatrix(source,pivot,mirrorAxis):
    curMatrix = om.MMatrix(cmds.getAttr(source+".worldMatrix[0]"))

    if mirrorAxis == "x":
        mirrorScale = [-1.0,1.0,1.0]
    elif mirrorAxis == "y":
        mirrorScale = [1.0,-1.0,1.0]
    elif mirrorAxis == "z":
        mirrorScale = [1.0,1.0,-1.0]

    mirrorScaleMatrix = om.MTransformationMatrix(om.MMatrix.kIdentity).setScale(mirrorScale,om.MSpace.kWorld).asMatrix()

    if pivot == "world":
        pivotMatrix = om.MMatrix.kIdentity
    else:
        pivotMatrix = om.MMatrix(cmds.getAttr(pivot+".worldMatrix[0]"))    

    pivotMatrix_inverse = pivotMatrix.inverse()
    dist_matrix = curMatrix * pivotMatrix_inverse * mirrorScaleMatrix * pivotMatrix

    dist_matrix = om.MTransformationMatrix(dist_matrix).setScale([-1.0,-1.0,-1.0],om.MSpace.kObject).asMatrix()    
    dist_matrix = om.MTransformationMatrix(dist_matrix).setScale([1.0,1.0,1.0],om.MSpace.kWorld).asMatrix()    

    return dist_matrix

matrixとれたので、位置と回転に分離してみる

def getMirrorPosition(source,pivot,mirrorAxis):
    setMatrix = mirrorMatrix(source,pivot,mirrorAxis)
    mirrorPosition = om.MTransformationMatrix(setMatrix).translation(om.MSpace.kWorld)    
    return mirrorPosition

def getMirrorOrient(source,pivot,mirrorAxis):
    setMatrix = mirrorMatrix(source,pivot,mirrorAxis)
    mirrorOrient = om.MTransformationMatrix(setMatrix).rotation(False)
    return mirrorOrient 

位置の方は問題なさそう。
回転の方がおかしい。
matrixの時点では問題なかったので

om.MTransformationMatrix(setMatrix).rotation(False)

ここが何かおかしいらしい。

OpenMaya.MTransformationMatrix.rotation(asQuaternion=False)
Returns the transformation's rotation component as either an Euler rotation or a quaternion.

とのこと。
('A)助けてインターネット

OpenMaya.MTransformationMatrix.rotation(asQuaternion=False) で返ってくるのは radian なので、angleに変換が必要らしい。

def getMirrorPosition(source,pivot,mirrorAxis):
    setMatrix = mirrorMatrix(source,pivot,mirrorAxis)
    mirrorPosition = om.MTransformationMatrix(setMatrix).translation(om.MSpace.kWorld)    
    return mirrorPosition

def getMirrorOrient(source,pivot,mirrorAxis):
    setMatrix = mirrorMatrix(source,pivot,mirrorAxis)
    mirrorOrient = om.MTransformationMatrix(setMatrix).rotation(False)
    return [om.MAngle(mirrorOrient.x).asDegrees(), om.MAngle(mirrorOrient.y).asDegrees(), om.MAngle(mirrorOrient.z).asDegrees()]        

無事回転もとれた。
あとはこれらをツールに組み込んで行くのですが、長くなるので割愛。
後日 githubかなんかで公開していこうかと思います。

image.png
image.png
image.png

ちょっと回り道してしまった感がありますが、これがあるとないで後々の作業に大きく影響が出るので。
ここまでくればもうリグ環境出来たも同然なので、続きは次回

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1