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 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 add2DChain(parent, name, positions, normal, negate=False): if not "%s" in name: name += "%s" transforms = tra.getChainTransform(positions, normal, negate=False) t = tra.setMatrixPosition(transforms[-1], positions[-1]) transforms.append(t) chain = [] for i, t in enumerate(transforms): node = addJoint(parent, name%i, t) chain.append(node) parent = node # moving rotation value to joint orient for i, jnt in enumerate(chain): if i == 0: jnt.setAttr("jointOrient", jnt.getAttr("rotate")) elif i == len(chain)-1: jnt.setAttr("jointOrient", 0, 0, 0) else: # This will fail if chain is not always oriented the same way (like Z chain) v0 = positions[i] - positions[i-1] v1 = positions[i+1] - positions[i] jnt.setAttr("jointOrient", 0, 0, dt.degrees(v0.angle(v1))) jnt.setAttr("rotate", 0, 0, 0) return chain
def add2DChain2(parent, name, positions, normal, negate=False, vis=True): """ Experimental 2D Chain creation function. Create a 2D joint chain. Like Softimage 2D chain. Warning: This function is WIP and not ready for production. Warning: This function will create un expected results if all the positions are not in the same 2D plane. Args: parent (dagNode): The parent for the chain. name (str): The node name. positions(list of vectors): the positons to define the chain. normal (vector): The normal vector to define the direction of the chain. negate (bool): If True will negate the direction of the chain Returns; list of dagNodes: The list containg all the joints of the chain >>> self.chain3bones = pri.add2DChain2(self.setup, self.getName("chain3bones%s_jnt"), self.guide.apos[0:4], self.normal, False) """ if "%s" not in name: name += "%s" transforms = tra.getChainTransform(positions, normal, negate) t = tra.setMatrixPosition(transforms[-1], positions[-1]) transforms.append(t) chain = [] for i, t in enumerate(transforms): node = addJoint(parent, name % i, t, vis) chain.append(node) parent = node # moving rotation value to joint orient for i, jnt in enumerate(chain): if i == 0: jnt.setAttr("jointOrient", jnt.getAttr("rotate")) elif i == len(chain) - 1: jnt.setAttr("jointOrient", 0, 0, 0) else: # This will fail if chain is not always oriented the same way (like Z chain) v0 = positions[i] - positions[i - 1] v1 = positions[i + 1] - positions[i] angle = dt.degrees(v0.angle(v1)) jnt.setAttr("jointOrient", 0, 0, angle) jnt.setAttr("rotate", 0, 0, 0) jnt.setAttr("radius", 1.5) return chain
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 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 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 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 polar(x, y): """ returns r, theta(degrees) """ r = (x ** 2 + y ** 2) ** 0.5 theta = dt.degrees(dt.atan(float(y) / x)) return r, theta
def add2DChain(parent, name, positions, normal, negate=False, vis=True): """ Create a 2D joint chain. Like Softimage 2D chain. Warning: This function will create un expected results if all the positions are not in the same 2D plane. Args: parent (dagNode): The parent for the chain. name (str): The node name. positions(list of vectors): the positons to define the chain. normal (vector): The normal vector to define the direction of the chain. negate (bool): If True will negate the direction of the chain Returns; list of dagNodes: The list containg all the joints of the chain >>> self.rollRef = pri.add2DChain(self.root, self.getName("rollChain"), self.guide.apos[:2], self.normal, self.negate) """ if "%s" not in name: name += "%s" transforms = tra.getChainTransform(positions, normal, negate) t = tra.setMatrixPosition(transforms[-1], positions[-1]) transforms.append(t) chain = [] for i, t in enumerate(transforms): node = addJoint(parent, name % i, t, vis) chain.append(node) parent = node # moving rotation value to joint orient for i, jnt in enumerate(chain): if i == 0: jnt.setAttr("jointOrient", jnt.getAttr("rotate")) jnt.setAttr("rotate", 0, 0, 0) elif i == len(chain) - 1: jnt.setAttr("jointOrient", 0, 0, 0) jnt.setAttr("rotate", 0, 0, 0) else: # This will fail if chain is not always oriented the same way (like X chain) v0 = positions[i] - positions[i - 1] v1 = positions[i + 1] - positions[i] angle = dt.degrees(v0.angle(v1)) jnt.setAttr("rotate", 0, 0, 0) jnt.setAttr("jointOrient", 0, 0, angle) # check if we have to negate Z angle by comparing the guide position and the resulting position. if i >= 1: # round the position values to 6 decimals precission # TODO: test with less precision and new check after apply Ik solver if [round(elem, 4) for elem in tra.getTranslation(jnt) ] != [round(elem, 4) for elem in positions[i]]: jp = jnt.getParent() # Aviod intermediate e.g. `transform3` groups that can appear # between joints due to basic moving around. while jp.type() == "transform": jp = jp.getParent() jp.setAttr("jointOrient", 0, 0, jp.attr("jointOrient").get()[2] * -1) jnt.setAttr("radius", 1.5) return chain
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
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 addJnt(obj=False, parent=False, noReplace=False, grp=None, jntName=None, *args): """Create one joint for each selected object. Args: obj (bool or dagNode, optional): The object to drive the new joint. If False will use the current selection. parent (bool or dagNode, optional): The parent for the joint. If False will try to parent to jnt_org. If jnt_org doesn't exist will parent the joint under the obj noReplace (bool, optional): If True will add the extension "_jnt" to the new joint name grp (pyNode or None, optional): The set to add the new joint. If none will use "rig_deformers_grp" *args: Maya's dummy Returns: pyNode: The New created joint. """ if not obj: oSel = pm.selected() else: oSel = [obj] for obj in oSel: if not parent: try: oParent = pm.PyNode("jnt_org") except TypeError: oParent = obj else: oParent = parent if not jntName: if noReplace: jntName = "_".join(obj.name().split("_")) + "_jnt" else: jntName = "_".join(obj.name().split("_")[:-1]) + "_jnt" jnt = primitive.addJoint(oParent, jntName, transform.getTransform(obj)) if grp: grp.add(jnt) else: try: defSet = pm.PyNode("rig_deformers_grp") pm.sets(defSet, add=jnt) except TypeError: pm.sets(n="rig_deformers_grp") defSet = pm.PyNode("rig_deformers_grp") pm.sets(defSet, add=jnt) jnt.setAttr("segmentScaleCompensate", False) jnt.setAttr("jointOrient", 0, 0, 0) try: cns_m = applyop.gear_matrix_cns(obj, jnt) # setting the joint orient compensation in order to have clean # rotation channels m = cns_m.drivenRestMatrix.get() tm = datatypes.TransformationMatrix(m) r = datatypes.degrees(tm.getRotation()) jnt.attr("jointOrientX").set(r[0]) jnt.attr("jointOrientY").set(r[1]) jnt.attr("jointOrientZ").set(r[2]) except RuntimeError: for axis in ["tx", "ty", "tz", "rx", "ry", "rz"]: jnt.attr(axis).set(0.0) return jnt
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