Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question Hand Rotation off in Humanoid

Discussion in 'Animation' started by damsel15aug, Mar 28, 2021.

  1. damsel15aug

    damsel15aug

    Joined:
    Dec 14, 2019
    Posts:
    1
    Hi, I am trying to map 3D Pose data on Rocketbox Avatar. Everything seems to work fine except Hands. The rotation of the right and left shoulder is off and elbows are not bending at all. I tried deleting Spine 2 in Avatar and naming spine 1 as Upperchest and parent it of Shoulders. It didn't work. I tried changing the Avatar but the problem stays the same. I also tried enabling Neck Triangle in 3ds Max but no change. Any help would be appreciated.



    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4.  
    5. public class Player: MonoBehaviour
    6. {
    7.     public int id;
    8.     public string username;
    9.  
    10.     // Pose Estimation members
    11.     public string[] str = new string[66];
    12.     public string pose = "";
    13.     Transform[] bone_t; // Model Bone Transform
    14.     Vector3 init_position; // Initial center position
    15.     Quaternion[] init_rot; // Initial rotation value
    16.     Quaternion[] init_inv; // Quaternion Inverse calculated from the initial bone direction
    17.     int[] bones = new int[14] { 2,3,6,7,8, 10,11,12, 14,15,16, 18,19,20 }; // parent bone
    18.     int[] child_bones = new int[14] {3, 5, 7, 8, 9, 11,12,13, 15,16,17, 19,20,21 }; // Child bones corresponding to bones
    19.  
    20.     Transform[] cube_t; // Debug Cube Transform
    21.     GameObject[] cubes = new GameObject[22];
    22.     public Boolean debug_cube;
    23.     public const int bone_num = 22;
    24.     public Text myText;
    25.  
    26.  
    27.     Animator anim;
    28.     static Vector3[] now_pos = new Vector3[bone_num];
    29.  
    30.     private void GetInitInfo()
    31.     {
    32.         bone_t = new Transform[bone_num];
    33.         init_rot = new Quaternion[bone_num];
    34.         init_inv = new Quaternion[bone_num];
    35.  
    36.        
    37.         bone_t[1] = anim.GetBoneTransform(HumanBodyBones.Hips);
    38.         bone_t[2] = anim.GetBoneTransform(HumanBodyBones.Spine);
    39.         bone_t[3] = anim.GetBoneTransform(HumanBodyBones.UpperChest);
    40.         bone_t[4] = anim.GetBoneTransform(HumanBodyBones.Neck);
    41.         bone_t[5] = anim.GetBoneTransform(HumanBodyBones.Head);
    42.         bone_t[6] = anim.GetBoneTransform(HumanBodyBones.RightShoulder);
    43.         bone_t[7] = anim.GetBoneTransform(HumanBodyBones.RightUpperArm);
    44.         bone_t[8] = anim.GetBoneTransform(HumanBodyBones.RightLowerArm);
    45.         bone_t[9] = anim.GetBoneTransform(HumanBodyBones.RightHand);
    46.         bone_t[10] = anim.GetBoneTransform(HumanBodyBones.RightUpperLeg);
    47.         bone_t[11] = anim.GetBoneTransform(HumanBodyBones.RightLowerLeg);
    48.         bone_t[12] = anim.GetBoneTransform(HumanBodyBones.RightFoot);
    49.         bone_t[13] = anim.GetBoneTransform(HumanBodyBones.RightToes);
    50.         bone_t[14] = anim.GetBoneTransform(HumanBodyBones.LeftShoulder);
    51.         bone_t[15] = anim.GetBoneTransform(HumanBodyBones.LeftUpperArm);
    52.         bone_t[16] = anim.GetBoneTransform(HumanBodyBones.LeftLowerArm);
    53.         bone_t[17] = anim.GetBoneTransform(HumanBodyBones.LeftHand);
    54.         bone_t[18] = anim.GetBoneTransform(HumanBodyBones.LeftUpperLeg);
    55.         bone_t[19] = anim.GetBoneTransform(HumanBodyBones.LeftLowerLeg);
    56.         bone_t[20] = anim.GetBoneTransform(HumanBodyBones.LeftFoot);
    57.         bone_t[21] = anim.GetBoneTransform(HumanBodyBones.LeftToes);
    58.  
    59.         // Make a triangle with Spine, LHip and RHip and make it the front direction.
    60.         Vector3 init_forward = TriangleNormal(bone_t[2].position, bone_t[18].position, bone_t[10].position);
    61.         init_inv[0] = Quaternion.Inverse(Quaternion.LookRotation(init_forward));
    62.  
    63.         init_position = bone_t[1].position;
    64.         init_rot[0] = bone_t[1].rotation;
    65.  
    66.         for (int i = 0; i < bones.Length; i++)
    67.         {
    68.             int b = bones[i];
    69.             int cb = child_bones[i];
    70.  
    71.             // Initial value of the target model's rotation
    72.             init_rot[b] = bone_t[b].rotation;
    73.             // Quaternion calculated from the initial bone direction
    74.             init_inv[b] = Quaternion.Inverse(Quaternion.LookRotation(bone_t[b].position - bone_t[cb].position, init_forward));
    75.         }
    76.     }
    77.  
    78.     // Returns a vector of length 1 perpendicular to the triangle formed by the specified 3 points
    79.     private static Vector3 TriangleNormal(Vector3 a, Vector3 b, Vector3 c)
    80.     {
    81.         Vector3 d1 = a - b;
    82.         Vector3 d2 = a - c;
    83.         Vector3 dd = Vector3.Cross(d1, d2);
    84.         dd.Normalize();
    85.         return dd;
    86.     }
    87.  
    88.     // Start is called before the first frame update
    89.     void Start()
    90.     {
    91.  
    92.         anim = GetComponent<Animator>();
    93.         GetInitInfo();
    94.     }
    95.  
    96.     // Update is called once per frame
    97.     int Update()
    98.     {
    99.         if (id == Client.instance.myId)
    100.         {
    101.             pose = PoseClient.instance.DataToPoseController();
    102.             float fps = (1.0f / Time.unscaledDeltaTime);
    103.             myText.text =  "FPS:" + fps;
    104.         }
    105.         if (pose != "" && pose != null)
    106.         {
    107.             str = pose.Split(',');
    108.             now_pos = new Vector3[bone_num];
    109.  
    110.             for (int i = 0; i < str.Length; i += 3)
    111.             {
    112.                 now_pos[i / 3] = new Vector3(float.Parse(str[i]), float.Parse(str[i + 1]), float.Parse(str[i + 2]));
    113.             }
    114.  
    115.             // Movement and rotation of the center
    116.             Vector3 pos_forward = TriangleNormal(now_pos[2], now_pos[18], now_pos[10]);
    117.             bone_t[1].position = now_pos[1] * PoseConstants.scale_ratio + new Vector3(init_position.x, init_position.y, init_position.z);
    118.             bone_t[1].rotation = Quaternion.LookRotation(pos_forward) * init_inv[0] * init_rot[0];
    119.  
    120.             // Rotation of each bone
    121.             for (int i = 0; i < bones.Length; i++)
    122.             {
    123.                 int b = bones[i];
    124.                 int cb = child_bones[i];
    125.                 bone_t[b].rotation = Quaternion.LookRotation(now_pos[b] - now_pos[cb], pos_forward) * init_inv[b] * init_rot[b];
    126.             }
    127.         }
    128.         return 0;
    129.     }
    130. }
    131.