Esempio n. 1
0
    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])