/// <summary>
        /// Encodes skeleton data to transmission.
        /// </summary>
        public static string EncodeSkeletonData(BodyData bodyData)
        {
            if (bodyData.JointData == null)
            {
                return EncodeError("EncodeSkeletonData: joint data is null.");
            }

            _stringBuilder.Remove(0, _stringBuilder.Length);
            _stringBuilder.AppendFormat(CultureInfo.InvariantCulture,"{0}|{1} {2} ", SkeletonFrameType, bodyData.UserId, (int)bodyData.TrackingState);
            foreach (var jointData in bodyData.JointData)
            {
                if (jointData.State == JointTrackingState.NotTracked)
                {
                    continue;
                }

                // joint_id state x y z qx qy qz qw 
                _stringBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0} {1} {2} {3} {4} {5} {6} {7} {8} ",
                                            (int)jointData.JointId, (int)jointData.State, jointData.PositionX, jointData.PositionY, jointData.PositionZ,
                                            jointData.QuaternionX, jointData.QuaternionY, jointData.QuaternionZ, jointData.QuaternionW);
            }
            return _stringBuilder.ToString();
        }
        /// <summary>
        /// Decodes the skeleton data received from the data stream into joint positions.
        /// </summary>
        public static void DecodeSkeletonData(string data, out BodyData bodyData)
        {
            const int jointsNumber = (int)JointType.NumberOfJoints;
            bodyData = new BodyData();
            bodyData.JointData = new JointData[jointsNumber];
            var jointsData = bodyData.JointData;

            if (jointsData == null || jointsData.Length != jointsNumber)
            {
                throw new Exception("DecodeSkeletonData is expecting a JointData[] buffer big enough to hold the data.");
            }

            for (int i = 0; i < jointsData.Length; i++)
            {
                jointsData[i].State = JointTrackingState.NotTracked;
            }

            string[] tokens = data.Split(' ');
            bodyData.UserId = int.Parse(tokens[0], CultureInfo.InvariantCulture);
            bodyData.TrackingState = (BodyTrackingState)int.Parse(tokens[1], CultureInfo.InvariantCulture);

            const int jointDataOffset = 2;
            const int elementsNumber = 9;
            for (int i = 0; i + jointDataOffset < (tokens.Length / elementsNumber) + jointDataOffset; i++)
            {
                int jointId = int.Parse(tokens[(i * elementsNumber) + jointDataOffset], CultureInfo.InvariantCulture);
                jointsData[jointId].State = (JointTrackingState)int.Parse(tokens[(i * elementsNumber + 1) + jointDataOffset], CultureInfo.InvariantCulture);
                jointsData[jointId].PositionX = float.Parse(tokens[(i * elementsNumber + 2) + jointDataOffset], CultureInfo.InvariantCulture);
                jointsData[jointId].PositionY = float.Parse(tokens[(i * elementsNumber + 3) + jointDataOffset], CultureInfo.InvariantCulture);
                jointsData[jointId].PositionZ = float.Parse(tokens[(i * elementsNumber + 4) + jointDataOffset], CultureInfo.InvariantCulture);
                jointsData[jointId].QuaternionX = float.Parse(tokens[(i * elementsNumber + 5) + jointDataOffset], CultureInfo.InvariantCulture);
                jointsData[jointId].QuaternionY = float.Parse(tokens[(i * elementsNumber + 6) + jointDataOffset], CultureInfo.InvariantCulture);
                jointsData[jointId].QuaternionZ = float.Parse(tokens[(i * elementsNumber + 7) + jointDataOffset], CultureInfo.InvariantCulture);
                jointsData[jointId].QuaternionW = float.Parse(tokens[(i * elementsNumber + 8) + jointDataOffset], CultureInfo.InvariantCulture);
             }
        }
 private BodyData SetupBodyData(int userId)
 {
     var bodyData = new BodyData();
     bodyData.UserId = userId;
     const int jointsNumber = (int)DataConverter.JointType.NumberOfJoints;
     var jointData = new JointData[jointsNumber];
     for (int i = 0; i < jointsNumber; i++)
     {
         jointData[i] = new JointData();
         jointData[i].JointId = (DataConverter.JointType)i;
     }
     bodyData.JointData = jointData;
     return bodyData;
 }