// initialize a roll joint data for the given joint as parent
    private void JoinRollJoint(string rollJointName, Omek.JointID parentJointID)
    {
        TransformWrapper tw  = m_hierarchyList.Find((a) => { return(a.m_jointID == parentJointID); });
        RollJointWrapper rjw = m_rollJointsList.Find((a) => { return(a.m_name == rollJointName); });

        tw.m_rollJoint      = rjw;
        rjw.m_parentWrapper = tw;
        if (tw.m_transform != null)
        {
            rjw.m_originalParentRotation        = tw.m_transform.localRotation;
            rjw.m_inverseOriginalParentRotation = Quaternion.Inverse(rjw.m_originalParentRotation);
        }
    }
    // return the reflected joint of a given joint
    private static Omek.JointID GetReflectedJointID(Omek.JointID jointID)
    {
        switch (jointID)
        {
        case Omek.JointID.leftCollar:
            return(Omek.JointID.rightCollar);

        case Omek.JointID.rightCollar:
            return(Omek.JointID.leftCollar);

        case Omek.JointID.leftShoulder:
            return(Omek.JointID.rightShoulder);

        case Omek.JointID.rightShoulder:
            return(Omek.JointID.leftShoulder);

        case Omek.JointID.leftElbow:
            return(Omek.JointID.rightElbow);

        case Omek.JointID.rightElbow:
            return(Omek.JointID.leftElbow);

        case Omek.JointID.leftFingerTip:
            return(Omek.JointID.rightFingerTip);

        case Omek.JointID.rightFingerTip:
            return(Omek.JointID.leftFingerTip);

        case Omek.JointID.leftHip:
            return(Omek.JointID.rightHip);

        case Omek.JointID.rightHip:
            return(Omek.JointID.leftHip);

        case Omek.JointID.leftKnee:
            return(Omek.JointID.rightKnee);

        case Omek.JointID.rightKnee:
            return(Omek.JointID.leftKnee);

        case Omek.JointID.rightFoot:
            return(Omek.JointID.leftFoot);

        case Omek.JointID.leftFoot:
            return(Omek.JointID.rightFoot);

        default:
            return(jointID);
        }
    }
 /// <summary>
 /// Set specific joint be active so it will play the animation
 /// </summary>
 /// <param name="jointID">the joint id to effect</param>
 /// <param name="isActive">should the joint be activate or deactivate</param>
 /// <param name="applyForAllChildren">should the joint children state be changed as well</param>
 public void SetJointActive(Omek.JointID jointID, bool isActive, bool applyForAllChildren = false)
 {
     foreach (TransformWrapper tw in m_hierarchyList)
     {
         if (tw.m_jointID == jointID)
         {
             if (applyForAllChildren)
             {
                 SetJointActiveForChildren(tw.m_transform, isActive);
             }
             else
             {
                 tw.m_active = isActive;
             }
             break;
         }
     }
 }
    // update the confidence  for a joint
    private void UpdateConfidence(ConfidanceParams confidanceParams, Omek.JointID jointID)
    {
        if (m_lastPersonIndex < 0)
        {
            return;
        }
        BeckonData.Persons[(uint)m_lastPersonIndex].Skeleton[(Omek.JointID)jointID].Confidence.Get(out confidanceParams.m_currentConfidence);
        // do we have good confidence for this frame
        bool isConfidant = (confidanceParams.m_currentConfidence >= 70);

        // initialize if this the first time
        if (confidanceParams.m_confidenceWeight == -1)
        {
            confidanceParams.m_lastFrameConfidence  = isConfidant;
            confidanceParams.m_lastCurrentStateTime = Time.realtimeSinceStartup;
            confidanceParams.m_confidenceWeight     = isConfidant ? 1 : 0;
            return;
        }

        // if there is a difference from last value and enough time passed since the last change
        if (isConfidant != confidanceParams.m_lastFrameConfidence && Time.realtimeSinceStartup >= confidanceParams.m_lastCurrentStateTime + m_confidenceChangeSafetyTime)
        {
            confidanceParams.m_lastFrameConfidence  = isConfidant;
            confidanceParams.m_lastCurrentStateTime = Time.realtimeSinceStartup;
        }
        else if (isConfidant == confidanceParams.m_lastFrameConfidence) // we have the same value as before - update last known time
        {
            confidanceParams.m_lastCurrentStateTime = Time.realtimeSinceStartup;
        }
        // move the real confidenceWeight towards 1 or 0 according to the current value
        if (confidanceParams.m_lastFrameConfidence)
        {
            confidanceParams.m_confidenceWeight = Mathf.MoveTowards(confidanceParams.m_confidenceWeight, 1, Time.deltaTime * m_confidenceChangeRate);
        }
        else
        {
            confidanceParams.m_confidenceWeight = Mathf.MoveTowards(confidanceParams.m_confidenceWeight, 0, Time.deltaTime * m_confidenceChangeRate);
        }
    }
 public TransformWrapper(Omek.JointID jointID, bool mandatory)
 {
     m_jointID   = jointID;
     m_mandatory = mandatory;
 }
    // We use LateUpdate so the transforms will be updated by all other animation.
    // We'll compute the transform of the tracking animation and blend them together
    void LateUpdate()
    {
        CheckForPersonChange();
        if (m_initalized)
        {
            m_weight = calcualteCurrentWeight();
            if (m_weight > 0)
            {
                OMKStatus rc = OMKStatus.OMK_ERROR_SKELETON_NOT_FOUND;
                if (m_useRetargetSkeleton)
                {
                    rc = BeckonManager.BeckonInstance.PersonAnalyzer.getRetargetedSkeleton(m_characterName, ref m_currentSkeleton);
                }
                else
                {
                    Omek.IPerson person;
                    rc = BeckonManager.BeckonInstance.PersonAnalyzer.getPerson((uint)m_lastPersonIndex, out person);
                    if (rc == OMKStatus.OMK_SUCCESS)
                    {
                        rc = person.copySkeleton(m_currentSkeleton);
                    }
                }
                if (rc != OMKStatus.OMK_SUCCESS)
                {
                    return;
                }
                Quaternion baseRotation = m_transform.rotation;
                m_transform.rotation = Quaternion.identity;
                float[] beckonQuat = new float[4];
                foreach (TransformWrapper transformWrapper in m_hierarchyList)
                {
                    if (!transformWrapper.m_active || transformWrapper.m_transform == null)
                    {
                        continue;
                    }
                    Omek.JointID jointID = transformWrapper.m_jointID;
                    if (m_mirror)
                    {
                        jointID = GetReflectedJointID(jointID);
                    }

                    rc = m_currentSkeleton.getJointOrientation((JointID)jointID, true, beckonQuat);

                    if (rc == OMKStatus.OMK_SUCCESS)
                    {
                        // fixing quaternion handness
                        Quaternion quat = UnityConverter.ToUnityQuaternion(beckonQuat);
                        if (m_mirror)
                        {
                            quat.x = -quat.x;
                            quat.w = -quat.w;
                        }

                        // add the original base T-pose rotation to the current rotation.
                        quat = quat * transformWrapper.m_originalRotation;

                        //Smoothly rotate towards the new quaternion based on the confidence

                        UpdateConfidence(transformWrapper.m_confidanceParams, jointID);
                        if (transformWrapper.m_confidanceParams.m_currentConfidence >= 70)
                        {
                            if (m_useSmoothing == true)
                            {
                                quat = RotateTowards(transformWrapper.m_lastRotation, quat, Time.deltaTime * m_animationSmoothing);
                            }
                        }
                        else
                        {
                            quat = transformWrapper.m_lastRotation;
                        }

                        // save the current rotation for next frame
                        transformWrapper.m_lastRotation = quat;

                        // smoothly blend in, the orientation from tracking with the transform orientation from all other animations base on animation weight
                        transformWrapper.m_transform.rotation = Quaternion.Slerp(transformWrapper.m_transform.rotation, quat, m_weight * transformWrapper.m_confidanceParams.m_confidenceWeight);

                        if (transformWrapper.m_rollJoint != null && transformWrapper.m_rollJoint.m_transform != null && transformWrapper.m_rollJoint.m_active)
                        {
                            rollRotation(transformWrapper.m_rollJoint);
                        }
                    }
                }
                m_transform.rotation = baseRotation;
            }
        }
    }