Mirroring a Pose



  • Hello,
    I'm trying to mirror a Character Object pose on the XY plane. In this example scene, I would like to assign the rotation of each shoulder to the other. The script in effect would look like this: Mirror.gif

    I have read the API documentation on Matrix Fundamentals. Here's what I've tried so far:

    • Setting the matrices of each shoulder with the other shoulder multiplied in X by -1. The rotations were incorrect because (I think) the shoulders' Z axes are different.
    import c4d
    
    def main(doc):
        doc.StartUndo()
        lShoulder = doc.SearchObject("L_FK_Shoulder_con+")
        rShoulder = doc.SearchObject("R_FK_Shoulder_con+")
    
        rMat = rShoulder.GetMg()
        lMat = lShoulder.GetMg()
    
        rMat.v1 = c4d.Vector(lMat.v1[0]*-1,lMat.v1[1],lMat.v1[2])
        rMat.v2 = c4d.Vector(lMat.v2[0]*-1,lMat.v2[1],lMat.v2[2])
        rMat.v3 = c4d.Vector(lMat.v3[0]*-1,lMat.v3[1],lMat.v3[2])
        rMat.off = c4d.Vector(lMat.off[0]*-1,lMat.off[1],lMat.off[2])
    
        lMat.v1 = c4d.Vector(rMat.v1[0]*-1,rMat.v1[1],rMat.v1[2])
        lMat.v2 = c4d.Vector(rMat.v2[0]*-1,rMat.v2[1],rMat.v2[2])
        lMat.v3 = c4d.Vector(rMat.v3[0]*-1,rMat.v3[1],rMat.v3[2])
        lMat.off = c4d.Vector(rMat.off[0]*-1,rMat.off[1],rMat.off[2])
    
        doc.AddUndo(c4d.UNDOTYPE_CHANGE, lShoulder)
        lShoulder.SetMg(rMat)
        doc.AddUndo(c4d.UNDOTYPE_CHANGE, rShoulder)
        rShoulder.SetMg(lMat)
    
        c4d.EventAdd()
        doc.EndUndo()
    
    if __name__=='__main__':
        main(doc)
    
    • I found Matrix.invert(), but that seems to be inverting every item in the Matrix.
    • I tried the code in this example from the forum, but it mirrors all axes and keeps adding rotation to the original matrix (ending up with rotations of thousands of degrees).
      Mirror a matrix over a defined plane.

    Can anyone help me to understand how to mirror on XY with two objects please?

    Thank you!!



  • Hi,

    first of all: I assume you actually mean a reflection on the YZ plane, since the symmetry in your example is along the X axis. A reflection on the XY plane would mean reflecting along the Z axis. Also that linked thread included quite some guess work for me, so that script does something different.

    Your approach is correct, here is a version I would consider slightly more readable.

    def reflect_object_on_yz_plane(op):
        """
        """
        # Get the global matrix of our object.
        mg = op.GetMg()
        # Get the offset (position) of the global matrix with a reflected x
        # component.
        off = c4d.Vector(-mg.off.x, mg.off.y, mg.off.z)
        # Construct the x column vector (c4d defines the axis in column vectors in
        # its transform matrices) by copying and mirroring the x column vector of
        # the object's global matrix on its x axis.
        v1 = c4d.Vector(-mg.v1.x, mg.v1.y, mg.v1.z)
        # The same for the y column
        v2 = c4d.Vector(-mg.v2.x, mg.v2.y, mg.v2.z)
        # The same for y column
        v3 = c4d.Vector(-mg.v3.x, mg.v3.y, mg.v3.z)
        # The new matrix.
        mg = c4d.Matrix(off, v1, v2, v3)
        # Set the global matrix of our object.
        op.SetMg(mg)
    

    I am not sure what you mean by incorrect z axis, but note that coordinate systems and therefor its matrices are either left handed or right handed (Cinema is left handed), which dictates the relation of the positive quadrants of the coordinate system. So I assume, what you mean by incorrect z axis, is a change of orientation of the z-axis gizmo in the editor, but that is actually normal.

    Cheers
    zipit



  • Hi,

    first of all: I assume you actually mean a reflection on the YZ plane, since the symmetry in your example is along the X axis. A reflection on the XY plane would mean reflecting along the Z axis. Also that linked thread included quite some guess work for me, so that script does something different.

    Your approach is correct, here is a version I would consider slightly more readable.

    def reflect_object_on_yz_plane(op):
        """
        """
        # Get the global matrix of our object.
        mg = op.GetMg()
        # Get the offset (position) of the global matrix with a reflected x
        # component.
        off = c4d.Vector(-mg.off.x, mg.off.y, mg.off.z)
        # Construct the x column vector (c4d defines the axis in column vectors in
        # its transform matrices) by copying and mirroring the x column vector of
        # the object's global matrix on its x axis.
        v1 = c4d.Vector(-mg.v1.x, mg.v1.y, mg.v1.z)
        # The same for the y column
        v2 = c4d.Vector(-mg.v2.x, mg.v2.y, mg.v2.z)
        # The same for y column
        v3 = c4d.Vector(-mg.v3.x, mg.v3.y, mg.v3.z)
        # The new matrix.
        mg = c4d.Matrix(off, v1, v2, v3)
        # Set the global matrix of our object.
        op.SetMg(mg)
    

    I am not sure what you mean by incorrect z axis, but note that coordinate systems and therefor its matrices are either left handed or right handed (Cinema is left handed), which dictates the relation of the positive quadrants of the coordinate system. So I assume, what you mean by incorrect z axis, is a change of orientation of the z-axis gizmo in the editor, but that is actually normal.

    Cheers
    zipit



  • Thank you for the clarification, @zipit.


Log in to reply