def compute(self, plug, dataBlock): dh_mirrorTranslation = dataBlock.inputValue(self.mirrorTranslation) mirrorTranslation = Axis(dh_mirrorTranslation.asShort()) inWorldMatrix = dataBlock.inputValue(self.inWorldMatrix).asMatrix() inParentInvMatrix = dataBlock.inputValue( self.inParentMatrixInv).asMatrix() dh_mirrorAxis = dataBlock.inputValue(self.mirrorAxis) axis = Axis(dh_mirrorAxis.asShort()) ### DEAL WITH ROTATION AND POSITION SEPARATELY ### R, S = inWorldMatrix.asPy( 3).decompose() #this gets just the 3x3 rotation and scale matrices x, y, z = R #extract basis vectors #mirror the rotation axes and construct the mirrored rotation matrix idxA, idxB = axis.otherAxes() x[idxA] = -x[idxA] x[idxB] = -x[idxB] y[idxA] = -y[idxA] y[idxB] = -y[idxB] z[idxA] = -z[idxA] z[idxB] = -z[idxB] #factor scale back into the matrix mirroredMatrix = Matrix(x + y + z, 3) * S mirroredMatrix = mirroredMatrix.expand(4) #now put the rotation matrix in the space of the target object dh_targetParentMatrixInv = dataBlock.inputValue( self.targetParentMatrixInv) tgtParentMatrixInv = dh_targetParentMatrixInv.asMatrix() matInv = tgtParentMatrixInv.asPy() #put the rotation in the space of the target's parent mirroredMatrix = mirroredMatrix * matInv #if there is a joint orient, make sure to compensate for it tgtJoX = dataBlock.inputValue(self.targetJointOrientX).asDouble() tgtJoY = dataBlock.inputValue(self.targetJointOrientY).asDouble() tgtJoZ = dataBlock.inputValue(self.targetJointOrientZ).asDouble() jo = Matrix.FromEulerXYZ(tgtJoX, tgtJoY, tgtJoZ) joInv = jo.inverse() joInv = joInv.expand(4) mirroredMatrix = mirroredMatrix * joInv #grab the rotation order of the target rotOrderIdx = dataBlock.inputValue(self.targetRotationOrder).asInt() #grab euler values R, S = mirroredMatrix.decompose( ) #we need to decompose again to extract euler angles... eulerXYZ = outX, outY, outZ = mayaRotationOrders[rotOrderIdx]( R) #R.ToEulerYZX() dh_outRX = dataBlock.outputValue(self.outRotateX) dh_outRY = dataBlock.outputValue(self.outRotateY) dh_outRZ = dataBlock.outputValue(self.outRotateZ) #set the rotation dh_outRX.setDouble(outX) dh_outRY.setDouble(outY) dh_outRZ.setDouble(outZ) dataBlock.setClean(plug) ### NOW DEAL WITH POSITION ### #set the position if mirrorTranslation == self.M_COPY: inLocalMatrix = inWorldMatrix * inParentInvMatrix pos = MPoint(inLocalMatrix(3, 0), inLocalMatrix(3, 1), inLocalMatrix(3, 2)) elif mirrorTranslation == self.M_INVERT: inLocalMatrix = inWorldMatrix * inParentInvMatrix pos = MPoint(-inLocalMatrix(3, 0), -inLocalMatrix(3, 1), -inLocalMatrix(3, 2)) elif mirrorTranslation == self.M_MIRROR: pos = MPoint(inWorldMatrix(3, 0), inWorldMatrix(3, 1), inWorldMatrix(3, 2)) pos = [pos.x, pos.y, pos.z] pos[axis] = -pos[axis] pos = MPoint(*pos) pos = pos * tgtParentMatrixInv else: return dh_outTX = dataBlock.outputValue(self.outTranslateX) dh_outTY = dataBlock.outputValue(self.outTranslateY) dh_outTZ = dataBlock.outputValue(self.outTranslateZ) dh_outTX.setDouble(pos[0]) dh_outTY.setDouble(pos[1]) dh_outTZ.setDouble(pos[2])