Skip to content

API & Core Algorithm

Jason Jung edited this page Jun 10, 2019 · 2 revisions

API and Core Algorithm

Connect To Kinect

KinectManager kinectManager = KinectManager.Instance;
AvatarController avatarCtrl = avatarModel ? avatarModel.gameObject.GetComponent<AvatarController>() : null;

Get Pose difference between Avatar model and Pose model / Avatar model and Base model (Percentage)

  • Each model is brought from PoseModelHelper class.

    MatchPercent = 1f - GetPoseDifference(isMirrored, true, ref sDiffDetails, avatarModel, poseModel);
    bMatchPercent = 1f - GetPoseDifference(isMirrored, true, ref bDiffDetails, avatarModel, baseModel);
    

Loop and see all connected joints are matched with pose model. If it is not matched, Print the text “Your pose is wrong”. Joint information is from KinectInterop class.

for (int i = 0; i < poseJoints.Count; i++)
    {
        KinectInterop.JointType joint = poseJoints[i];
        KinectInterop.JointType nextJoint = kinectManager.GetNextJoint(joint);

        if (nextJoint != joint && (int)nextJoint >= 0 && (int)nextJoint < KinectInterop.Constants.MaxJointCount)
        {
            Transform avatarTransform1 = avatarModel.GetBoneTransform(avatarModel.GetBoneIndexByJoint(joint, isMirrored));
            Transform avatarTransform2 = avatarModel.GetBoneTransform(avatarModel.GetBoneIndexByJoint(nextJoint, isMirrored));

            Transform poseTransform1 = poseModel.GetBoneTransform(poseModel.GetBoneIndexByJoint(joint, isMirrored));
            Transform poseTransform2 = poseModel.GetBoneTransform(poseModel.GetBoneIndexByJoint(nextJoint, isMirrored));

            if (avatarTransform1 != null && avatarTransform2 != null && poseTransform1 != null && poseTransform2 != null)
            {
                Vector3 vAvatarBone = (avatarTransform2.position - avatarTransform1.position).normalized;
                Vector3 vPoseBone = (poseTransform2.position - poseTransform1.position).normalized;

                float fDiff = Vector3.Angle(vPoseBone, vAvatarBone);
                if (fDiff > 90f) fDiff = 90f;

                fAngleDiff += fDiff;
                fMaxDiff += 90f;  // we assume the max diff could be 90 degrees

                //sbDetails.AppendFormat("{0} - {1:F0} deg.", joint, fDiff).AppendLine();

                if ((fDiff > 30 && fDiff < 60) && (KinectInterop.JointType.ShoulderLeft == poseJoints[i] || KinectInterop.JointType.ShoulderRight == poseJoints[i]))
                {
                    sbDetails.AppendFormat(poseJoints[i] == KinectInterop.JointType.ShoulderLeft ? "왼쪽팔이 일치하지 않습니다.\n" : "오른쪽팔이 일치하지 않습니다\n");
                }
                if ((fDiff > 30 && fDiff < 60) && (KinectInterop.JointType.KneeLeft == poseJoints[i] || KinectInterop.JointType.KneeRight == poseJoints[i]))
                {
                    sbDetails.AppendFormat(poseJoints[i] == KinectInterop.JointType.KneeLeft ? "왼쪽 다리가 일치하지 않습니다.\n" : "오른쪽 다리가 일치하지 않습니다\n");
                }
                sbDetails.AppendFormat("");
            }
            else
            {
                sbDetails.AppendFormat("{0} - n/a", joint).AppendLine();
            }
        }
    }

Calculate the percentage of matching among all joints then return it.

float fPercentDiff = 0f;
if (bPercentDiff && fMaxDiff > 0f)
{
    fPercentDiff = fAngleDiff / fMaxDiff;
}

// details info
sbDetails.AppendLine();
sbDetails.AppendFormat("Sum-Diff: - {0:F0} deg out of {1:F0} deg", fAngleDiff, fMaxDiff).AppendLine();
sbDetails.AppendFormat("Percent-Diff: {0:F0}%", fPercentDiff * 100).AppendLine();
sDiffDetails = sbDetails.ToString();

return (bPercentDiff ? fPercentDiff : fAngleDiff);

Using ‘isMatched’ Boolean, if user did a great pose, the count is increased when user will be back to attitude posture(base model).

if (bPoseMatched)
{
   if (!isMatched)
   {
       isMatched = true;
   }
}
else if (baseMatched)
{
   if (isMatched)
   {
       count++;
       isMatched = false;
   }
}