Distortion issue when rotating avatar in RiggedModel scene

In this scene, if the avatar’s Z value is 0, skeleton tracking works without a problem.

However, when the avatar’s z value rotates, the avatar’s joints become tangled.

ex) If I rotate the avatar 90 degrees around the z-axis and raise my arm, I want the avatar’s arm to go up above the avatar’s head. However, the avatar’s arms only move upward on the screen.

I would like to know which part of the script I need to modify to resolve this issue.

Hello @sabin

Like this?

Thank you for answer.

It’s similar, but what I tested was the RiggedModel scene.
Tested with RiggedAvatar

Did you manage to achieve the desired result?

No I didn’t get it. :frowning:

When using the Nuitrack Avatar component (as I showed earlier), does the avatar not work when rotated 90 degrees?
Or do you want to achieve something else?

It is difficult to test in the scene you showed because we do not currently have a sensor.
There is a problem with avatar tracking in the scene I mentioned.

If you need RiggedAvatar for some reason, then you can update the script and the avatar will rotate in any direction

RiggedAvatar.cs
using UnityEngine;
using System.Collections.Generic;
using NuitrackSDK.Calibration;


namespace NuitrackSDK.Tutorials.AvatarAnimation
{
    [AddComponentMenu("NuitrackSDK/Tutorials/Avatar Animation/Rigged Avatar")]
    public class RiggedAvatar : MonoBehaviour
    {
        [Header("Rigged model")]
        [SerializeField]
        ModelJoint[] modelJoints;
        [SerializeField]
        nuitrack.JointType rootJoint = nuitrack.JointType.LeftCollar;
        /// <summary> Model bones </summary>
        Dictionary<nuitrack.JointType, ModelJoint> jointsRigged = new Dictionary<nuitrack.JointType, ModelJoint>();

        void Start()
        {
            for (int i = 0; i < modelJoints.Length; i++)
            {
                modelJoints[i].baseRotOffset = Quaternion.Inverse(transform.rotation) * modelJoints[i].bone.rotation;
                jointsRigged.Add(modelJoints[i].jointType.TryGetMirrored(), modelJoints[i]);
            }
        }

        void Update()
        {
            if (NuitrackManager.Users.Current != null && NuitrackManager.Users.Current.Skeleton != null)
                ProcessSkeleton(NuitrackManager.Users.Current.Skeleton);
        }

        void ProcessSkeleton(UserData.SkeletonData skeleton)
        {
            //Calculate the model position: take the root position and invert movement along the Z axis
            Vector3 rootPos = Quaternion.Euler(0, 180, 0) * skeleton.GetJoint(nuitrack.JointType.Waist).Position; ;
            jointsRigged[nuitrack.JointType.Waist].bone.transform.position = transform.TransformPoint(rootPos);

            foreach (var riggedJoint in jointsRigged)
            {
                //Get joint from the Nuitrack
                UserData.SkeletonData.Joint joint = skeleton.GetJoint(riggedJoint.Key);

                ModelJoint modelJoint = riggedJoint.Value;

                //Calculate the model bone rotation: take the mirrored joint orientation, add a basic rotation of the model bone, invert movement along the Z axis
                Quaternion jointOrient = transform.rotation * Quaternion.Inverse(CalibrationInfo.SensorOrientation) * joint.RotationMirrored * modelJoint.baseRotOffset;

                modelJoint.bone.rotation = jointOrient;
            }
        }
    }
}

Do you have any more questions about Nuitrack?