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).