Exemple #1
0
def mirrorMatrix(matrix, axis=AX_X, orientAxis=AX_X):
    '''
	axis is the axis things are flipped across
	orientAxis is the axis that gets flipped when mirroring orientations
	'''
    assert isinstance(matrix, Matrix)
    mirroredMatrix = Matrix(matrix)

    #make sure we've been given a Axis instances...  don't bother testing, just do it, and make it absolute (non-negative - mirroring in -x is the same as mirroring in x)
    mirrorAxis = abs(Axis(axis))
    axisA = abs(Axis(orientAxis))

    #flip all axes
    axisB, axisC = axisA.otherAxes()
    mirroredMatrix[axisB][mirrorAxis] = -matrix[axisB][mirrorAxis]
    mirroredMatrix[axisC][mirrorAxis] = -matrix[axisC][mirrorAxis]

    #the above flipped all axes - but this results in a changing of coordinate system handed-ness, so flip one of the axes back
    nonMirrorAxisA, nonMirrorAxisB = mirrorAxis.otherAxes()
    mirroredMatrix[axisA][
        nonMirrorAxisA] = -mirroredMatrix[axisA][nonMirrorAxisA]
    mirroredMatrix[axisA][
        nonMirrorAxisB] = -mirroredMatrix[axisA][nonMirrorAxisB]

    #if the input matrix was a 4x4 then mirror translation
    if matrix.size == 4:
        mirroredMatrix[3][mirrorAxis] = -matrix[3][mirrorAxis]

    return mirroredMatrix
Exemple #2
0
    def setup(self, axis=None):
        '''
		sets up the initial state of the pair node
		'''

        if axis:
            axis = abs(Axis(axis))
            setAttr('%s.axis' % self.node, axis)

        #if we have two controls try to auto determine the orientAxis and the flipAxes
        if self.controlA and self.controlB:
            worldMatrixA = getWorldRotMatrix(self.controlA)
            worldMatrixB = getWorldRotMatrix(self.controlB)

            #so restPoseB = restPoseA * offsetMatrix
            #restPoseAInv * restPoseB = restPoseAInv * restPoseA * offsetMatrix
            #restPoseAInv * restPoseB = I * offsetMatrix
            #thus offsetMatrix = restPoseAInv * restPoseB
            offsetMatrix = worldMatrixA.inverse() * worldMatrixB

            AXES = AX_X.asVector(), AX_Y.asVector(), AX_Z.asVector()
            flippedAxes = []
            for n in range(3):
                axisNVector = Vector(offsetMatrix[n][:3])

                #if the axes are close to being opposite, then consider it a flipped axis...
                if axisNVector.dot(AXES[n]) < -0.8:
                    flippedAxes.append(n)

            for n, flipAxes in enumerate(self.FLIP_AXES):
                if tuple(flippedAxes) == flipAxes:
                    setAttr('%s.flipAxes' % self.node, n)
                    break

        #this is a bit of a hack - and not always true, but generally singular controls built by skeleton builder will work with this value
        elif self.controlA:
            setAttr('%s.flipAxes' % self.node, 0)
            self.setWorldSpace(False)
Exemple #3
0
    def doIt(self, mArgs):
        ret, argData = self.grabArgDb(mArgs)
        if ret:
            return

        sel = OpenMaya.MSelectionList()
        argData.getObjects(sel)

        objs = []
        for n in range(sel.length()):
            obj = MObject()
            sel.getDependNode(n, obj)
            objs.append(obj)

        #
        if argData.isQuery():
            rotNode = objs[0]

            if argData.isFlagSet(self.kFlagAxis):
                self.setResult(cmd.getAttr('%s.mirrorAxis' % rotNode))

            elif argData.isFlagSet(self.kFlagMode):
                self.setResult(cmd.getAttr('%s.mirrorTranslation' % rotNode))

            return

        #if we're in edit mode, find the node
        elif argData.isEdit():
            rotNode = objs[0]

        #otherwise we're in creation mode - so build the node and connect things up
        else:
            obj, tgt = objs

            #is dummy mode set?
            isDummyMode = argData.isFlagSet(
                self.kFlagDummy) or argData.isFlagSet(self.kFlagDummy)

            #see if there is already a node connected
            existing = cmd.listConnections('%s.t' % tgt,
                                           '%s.r' % tgt,
                                           type=MirrorNode.NODE_TYPE_NAME)
            if existing:
                self.displayWarning(
                    "There is a %s node already connected - use edit mode!" %
                    MirrorNode.NODE_TYPE_NAME)
                self.setResult(existing[0])

                return
            else:
                rotNode = cmd.createNode('rotationMirror')
                cmd.connectAttr('%s.worldMatrix' % obj,
                                '%s.inWorldMatrix' % rotNode)
                cmd.connectAttr('%s.parentInverseMatrix' % obj,
                                '%s.inParentInverseMatrix' % rotNode)

                cmd.connectAttr('%s.parentInverseMatrix' % tgt,
                                '%s.targetParentInverseMatrix' % rotNode)

                joAttrpath = '%s.jo' % tgt
                if cmd.objExists(joAttrpath):
                    cmd.connectAttr(joAttrpath,
                                    '%s.targetJointOrient' % rotNode)

                cmd.connectAttr('%s.rotateOrder' % tgt,
                                '%s.targetRotationOrder' % rotNode)

                if not isDummyMode:
                    cmd.connectAttr('%s.outTranslate' % rotNode, '%s.t' % tgt)
                    cmd.connectAttr('%s.outRotate' % rotNode, '%s.r' % tgt)

                cmd.select(obj)

        #set the result to the node created...
        self.setResult(rotNode)

        #set any attributes passed in from the command-line
        if argData.isFlagSet(self.kFlagAxis):
            axisInt = Axis.FromName(
                argData.flagArgumentString(self.kFlagAxis, 0))
            cmd.setAttr('%s.mirrorAxis' % rotNode, axisInt)

        if argData.isFlagSet(self.kFlagMode):
            modeStr = argData.flagArgumentString(self.kFlagMode, 0)
            modeIdx = list(MirrorNode.MIRROR_MODE_NAMES).index(modeStr)
            cmd.setAttr('%s.mirrorTranslation' % rotNode, modeIdx)
Exemple #4
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])
Exemple #5
0
 def getAxis(self):
     return Axis(getAttr('%s.axis' % self.node))
Exemple #6
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] )