Awesome Cedric! Thanks for the help. Figured it out with a little less code this time. ;)
The next step would be figuring out how to use this technique for points on a curve. The idea is to have a curve and a start Object with a certain orientation and an end object with a Certain orientation and along the curve blend between these two orientations. Similar to the Maya Spline IK Advanced Twist. Here's my lookAt / aim script version supporting a source object, aimTarget object and upTarget object. (Supporting the up target was quite some experimenting and thinking it through for me.) Also supporting any x, y, z aim axis and up axis as long as they are orthogonal. #### import maya.cmds as mc import maya.OpenMaya as om def getDependNodeByName( name ): selList = om.MSelectionList () selList.add (name) node = om.MObject() selList.getDependNode (0, node) return node def getDagPathByName( name ): selList = om.MSelectionList () selList.add (name) node = om.MDagPath() selList.getDagPath (0, node) return node def gsOrthonormalize( normal, tangent ): # Gram-Schmidt Orthonormalization normal.normalize() proj = normal * ( tangent * normal ) # normal * dotProduct(tangent,normal) tangent = tangent - proj tangent.normalize() return normal, tangent srcNode = getDagPathByName("pSphere1") targetNode = getDagPathByName("pCube1") upNode = getDagPathByName("pCube2") fnTransform = om.MFnTransform() fnTransform.setObject(srcNode) srcTransformMatrix = fnTransform.transformation() srcPos = srcTransformMatrix.getTranslation(om.MSpace.kWorld) fnTransform.setObject(targetNode) aimTargetTransformMatrix = fnTransform.transformation() aimTargetPos = aimTargetTransformMatrix.getTranslation(om.MSpace.kWorld) fnTransform.setObject(upNode) upTargetTransformMatrix = fnTransform.transformation() upTargetPos = upTargetTransformMatrix.getTranslation(om.MSpace.kWorld) """ Step one: Aim the aimAxis """ basisAimVec = om.MVector(0,0,1) aimVec = aimTargetPos - srcPos upVec = upTargetPos - srcPos quat = basisAimVec.rotateTo(aimVec) # give the quaternion rotation so that x points to basisAimVec # Maybe if we addRotationQuaternion we can support beyond 360? (so it will aim to the closest value?) # Because the MQuaternion and MTransformMatrix classes support information beyond 360 degrees srcTransformMatrix.setRotationQuaternion( quat.x, quat.y, quat.z, quat.w, om.MSpace().kWorld ) """ Step two: Aim the upAxis (twisting around the aimAxis) """ mat = srcTransformMatrix.asMatrix() basisUpVec = om.MVector(1,0,0) basisUpVecObject = basisUpVec * mat """ # Option 1: Gram-Schmidt Orthonormalization """ tempVec,upVec = gsOrthonormalize(aimVec,upVec) """ # Option 2: Remove any distance in aimAxis from upAxis so vector becomes orthogonal to aimAxis Remove the rotation we have from the lookAt from the upVector (from upTargetPos-srcPos) Then remove any translation in the aimAxis (so we exclude changing that when calculating the quaternion) upVec = upVec * mat.inverse() upVec.x = 0 # currently requires to hard-code which axis is the aim axis, could be done otherwise though upVec = upVec * mat """ quat = basisUpVecObject.rotateTo(upVec) srcTransformMatrix.addRotationQuaternion( quat.x, quat.y, quat.z, quat.w, om.MSpace().kWorld ); # Set the adjusted matrix fnTransform.setObject(srcNode) fnTransform.set(srcTransformMatrix) mc.refresh() ### Let me know if you guys see anything that can be done easier or better. Really appreciate the help. -Roy -- view archives: http://groups.google.com/group/python_inside_maya change your subscription settings: http://groups.google.com/group/python_inside_maya/subscribe