void SetToTPose()
        {
            Dictionary <HumanBodyBones, Transform> includeJoints = jointFieldMap.Keys.
                                                                   Where(k => GetTransformFromField(k) != null).
                                                                   ToDictionary(k => k.ToUnityBones(), v => GetTransformFromField(v));

            Object[] bones = includeJoints.Values.ToArray();
            Undo.RegisterCompleteObjectUndo(bones, "Set T-Pose");

            NuitrackAvatar avatar = target as NuitrackAvatar;

            SkeletonUtils.SetToTPose(avatar.transform, includeJoints);
        }
        public SkeletonBonesView(Transform root, ViewMode viewMode = ViewMode.AssignedBones)
        {
            CurrentViewMode = viewMode;
            this.root       = root;

            validBones = SkeletonUtils.GetValidBones(root);

            childsList = new Dictionary <nuitrack.JointType, List <nuitrack.JointType> >();

            foreach (nuitrack.JointType jointType in Enum.GetValues(typeof(nuitrack.JointType)))
            {
                nuitrack.JointType parent = jointType.GetParent();

                if (parent != nuitrack.JointType.None)
                {
                    if (!childsList.ContainsKey(parent))
                    {
                        childsList.Add(parent, new List <nuitrack.JointType>());
                    }

                    childsList[parent].Add(jointType);
                }
            }

            // UI toolbar elements

            GUIContent modelBonesContent = EditorGUIUtility.IconContent("scenepicking_pickable-mixed_hover");

            modelBonesContent.text = "Model bones";

            GUIContent assignBonesContent = EditorGUIUtility.IconContent("AvatarSelector");

            assignBonesContent.text = "Assigned bones";

            GUIContent noneContent = EditorGUIUtility.IconContent("animationvisibilitytoggleoff");

            skeletonModeGuiContent = new GUIContent[] { modelBonesContent, assignBonesContent, noneContent };
        }
        void DrawSkeletonMap()
        {
            IEnumerable <JointType> activeJoints = jointFieldMap.Keys.Where(k => GetTransformFromField(k) != null);

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Avatar map", EditorStyles.boldLabel);

            if (skeletonMapper != null)
            {
                skeletonMapper.Draw(activeJoints.ToList());
            }

            GUIContent toObjectGUIContent = EditorGUIUtility.IconContent("SceneViewCamera");

            toObjectGUIContent.text = "Centered in view";

            if (GUILayout.Button(toObjectGUIContent))
            {
                NuitrackAvatar avatar = target as NuitrackAvatar;
                SkeletonUtils.CenteredInView(avatar.transform);
            }

            if (skeletonBonesView != null)
            {
                skeletonBonesView.DrawInspectorGUI();
            }

            EditorGUILayout.Space();

            if (skeletonJointListUI != null)
            {
                Dictionary <JointType, Transform> jointDict = activeJoints.ToDictionary(k => k, v => GetTransformFromField(v));
                skeletonJointListUI.Draw(jointDict);
            }

            EditorGUILayout.Space();
            DrawAutomapTools(activeJoints);
        }
        void AutoMapping()
        {
            NuitrackAvatar avatar = target as NuitrackAvatar;

            Dictionary <HumanBodyBones, Transform> skeletonBonesMap = SkeletonUtils.GetBonesMap(avatar.transform);

            if (skeletonBonesMap == null || skeletonBonesMap.Count == 0)
            {
                Debug.LogError("It is not possible to automatically fill in the skeleton map. Check the correctness of your model.");
                return;
            }

            List <HumanBodyBones> failFoundBones = new List <HumanBodyBones>();

            foreach (JointType jointType in jointFieldMap.Keys)
            {
                HumanBodyBones humanBodyBones = jointType.ToUnityBones();

                if (GetTransformFromField(jointType) == null)
                {
                    if (excludeAutoFillJoints.Contains(jointType) || !skeletonBonesMap.ContainsKey(humanBodyBones))
                    {
                        failFoundBones.Add(humanBodyBones);
                    }
                    else
                    {
                        EditJoint(jointType, skeletonBonesMap[humanBodyBones]);
                    }
                }
            }

            if (failFoundBones.Count > 0)
            {
                Debug.Log(string.Format("For bones: <color=orange><b>{0}</b></color>, could not be found object Transforms", string.Join(", ", failFoundBones)));
            }
        }
        void DrawBoneController(int controllerID, Transform boneTransform, List <Transform> childs, nuitrack.JointType jointType, float size)
        {
            childs ??= new List <Transform>();

            Event e = Event.current;

            //We divide the size by 2, since strange behavior is detected when an element falls into the selection.
            //The size of the visual element is set by the diameter, and the selection area by the radius.
            Handles.SphereHandleCap(controllerID, boneTransform.position, boneTransform.rotation, size / 2, EventType.Layout);

            switch (e.GetTypeForControl(controllerID))
            {
            case EventType.MouseDown:
                if (HandleUtility.nearestControl == controllerID && e.button == 0)
                {
                    // Respond to a press on this handle. Drag starts automatically.
                    GUIUtility.hotControl      = controllerID;
                    GUIUtility.keyboardControl = controllerID;

                    e.Use();
                }
                break;

            case EventType.MouseUp:
                if (GUIUtility.hotControl == controllerID && e.button == 0)
                {
                    GUIUtility.hotControl = 0;
                    e.Use();

                    OnBoneSelected?.Invoke(CurrentViewMode, jointType, boneTransform);
                }
                break;

            case EventType.Repaint:
                Color withHoverColor = Handles.color;

                if (GUIUtility.hotControl == 0 && HandleUtility.nearestControl == controllerID)
                {
                    withHoverColor = Color.Lerp(Handles.color, hoverColor, 0.5f);
                }

                using (new HandlesColor(withHoverColor))
                {
                    Handles.SphereHandleCap(controllerID, boneTransform.position, boneTransform.rotation, size, EventType.Repaint);

                    foreach (Transform child in childs)
                    {
                        SkeletonUtils.DrawBone(boneTransform.position, child.position);
                    }
                }
                break;

            case EventType.KeyDown:
                if ((e.keyCode == KeyCode.Backspace || e.keyCode == KeyCode.Delete) && GUIUtility.keyboardControl == controllerID)
                {
                    GUIUtility.keyboardControl = 0;
                    e.Use();

                    OnRemoveBone?.Invoke(CurrentViewMode, jointType, boneTransform);
                }
                break;
            }
        }