Scripting an orientConstraint with offset

263 views
Skip to first unread message

Jakob Welner

unread,
Mar 22, 2011, 3:30:46 PM3/22/11
to python_inside_maya
this is more of a general Maya scripting question than python specific but I thought I'd hear you out anyway.

I'm doing an IK-FK matching tool with the IK and FK controllers having different orientation, rotation space and rotation order.. all that stuff...and now I need to match them up so they are oriented the same in worldspace.

Initially I've been doing it with an orientConstraint where I apply a certain offset value to match up the two controllers, read the rotation, delete the constraint and apply the rotation values.
This however is not always working as the constraint will fail if you have other connections messing around with your rotations (in this case usually another constraint with the weighting set to 0)

For that reason I want to do the orientation matching without use of constraints and my immediate though was a simply xform rotation query in worldspace on my master ctrl and apply that rotation + the offset to my target ctrl in worldspace as well but it's not working.
I get offsets that vary depending on initial rotation and I can't find my way around in why that should happen.. It's very likely some rotationOrder that messing with me but I haven't been able to solve it yet.

Does anyone have a method for matching rotations like that either by faking the math of an orientConstraint or by taking a completely different route?

Cheers and thanks in advance.


JAKOB WELNER
    _____________
    Animator | R&D
    jakob.welner.dk

Christopher Crouzet

unread,
Mar 22, 2011, 4:55:33 PM3/22/11
to python_in...@googlegroups.com
Hey Jakob! :)


if I correctly understood your problem, I think it's just a matter of retrieving your rotation offset as a matrix and multiply that matrix by the world matrix of the target object (the order of that multiplication matters). You'll then need to retrieve the rotation component of that computed matrix and apply it to your object.

I wrote an example code using the API, if you select your target object then source object, it should do the job whatever their object space or rotation orders are.
Also I put in the first line the euler rotation offset so you can see how it goes with different settings.


## Start of Python code.
#

rotOffset = OpenMaya.MVector( 90.0, 0.0, -90.0 ) * math.pi / 180.0



import math
from maya import OpenMaya


# Retrieve the current selection.
selList = OpenMaya.MSelectionList()
OpenMaya.MGlobal.getActiveSelectionList( selList )


# Convert it as MFnTransform nodes. First item is the target, second is the source.
dag_nodes = []
it_selList = OpenMaya.MItSelectionList( selList, OpenMaya.MFn.kTransform )
while not it_selList.isDone():
   
    dagPath = OpenMaya.MDagPath()
    it_selList.getDagPath( dagPath )
   
    dag_nodes.append( OpenMaya.MFnTransform( dagPath ) )
   
    it_selList.next()


# Create the offset rotation matrix.
m_rotOffset = OpenMaya.MEulerRotation( rotOffset, OpenMaya.MEulerRotation.kXYZ ).asMatrix()

# Retrieve the world matrix of the target node.
m_worldTarget = dag_nodes[0].dagPath().inclusiveMatrix()

# Compute the final world matrix.
m_worldFinal = m_rotOffset * m_worldTarget

# Convert it in the local space of the source object.
m_localFinal = m_worldFinal * dag_nodes[1].dagPath().exclusiveMatrixInverse()


# Apply the rotation component to the source object.
dag_nodes[1].setRotation( OpenMaya.MTransformationMatrix( m_localFinal ).rotation() )

#
##


Cheers,
Christopher.



Reply all
Reply to author
Forward
0 new messages