def setJointRotation(sourceList, targetList, x, sParentMat, tParentMat): for i, (sourceChild, targetChild) in enumerate(zip(sourceList, targetList)): """Get keyframe rotations as k""" k = pm.getAttr(sourceChild + '.rotate', time=x) k = dt.EulerRotation(k[0], k[1], k[2]).asMatrix() """Create isolatedRotation""" isolatedRotation = sBindPoseInversed[i] * k """Change of basis to world space rotation""" sOrientation = sourceChild.getOrientation().asMatrix() sOrientationInversed = sOrientation.transpose() sParentsInversed = sParentMat[i].transpose() worldspaceRotation = sOrientationInversed * sParentsInversed * isolatedRotation * sParentMat[ i] * sOrientation """Second change of basis to the space of target""" tOrientation = targetChild.getOrientation().asMatrix() tOrientationInversed = tOrientation.transpose() tParentsInversed = tParentMat[i].transpose() translatedRotation = tOrientation * tParentMat[ i] * worldspaceRotation * tParentsInversed * tOrientationInversed tRot = pm.getAttr(targetChild + '.rotate', t=0) tRot = dt.EulerRotation(tRot[0], tRot[1], tRot[2]).asMatrix() finalRotation = tRot * translatedRotation """Get rotation values from the translated rotation matrix and set key for target""" eulRot = dt.EulerRotation(finalRotation) eulRot = dt.degrees(eulRot) pm.setAttr(targetChild + '.rotate', eulRot.x, eulRot.y, eulRot.z) """If joint is root, then also set translation""" if sourceChild.getParent() is None: sKmove = pm.getAttr(sourceChild + '.translate', time=x) pm.setAttr(targetChild + '.translate', sKmove[0], sKmove[1], sKmove[2]) pm.setKeyframe(targetChild, t=(x), edit=True)
def calcSourceParentBP(child, parentBindPose): parent = child.getParent() if parent: parentBindPose = calcSourceParentBP(parent, parentBindPose) #parentBindPose = (parent.getRotation().asMatrix() * parent.getOrientation().asMatrix()) * parentBindPose parentBindPose = (dt.EulerRotation(parent.rotate.get(t=0)).asMatrix() * dt.EulerRotation(parent.jointOrient.get( t=0)).asMatrix()) * parentBindPose return parentBindPose
def _add_rotate(cls, node, rotation): rotation = dt.EulerRotation([axis for axis in rotation]) matrix = dt.TransformationMatrix() q = rotation.asQuaternion() matrix.addRotationQuaternion(q.x, q.y, q.z, q.w, space='object') cls._add_transformation(node, matrix)
def setRotOrder(node, s="XYZ"): """Set the rotorder of the object. Arguments: node (dagNode): The object to set the rot order on. s (str): Value of the rotorder. Possible values : ("XYZ", "XZY", "YXZ", "YZX", "ZXY", "ZYX") """ a = ["XYZ", "YZX", "ZXY", "XZY", "YXZ", "ZYX"] if s not in a: mgear.log("Invalid Rotorder : " + s, mgear.siError) return False # Unless Softimage there is no event on the rotorder parameter to # automatically adapt the angle values # So let's do it manually using the EulerRotation class er = datatypes.EulerRotation([ pm.getAttr(node + ".rx"), pm.getAttr(node + ".ry"), pm.getAttr(node + ".rz") ], unit="degrees") er.reorderIt(s) node.setAttr("ro", a.index(s)) node.setAttr("rotate", er.x, er.y, er.z)
def targetTree(node, currTime, jointIndex=0, targetIndex=0): for child in node.getChildren(): if child.numChildren() > 0: jointIndex, targetIndex = targetTree(child, currTime, jointIndex, targetIndex) if myUI.targetIndex[targetIndex] > -1: if getBindPose == 0: tJointRotation.append(child.getRotation().asMatrix()) pm.setKeyframe(child) #pm.currentTime(0) parentBindPose = 1 targetParentBP = calcSourceParentBP(child, parentBindPose) pm.currentTime(currTime) translatedRotation.append( child.getOrientation().asMatrix() * targetParentBP * worldSpaceRotation[jointIndex] * targetParentBP.inverse() * child.getOrientation().asMatrix().inverse()) translatedRotation[jointIndex] = tJointRotation[ jointIndex] * translatedRotation[jointIndex] child.setRotation( dt.degrees(dt.EulerRotation(translatedRotation[jointIndex]))) jointIndex += 1 targetIndex += 1 return jointIndex, targetIndex
def sRotation(sourceNames): parentMatrix = dt.Matrix() for node in sourceNames: if (node is not sourceNames[0]): nodeRot = pm.getAttr(node + '.rotate', time=0) nodeRot = dt.EulerRotation(nodeRot[0], nodeRot[1], nodeRot[2]).asMatrix() parentMatrix *= node.getOrientation().asMatrix() * nodeRot return parentMatrix
def PerentRotAndOr(node, orient, jointsRoatations): if node.getParent(): tempPerent = node.getParent() orient.append(tempPerent.getOrientation().asMatrix()) rotation = dt.Matrix() pm.currentTime(0.0) rot = tempPerent.getRotation() rotation = dt.EulerRotation(rot).asMatrix() jointsRoatations.append(rotation) if tempPerent.getParent(): PerentRotAndOr(tempPerent, orient, jointsRoatations)
def test_control_curve_worldspace_orientation(self): """ Test if the control curve in orientated in worldspace zero. """ self.single_control.set_worldspace_orientation(True) self.single_control.build_from_operator() control_curve = self.single_control.controls[0] ws_matrix = control_curve.getMatrix(worldSpace=True) tm_matrix = dt.TransformationMatrix(ws_matrix) self.assertEqual( tm_matrix.getRotation(), dt.EulerRotation([0.0, -0.0, 0.0], unit="radians"), )
def current_distance(): # Return the distance between the IK and FK positions. This measures the error in our current pole # vector angle. # # We can use both distance and orientation to decide how close the pose is. Distance doesn't work when # the elbow is locked straight, since the pole vector will only rotate the elbow and not rotate it. if mode == 'angle': # Read the difference in orientation. r1 = pm.xform(fk_2, q=True, ws=True, ro=True) r2 = pm.xform(ik_2, q=True, ws=True, ro=True) q1 = dt.EulerRotation(*r1).asQuaternion() q2 = dt.EulerRotation(*r2).asQuaternion() angle = angle_between_quaternions(q1, q2) angle = angle / math.pi * 180.0 return angle else: # Read the difference in position. t1 = pm.xform(fk_2, q=True, ws=True, t=True) t2 = pm.xform(ik_2, q=True, ws=True, t=True) return dist(t1, t2)
def transferMatrices(tIndex, sUIJoints, tUIJoints, currentKF): tRIndex = 0 for joints in tJoints: if joints == tUIJoints[tIndex]: break tRIndex += 1 sRIndex = 0 for joints in sJoints: if joints == sUIJoints[tIndex]: break sRIndex += 1 sOrientation = sOrientations[sRIndex] sCurrentRotation = sJoints[sRIndex].getRotation().asMatrix() tOrientation = tOrientations[tRIndex] tCurrentRotation = tJoints[tRIndex].getRotation().asMatrix() SPM, TPM = getParentMatrix(sJoints[sRIndex], tJoints[tRIndex]) isolatedRotation = sRotations[sRIndex].inverse() * sCurrentRotation worldSpaceRotation = sOrientation.inverse() * SPM.inverse( ) * isolatedRotation * SPM * sOrientation translatedRotation = tOrientation * TPM * worldSpaceRotation * TPM.inverse( ) * tOrientation.inverse() translatedRotation = tRotations[tRIndex] * translatedRotation finalRotation = dt.degrees(dt.EulerRotation(translatedRotation)) tJointsFinalMatrix.append(finalRotation) pm.setKeyframe(tJoints[tRIndex], v=finalRotation[0], at='rotateX', t=(currentKF, currentKF)) pm.setKeyframe(tJoints[tRIndex], v=finalRotation[1], at='rotateY', t=(currentKF, currentKF)) pm.setKeyframe(tJoints[tRIndex], v=finalRotation[2], at='rotateZ', t=(currentKF, currentKF)) tIndex += 1 if tIndex < len(tUIJoints) and tIndex < len(sUIJoints): transferMatrices(tIndex, sUIJoints, tUIJoints, currentKF)
def WriteToFile(newFile, hirarchy, rotationsInvert, orentInvert, perentMatrixListInvers, perentMatrixList, orent, frameStart, frameEnd, nrOfframes): if (newFile[0] == None): sys.stdout.write( 'Error: A name or a path for the file was never chosen.') return exportFile = open(newFile[0], 'wb') exportFile.write(struct.pack('ii', nrOfframes, len(hirarchy))) frameList = list(range(frameStart, (frameEnd + 1))) for index, h in enumerate(hirarchy): exportFile.write(struct.pack('i', len(str(h)))) exportFile.write(str(h)) for i in frameList: fRotation = dt.Matrix() # Get Final source rotation at this keyframe: pm.currentTime(i) fRotation = h.getRotation() fRotation = dt.EulerRotation(fRotation).asMatrix() # Isolated rotation: k = rotationsInvert[index] * fRotation # World space rotation: kPrim = orentInvert[index] * perentMatrixListInvers[ index] * k * perentMatrixList[index] * orent[index] # Export every float in matrix in one chunk of data: exportFile.write( struct.pack('ffffffffffffffff', kPrim.a00, kPrim.a01, kPrim.a02, kPrim.a03, kPrim.a10, kPrim.a11, kPrim.a12, kPrim.a13, kPrim.a20, kPrim.a21, kPrim.a22, kPrim.a23, kPrim.a30, kPrim.a31, kPrim.a32, kPrim.a33)) exportFile.close() sys.stdout.write('Info: File successfully exported.')
def test_world_position(self): """ Test the world space position in translate and rotate. """ ws_matrix_test_op_1 = datatypes.TransformationMatrix( self.test_op_1.get_main_op_ws_matrix() ) test_ws_vec = datatypes.Vector( [27.820655082060398, -0.7524801847300928, -4.0237613976076] ) test_ws_rotation = datatypes.EulerRotation( [1.934698909968065, -0.16331263127797427, 1.1967119606022243], unit="radians", ) ws_matrix_test_op_1_subs = [ datatypes.TransformationMatrix(matrix) for matrix in self.test_op_1.get_sub_op_nodes_ws_matrix() ] ws_vec_test_op_1_subs = [ ts_matrix.getTranslation("world") for ts_matrix in ws_matrix_test_op_1_subs ] test_ws_vec_subs = [ datatypes.Vector( [31.42623634611877, 8.432088910758539, -2.397884932907285] ), datatypes.Vector( [35.03181761017714, 17.61665800624717, -0.7720084682069708] ), datatypes.Vector( [38.637398874235515, 26.801227101735805, 0.8538679964933436] ), ] self.assertEqual(ws_vec_test_op_1_subs, test_ws_vec_subs) self.assertEqual( ws_matrix_test_op_1.getTranslation("world"), test_ws_vec ) self.assertEqual(ws_matrix_test_op_1.getRotation(), test_ws_rotation)
def targetTree(targetTreeItem, currTime, listLength): global targetCount global newTargetList global getBindPose global tJointRotation if targetCount != 0: for items in range(listLength): if getBindPose == 0: tJointRotation.append(targetTreeItem.getRotation().asMatrix()) pm.setKeyframe(targetTreeItem) #pm.currentTime(0) parentBindPose = 1 targetParentBP = calcSourceParentBP(targetTreeItem, parentBindPose) pm.currentTime(currTime) translatedRotation.append( targetTreeItem.getOrientation().asMatrix() * targetParentBP * worldSpaceRotation[targetCount] * targetParentBP.inverse() * targetTreeItem.getOrientation().asMatrix().inverse()) translatedRotation[targetCount] = tJointRotation[ targetCount] * translatedRotation[targetCount] targetTreeItem.setRotation( dt.degrees(dt.EulerRotation(translatedRotation[targetCount]))) targetCount += 1 if listLength != targetCount: targetTree(targetList[targetCount], currTime, listLength) #Calculate the rotation for the node and set keyframe if node is still in the list checkViable = checkInList(node, aList) if checkVialbe == 1: pm.setKeyFrame() else: targetCount += 1 targetTree(targetList[targetCount], currTime, listLength)
def setRotOrder(node, s="XYZ"): a = ["XYZ", "YZX", "ZXY", "XZY", "YXZ", "ZYX"] if s not in a: mgear.log("Invalid Rotorder : " + s, mgear.siError) return False # Unless Softimage there is no event on the rotorder parameter to automatically adapt the angle values # So let's do it manually using the EulerRotation class er = dt.EulerRotation( [getAttr(node + ".rx"), getAttr(node + ".ry"), getAttr(node + ".rz")], unit="degrees") er.reorderIt(s) node.setAttr("ro", a.index(s)) node.setAttr("rotate", er.x, er.y, er.z)
def setTargetTree(node, jointIndex=0, targetIndex=0): for child in node.getChildren(): if child.numChildren() > 0: jointIndex, targetIndex = setTargetTree(child, jointIndex, targetIndex) if myUI.targetIndex[targetIndex] < len(myUI.targetTree) + 1: if myUI.targetIndex[targetIndex] > -1: child.setRotation( dt.degrees( dt.EulerRotation(translatedRotation[ myUI.targetIndex[targetIndex]]))) pm.setKeyframe(child) jointIndex += 1 else: jointIndex += 1 targetIndex += 1 return jointIndex, targetIndex
def HirarchyListCreator(hirarchy, orient, jointsRoatations, perentMatrixList, perentMatrixListInvers, orentations, orentationsInvert, rotations, rotationsInvert): sorce = pm.ls(sl=True)[0] if sorce is None: sys.stdout.write('Error: At least one joint must be selected.') return # Makes sure the joint selected is really the root joint: rootSorce = ReversedHierarchy(sorce) rootSorce = pm.ls(sl=True)[0] # Hierarchy Calculations: # Add root joint to the list first: hirarchy.append(rootSorce) # Add all roots children: Hirarchy(rootSorce, hirarchy) for s in hirarchy: tempParentMatrix = dt.Matrix() # For sorce: PerentRotAndOr(s, orient, jointsRoatations) tempParentMatrix = CalculateOriAndRot(orient, jointsRoatations) perentMatrixList.append(tempParentMatrix) perentMatrixListInvers.append(tempParentMatrix.inverse()) orient[:] = [] jointsRoatations[:] = [] for h in hirarchy: pm.currentTime(0.0) rot = h.getRotation() rotation = dt.EulerRotation(rot).asMatrix() rotations.append(rotation) rotationsInvert.append(rotation.inverse()) Orientations(hirarchy, orentations, orentationsInvert) sys.stdout.write('Info: Target skeleton hierarchy calculated.')
def CreateLayers(animLayerName, hirarchy, nrOfFrames, rotations, orent, orentInvert, perentMatrixList, perentMatrixListInvers, jointMatrixesList, animLayerList): animLayer1 = pm.animLayer(animLayerName) animLayerList.append(animLayer1) for index, h in enumerate(hirarchy): pm.select(h, replace=True) pm.animLayer(animLayerName, edit=True, addSelectedObjects=True) # Loop through Keys: for i in range(0, (nrOfFrames + 1)): # Get Final source rotation at this keyframe: pm.currentTime(i) kBiss = orent[index] * perentMatrixList[index] * jointMatrixesList[index][i] * perentMatrixListInvers[index] * orentInvert[index] # Final rotation: finalRotation = rotations[index] * kBiss #===================================================================== # Get the right format for rotations: keyRotQ = dt.EulerRotation(finalRotation) keyRotDegree = dt.degrees(keyRotQ) #===================================================================== # Set rotations at current time: h.setRotation(keyRotDegree) # Save to keyframe: pm.setKeyframe(h, time = (i,i), edit = True, animLayer = animLayerName) #Set weights to 0.0 so they dont influence other layers when baked: pm.animLayer(animLayerName, edit = True, w=0.0) sys.stdout.write('Info: Animation layers successfully created.\n')
def main(jointList, newJointList, hip, newHip): first = pm.findKeyframe(hip, which='first') last = pm.findKeyframe(hip, which='last') pm.setCurrentTime(0) parentList = [] targetParentList = [] parents(hip, dt.Matrix(), parentList, jointList) parents(newHip, dt.Matrix(), targetParentList, newJointList) i = 0 a = 0 identityMatrix = dt.Matrix() identityMatrix2 = dt.Matrix() while i < len(jointList): curr = first pm.setCurrentTime(0) pyJoint = pm.PyNode(jointList[i]) targetJoint = pm.PyNode(newJointList[i]) parentJoint = parentList[i] targetParentJoint = targetParentList[i] bindPoseInverse = pyJoint.getRotation().asMatrix().inverse() bindPose = pyJoint.getRotation().asMatrix() bindPoseTarget = targetJoint.getRotation().asMatrix() while curr <= last: curr = pm.findKeyframe(hip, time=curr, which='next') pm.setCurrentTime(curr) if i == 0: k = pyJoint.getRotation().asMatrix() * bindPoseInverse kPrim = identityMatrix.setToIdentity().inverse() * k * identityMatrix2.setToIdentity() kPrim2 = parentList[i] * kPrim * parentList[i].inverse() final = bindPoseTarget * kPrim2 targetJoint.setRotation(dt.degrees(dt.EulerRotation(final))) targetJoint.setTranslation(pyJoint.getTranslation()) pm.setKeyframe(targetJoint) else: ####################################HIP DONE########################################### bodyK = bindPoseInverse * pyJoint.getRotation().asMatrix() bodykPrim = parentList[i].inverse() * bodyK * parentList[i] bodykPrim2 = targetParentList[i] * bodykPrim * targetParentList[i].inverse() bodyFinal = bindPoseTarget * bodykPrim2 targetJoint.setRotation(dt.degrees(dt.EulerRotation(bodyFinal))) pm.setKeyframe(targetJoint) # apply key values if curr==last: i = i + 1 break
def TransferAnimation(jointCount, frameCount, sourceList, targetList): #for every joint in source- and target skeleton for jointIndex in range(jointCount): """ SOURCE - Get bindpose and orientations """ sourceJointBindPose = sourceList[jointIndex].getRotation().asMatrix() sourceJoindBindPoseInversed = sourceJointBindPose.inverse().asMatrix() sourceJointOrientation = sourceList[jointIndex].getOrientation( ).asMatrix() sourceJointOrientationInversed = sourceJointOrientation.inverse( ).asMatrix() """ SOURCE - Get parent Matricies """ sourceParentMatrix = dt.Matrix() sourceParentList = [] sourceParentList = sourceList[jointIndex].getAllParents() parLenS = len(sourceParentList) # get all parents rot + orient if parLenS > 0: for prnt in sourceParentList: rot = prnt.getRotation().asMatrix() ori = prnt.getOrientation().asMatrix() sourceParentMatrix *= ori * rot #if root joint, rot + orient = identity mat elif jointIndex is jointCount - 1: rot = dt.Matrix() ori = dt.Matrix() sourceParentMatrix *= ori * rot sourceParentMatrixInverse = sourceParentMatrix.inverse().asMatrix() """ TARGET - Get Bindpose and Orientations """ targetJointBindPose = targetList[jointIndex].getRotation().asMatrix() targetJointOrientation = targetList[jointIndex].getOrientation( ).asMatrix() targetJointOrientationInverse = targetJointOrientation.inverse( ).asMatrix() """ TARGET - Get parent matricies """ targetParentMatrix = dt.Matrix() targetParentList = [] targetParentList = targetList[jointIndex].getAllParents() parLenT = len(targetParentList) # get all parents rot + orient if parLenT > 0: for tPrnt in targetParentList: rotT = tPrnt.getRotation().asMatrix() oriT = tPrnt.getOrientation().asMatrix() targetParentMatrix *= oriT * rotT #if root joint, rot + orient = identity mat elif jointIndex is jointCount - 1: rotT = dt.Matrix() oriT = dt.Matrix() targetParentMatrix *= oriT * rotT targetParentMatrixInverse = targetParentMatrix.inverse().asMatrix() #for every frame in nrOf Frames for joint at joint index for frame in range(frameCount): """ SOURCE - Calculate K """ #if root joint if jointIndex is jointCount - 1: sourceJointFinalRot = pm.keyframe(sourceList[jointIndex], time=(frame, frame), query=True, eval=True)[7:10] else: sourceJointFinalRot = pm.keyframe(sourceList[jointIndex], time=(frame, frame), query=True, eval=True)[6:9] sourceJointFinalRotEuler = dt.EulerRotation( sourceJointFinalRot).asMatrix() isolatedRotK = sourceJoindBindPoseInversed * sourceJointFinalRotEuler kPrim = sourceJointOrientationInversed * sourceParentMatrixInverse * isolatedRotK * sourceParentMatrix * sourceJointOrientation kBis = targetJointOrientation * targetParentMatrix * kPrim * targetParentMatrixInverse * targetJointOrientationInverse finalRotation = targetJointBindPose * kBis FinEuler = dt.EulerRotation(finalRotation) FinDegrees = dt.degrees(FinEuler) """SET FINAL ROTATION . . . . . . . . . . . . . . . . . . """ pm.setKeyframe(targetList[jointIndex], time=(frame, frame), attribute='rotateX', value=FinDegrees.x) pm.setKeyframe(targetList[jointIndex], time=(frame, frame), attribute='rotateY', value=FinDegrees.y) pm.setKeyframe(targetList[jointIndex], time=(frame, frame), attribute='rotateZ', value=FinDegrees.z) del targetParentList[:] del sourceParentList[:]
def getBindPoses(sourceList, newList): for joints in sourceList: bindPose = pm.getAttr(joints + '.rotate', t=0) bindPose = dt.EulerRotation(bindPose[0], bindPose[1], bindPose[2]).asMatrix() newList.append(bindPose.transpose())
def calcFinalRotation(sourceJ, targetJ, key): #Isolate rotation from keyframe cmds.currentTime(0) sBindPose = sourceJ.getRotation().asMatrix() invrsBindPose = sBindPose.inverse() cmds.currentTime(key) #Isolated Rotation kI = invrsBindPose * sourceJ.getRotation().asMatrix() #Convert rotation to standard coordinate space sBO = sourceJ.getOrientation().asMatrix() sBO2 = sBO.inverse() #Get Parents sBPOmtx = dt.Matrix() sParent = sourceJ.getParent() if (sParent != None): cmds.currentTime(0) sBPO = getParentsBPO(sourceJ, sBPOmtx) cmds.currentTime(key) sBPO2 = sBPO.inverse() else: sBPO = dt.Matrix() sBPO2 = sBPO.inverse() #World Space Rotation kII = sBO2 * sBPO2 * kI * sBPO * sBO #Convert rotation to target joint coordinate space tBO = targetJ.getOrientation().asMatrix() tBO2 = tBO.inverse() #Get Parents tBPOmtx = dt.Matrix() #TEST tParent = targetJ.getParent() if (tParent != None): cmds.currentTime(0) tBPO = getParentsBPO(targetJ, tBPOmtx) cmds.currentTime(key) tBPO2 = tBPO.inverse() else: tBPO = dt.Matrix() tBPO2 = tBPO.inverse() #Translated Rotation kIII = tBO * tBPO * kII * tBPO2 * tBO2 #Calculate Final Rotation cmds.currentTime(0) tBindPose = targetJ.getRotation().asMatrix() finalRot = tBindPose * kIII cmds.currentTime(key) #Convert Matrix to Euler Rotation eulerRot = dt.EulerRotation(finalRot) degRot = dt.degrees(eulerRot) return degRot