Inverting specific axes using Quaternions?

I am trying to convert from one rotated avatar rig bone to a network rig bone based on a (non humnaoid) “palm” offset bone that has been animated.

I am using the approach below to adjust the orientation of the axes in hopes to compensate for the difference between forward directions. The idea is to offset an IK target bone that always tracks the player’s controller. And the (now offset) IK target bone makes the avatar’s hand appear as offset to the player’s controller based on the animated palm hand bone.

So here’s a partially working concept but it shows apparent gimbal lock occurring when some of the rotations approach zero.

                NetSkeletonOffsetPoint.localRotation = Quaternion.Euler (
                    -AvatarAttachPointOffset.localRotation.eulerAngles.z,
                    -AvatarAttachPointOffset.localRotation.eulerAngles.y,
                    AvatarAttachPointOffset.localRotation.eulerAngles.x
                ); //How to do this with Quaternions instead???

What I would really like to understand is how to represent a similar function using Quaternions, but I’m not sure how to adjust the axes directions like the above.

Can it be done by calculating and simply applying an offset:

handOffsetPoint.localRotation = attachPointOffset * Quaternion.inverse(someOffsetQuaternion);

I do not understand how to handle the inverting of the seperate y and z axis while preserving the x using Quaternions?

I did attempt to use the orientation matrix directly to adjust the axes, however I tried many different values for the rows but couldn’t get things to line up.

    Matrix4x4 GetInversionMatrix(Transform t) {
        var Mo = Matrix4x4.TRS (
            t.localPosition,
            t.localRotation,
            t.localScale
        );
        var Mi = Matrix4x4.identity;

        Mi.SetRow (0, new Vector4 (0, 0, -1, 0)); //set the inversion
        Mi.SetRow (1, new Vector4 (0, -1, 0, 0)); //set the inversion
        Mi.SetRow (2, new Vector4 (1, 0, 0, 0)); //set the inversion
        Mi.SetRow (3, new Vector4 (0, 0, 0, 1)); //set the inversion
        return Mi * Mo * Mi;
    }

    void syncTransformInversion(Transform src_bone, Transform dst_bone) {
        dst_bone.position = src_bone.position;
        dst_bone.rotation = GetInversionMatrix (src_bone).GetRotation () ;
    }

Note that the above method appeared to work in a previous project, however the rigs where different and I can’t recall how the animations where created or what the matrix values where, so I’m back to the drawing board.

Any help would be great, I’m kind of stuck on this part and after staring at animated character rotations all day and trying to translate them between bones with different facing directions I’ve really just got to step back and give this some thought (and maybe a little sleep).

Still totally stuck.

After hours of trying stuff I made three super simple animations, where the palm bone rotates only 90 degrees on each axis after 10 frames.

But when I imported the X Y and Z animations into unity I noticed that the Y animation looks bogus compared to the clean curves in blender, while the X and Z are fine.

Blender’s curves (Y axis only animation)

Unity’s curves (should be Y axis only animation but instead it’s crazyness)

When I play the animation in the editor it seems to be the same as blender, but I just can’t get over how wild those curve look.

I have no idea why this is happening or how to stop it, but I feel that maybe my above code is correct and the apparent gimbal lock issue is actually due to this inconsistency.

Has anyone ever run into this issue before?

Also I have read the documentation here that states “in Unity 5.3 and onwards there is the option to turn off animation resampling”. But this option does not exist?

Where is this located???

[Update]
I managed to create some more animation and imported them as generic rig type, this allowed me to disable re-sampling. Now the curves look more or less how I would expect them to, however this did not seem to have any affect regarding the gimbal lock issue.

Still working towards a solution…