private void HandsController_HandsDetected(object sender, HandCollection e)
        {
            // Display the results!

            if (e.HandLeft != null)
            {
                // Draw contour.
                foreach (var point in e.HandLeft.ContourDepth)
                {
                    DrawEllipse(point, Brushes.Green, 2.0);
                }

                // Draw fingers.
                foreach (var finger in e.HandLeft.Fingers)
                {
                    DrawEllipse(finger.DepthPoint, Brushes.White, 4.0);
                }
            }

            if (e.HandRight != null)
            {
                // Draw contour.
                foreach (var point in e.HandRight.ContourDepth)
                {
                    DrawEllipse(point, Brushes.Blue, 2.0);
                }

                // Draw fingers.
                foreach (var finger in e.HandRight.Fingers)
                {
                    DrawEllipse(finger.DepthPoint, Brushes.White, 4.0);
                }
            }
        }
        /// <summary>
        /// Updates the finger-detection engine with the new data.
        /// </summary>
        /// <param name="data">A pointer to an array of depth data.</param>
        /// <param name="body">The body to search for hands and fingers.</param>
        public unsafe void Update(ushort *data, Body body)
        {
            if (data == null || body == null)
            {
                return;
            }

            if (DepthWidth == 0)
            {
                DepthWidth = DEFAULT_DEPTH_WIDTH;
            }

            if (DepthHeight == 0)
            {
                DepthHeight = DEFAULT_DEPTH_HEIGHT;
            }

            if (_handPixelsLeft == null)
            {
                _handPixelsLeft = new byte[DepthWidth * DepthHeight];
            }

            if (_handPixelsRight == null)
            {
                _handPixelsRight = new byte[DepthWidth * DepthHeight];
            }

            //Hand handLeft = null;
            Hand handRight = null;

            //Joint jointHandLeft = body.Joints[JointType.HandLeft];
            Joint jointHandRight = body.Joints[JointType.HandRight];
            //Joint jointWristLeft = body.Joints[JointType.WristLeft];
            Joint jointWristRight = body.Joints[JointType.WristRight];
            //Joint jointTipLeft = body.Joints[JointType.HandTipLeft];
            Joint jointTipRight = body.Joints[JointType.HandTipRight];
            //Joint jointThumbLeft = body.Joints[JointType.ThumbLeft];
            Joint jointThumbRight = body.Joints[JointType.ThumbRight];

            // DepthSpacePoint depthPointHandLeft = CoordinateMapper.MapCameraPointToDepthSpace(jointHandLeft.Position);
            // DepthSpacePoint depthPointWristLeft = CoordinateMapper.MapCameraPointToDepthSpace(jointWristLeft.Position);
            //DepthSpacePoint depthPointTipLeft = CoordinateMapper.MapCameraPointToDepthSpace(jointTipLeft.Position);
            //DepthSpacePoint depthPointThumbLeft = CoordinateMapper.MapCameraPointToDepthSpace(jointThumbLeft.Position);

            DepthSpacePoint depthPointHandRight  = CoordinateMapper.MapCameraPointToDepthSpace(jointHandRight.Position);
            DepthSpacePoint depthPointWristRight = CoordinateMapper.MapCameraPointToDepthSpace(jointWristRight.Position);
            DepthSpacePoint depthPointTipRight   = CoordinateMapper.MapCameraPointToDepthSpace(jointTipRight.Position);
            DepthSpacePoint depthPointThumbRight = CoordinateMapper.MapCameraPointToDepthSpace(jointThumbRight.Position);

            //float handLeftX = depthPointHandLeft.X;
            //float handLeftY = depthPointHandLeft.Y;
            //float wristLeftX = depthPointWristLeft.X;
            //float wristLeftY = depthPointWristLeft.Y;
            //float tipLeftX = depthPointTipLeft.X;
            //float tipLeftY = depthPointTipLeft.Y;
            //float thumbLeftX = depthPointThumbLeft.X;
            //float thumbLeftY = depthPointThumbLeft.Y;

            float handRightX  = depthPointHandRight.X;
            float handRightY  = depthPointHandRight.Y;
            float wristRightX = depthPointWristRight.X;
            float wristRightY = depthPointWristRight.Y;
            float tipRightX   = depthPointTipRight.X;
            float tipRightY   = depthPointTipRight.Y;
            float thumbRightX = depthPointThumbRight.X;
            float thumbRightY = depthPointThumbRight.Y;

            // bool searchForLeftHand = DetectLeftHand && !float.IsInfinity(handLeftX) && !float.IsInfinity(handLeftY) && !float.IsInfinity(wristLeftX) && !float.IsInfinity(wristLeftY) && !float.IsInfinity(tipLeftX) && !float.IsInfinity(tipLeftY) && !float.IsInfinity(thumbLeftX) && !float.IsInfinity(thumbLeftY);
            bool searchForRightHand = DetectRightHand && !float.IsInfinity(handRightX) && !float.IsInfinity(handRightY) && !float.IsInfinity(wristRightX) && !float.IsInfinity(wristRightY) && !float.IsInfinity(tipRightX) && !float.IsInfinity(tipRightY) && !float.IsInfinity(thumbRightX) && !float.IsInfinity(thumbRightY);


            this.fingers = new List <DepthPointEx>();
            //if (searchForLeftHand || searchForRightHand)
            if (searchForRightHand)
            {
                //double distanceLeft = searchForLeftHand ? CalculateDistance(handLeftX, handLeftY, tipLeftX, tipLeftY, thumbLeftX, thumbLeftY) : 0.0;
                double distanceRight = searchForRightHand ? CalculateDistance(handRightX, handRightY, tipRightX, tipRightY, thumbRightX, thumbRightY) : 0.0;

                //double angleLeft = searchForLeftHand ? DepthPointEx.Angle(wristLeftX, wristLeftY, wristLeftX, 0, handLeftX, handLeftY) : 0.0;
                double angleRight = searchForRightHand ? DepthPointEx.Angle(wristRightX, wristRightY, wristRightX, 0, handRightX, handRightY) : 0.0;

                //int minLeftX = searchForLeftHand ? (int)(handLeftX - distanceLeft) : 0;
                //int minLeftY = searchForLeftHand ? (int)(handLeftY - distanceLeft) : 0;
                //int maxLeftX = searchForLeftHand ? (int)(handLeftX + distanceLeft) : 0;
                //int maxLeftY = searchForLeftHand ? (int)(handLeftY + distanceLeft) : 0;

                int minRightX = searchForRightHand ? (int)(handRightX - distanceRight) : 0;
                int minRightY = searchForRightHand ? (int)(handRightY - distanceRight) : 0;
                int maxRightX = searchForRightHand ? (int)(handRightX + distanceRight) : 0;
                int maxRightY = searchForRightHand ? (int)(handRightY + distanceRight) : 0;

                //float depthLeft = jointHandLeft.Position.Z * 1000; // m to mm
                float depthRight = jointHandRight.Position.Z * 1000;

                for (int i = 0; i < DepthWidth * DepthHeight; ++i)
                {
                    ushort depth = data[i];

                    int depthX = i % DepthWidth;
                    int depthY = i / DepthWidth;

                    bool isInBounds = depth >= MIN_DEPTH && depth <= MAX_DEPTH;

                    //bool conditionLeft = depth >= depthLeft - DEPTH_THRESHOLD &&
                    //                     depth <= depthLeft + DEPTH_THRESHOLD &&
                    //                     depthX >= minLeftX && depthX <= maxLeftX &&
                    //                     depthY >= minLeftY && depthY <= maxLeftY;

                    bool conditionRight = depth >= depthRight - DEPTH_THRESHOLD &&
                                          depth <= depthRight + DEPTH_THRESHOLD &&
                                          depthX >= minRightX && depthX <= maxRightX &&
                                          depthY >= minRightY && depthY <= maxRightY;

                    //_handPixelsLeft[i] = (byte)(isInBounds && searchForLeftHand && conditionLeft ? 255 : 0);
                    _handPixelsRight[i] = (byte)(isInBounds && searchForRightHand && conditionRight ? 255 : 0);
                }

                List <DepthPointEx> contourLeft  = new List <DepthPointEx>();
                List <DepthPointEx> contourRight = new List <DepthPointEx>();

                for (int i = 0; i < DepthWidth * DepthHeight; ++i)
                {
                    ushort depth = data[i];

                    int depthX = i % DepthWidth;
                    int depthY = i / DepthWidth;

                    //if (searchForLeftHand)
                    //{
                    //    if (_handPixelsLeft[i] != 0)
                    //    {
                    //        byte top = i - DepthWidth >= 0 ? _handPixelsLeft[i - DepthWidth] : (byte)0;
                    //        byte bottom = i + DepthWidth < _handPixelsLeft.Length ? _handPixelsLeft[i + DepthWidth] : (byte)0;
                    //        byte left = i - 1 >= 0 ? _handPixelsLeft[i - 1] : (byte)0;
                    //        byte right = i + 1 < _handPixelsLeft.Length ? _handPixelsLeft[i + 1] : (byte)0;

                    //        bool isInContour = top == 0 || bottom == 0 || left == 0 || right == 0;

                    //        if (isInContour)
                    //        {
                    //            contourLeft.Add(new DepthPointEx { X = depthX, Y = depthY, Z = depth });
                    //        }
                    //    }
                    //}

                    if (searchForRightHand)
                    {
                        if (_handPixelsRight[i] != 0)
                        {
                            byte top    = i - DepthWidth >= 0 ? _handPixelsRight[i - DepthWidth] : (byte)0;
                            byte bottom = i + DepthWidth < _handPixelsRight.Length ? _handPixelsRight[i + DepthWidth] : (byte)0;
                            byte left   = i - 1 >= 0 ? _handPixelsRight[i - 1] : (byte)0;
                            byte right  = i + 1 < _handPixelsRight.Length ? _handPixelsRight[i + 1] : (byte)0;

                            bool isInContour = top == 0 || bottom == 0 || left == 0 || right == 0;

                            if (isInContour)
                            {
                                contourRight.Add(new DepthPointEx {
                                    X = depthX, Y = depthY, Z = depth
                                });
                            }
                        }
                    }
                }

                //if (searchForLeftHand)
                //{
                //    handLeft = GetHand(body.TrackingId, body.HandLeftState, contourLeft, angleLeft, wristLeftX, wristLeftY, false, handLeftX, handLeftY);
                //}

                if (searchForRightHand)
                {
                    handRight = GetHand(body.TrackingId, body.HandRightState, contourRight, angleRight, wristRightX, wristRightY, true, handRightX, handRightY);
                }
            }

            //if (handLeft != null || handRight != null)
            if (handRight != null)
            {
                HandCollection hands = new HandCollection
                {
                    TrackingId = body.TrackingId,
                    //HandLeft = handLeft,
                    HandRight = handRight
                };

                if (HandsDetected != null)
                {
                    HandsDetected(this, hands);
                }
            }
        }
        /// <summary>
        /// Updates the finger-detection engine with the new data.
        /// </summary>
        /// <param name="data">A pointer to an array of depth data.</param>
        /// <param name="body">The body to search for hands and fingers.</param>
        public unsafe void Update(ushort* data, Body body)
        {
            if (data == null || body == null) return;

            if (DepthWidth == 0)
            {
                DepthWidth = DEFAULT_DEPTH_WIDTH;
            }

            if (DepthHeight == 0)
            {
                DepthHeight = DEFAULT_DEPTH_HEIGHT;
            }

            if (_handPixelsLeft == null)
            {
                _handPixelsLeft = new byte[DepthWidth * DepthHeight];
            }

            if (_handPixelsRight == null)
            {
                _handPixelsRight = new byte[DepthWidth * DepthHeight];
            }

            Hand handLeft = null;
            Hand handRight = null;

            Joint jointHandLeft = body.Joints[JointType.HandLeft];
            Joint jointHandRight = body.Joints[JointType.HandRight];
            Joint jointWristLeft = body.Joints[JointType.WristLeft];
            Joint jointWristRight = body.Joints[JointType.WristRight];
            Joint jointTipLeft = body.Joints[JointType.HandTipLeft];
            Joint jointTipRight = body.Joints[JointType.HandTipRight];
            Joint jointThumbLeft = body.Joints[JointType.ThumbLeft];
            Joint jointThumbRight = body.Joints[JointType.ThumbRight];

            DepthSpacePoint depthPointHandLeft = CoordinateMapper.MapCameraPointToDepthSpace(jointHandLeft.Position);
            DepthSpacePoint depthPointWristLeft = CoordinateMapper.MapCameraPointToDepthSpace(jointWristLeft.Position);
            DepthSpacePoint depthPointTipLeft = CoordinateMapper.MapCameraPointToDepthSpace(jointTipLeft.Position);
            DepthSpacePoint depthPointThumbLeft = CoordinateMapper.MapCameraPointToDepthSpace(jointThumbLeft.Position);

            DepthSpacePoint depthPointHandRight = CoordinateMapper.MapCameraPointToDepthSpace(jointHandRight.Position);
            DepthSpacePoint depthPointWristRight = CoordinateMapper.MapCameraPointToDepthSpace(jointWristRight.Position);
            DepthSpacePoint depthPointTipRight = CoordinateMapper.MapCameraPointToDepthSpace(jointTipRight.Position);
            DepthSpacePoint depthPointThumbRight = CoordinateMapper.MapCameraPointToDepthSpace(jointThumbRight.Position);

            float handLeftX = depthPointHandLeft.X;
            float handLeftY = depthPointHandLeft.Y;
            float wristLeftX = depthPointWristLeft.X;
            float wristLeftY = depthPointWristLeft.Y;
            float tipLeftX = depthPointTipLeft.X;
            float tipLeftY = depthPointTipLeft.Y;
            float thumbLeftX = depthPointThumbLeft.X;
            float thumbLeftY = depthPointThumbLeft.Y;

            float handRightX = depthPointHandRight.X;
            float handRightY = depthPointHandRight.Y;
            float wristRightX = depthPointWristRight.X;
            float wristRightY = depthPointWristRight.Y;
            float tipRightX = depthPointTipRight.X;
            float tipRightY = depthPointTipRight.Y;
            float thumbRightX = depthPointThumbRight.X;
            float thumbRightY = depthPointThumbRight.Y;

            bool searchForLeftHand = DetectLeftHand && !float.IsInfinity(handLeftX) && !float.IsInfinity(handLeftY) && !float.IsInfinity(wristLeftX) && !float.IsInfinity(wristLeftY) && !float.IsInfinity(tipLeftX) && !float.IsInfinity(tipLeftY) && !float.IsInfinity(thumbLeftX) && !float.IsInfinity(thumbLeftY);
            bool searchForRightHand = DetectRightHand && !float.IsInfinity(handRightX) && !float.IsInfinity(handRightY) && !float.IsInfinity(wristRightX) && !float.IsInfinity(wristRightY) && !float.IsInfinity(tipRightX) && !float.IsInfinity(tipRightY) && !float.IsInfinity(thumbRightX) && !float.IsInfinity(thumbRightY);


            this.fingers = new List<DepthPointEx>();
            if (searchForLeftHand || searchForRightHand)
            {
                double distanceLeft = searchForLeftHand ? CalculateDistance(handLeftX, handLeftY, tipLeftX, tipLeftY, thumbLeftX, thumbLeftY) : 0.0;
                double distanceRight = searchForRightHand ? CalculateDistance(handRightX, handRightY, tipRightX, tipRightY, thumbRightX, thumbRightY) : 0.0;

                double angleLeft = searchForLeftHand ? DepthPointEx.Angle(wristLeftX, wristLeftY, wristLeftX, 0, handLeftX, handLeftY) : 0.0;
                double angleRight = searchForRightHand ? DepthPointEx.Angle(wristRightX, wristRightY, wristRightX, 0, handRightX, handRightY) : 0.0;

                int minLeftX = searchForLeftHand ? (int)(handLeftX - distanceLeft) : 0;
                int minLeftY = searchForLeftHand ? (int)(handLeftY - distanceLeft) : 0;
                int maxLeftX = searchForLeftHand ? (int)(handLeftX + distanceLeft) : 0;
                int maxLeftY = searchForLeftHand ? (int)(handLeftY + distanceLeft) : 0;

                int minRightX = searchForRightHand ? (int)(handRightX - distanceRight) : 0;
                int minRightY = searchForRightHand ? (int)(handRightY - distanceRight) : 0;
                int maxRightX = searchForRightHand ? (int)(handRightX + distanceRight) : 0;
                int maxRightY = searchForRightHand ? (int)(handRightY + distanceRight) : 0;

                float depthLeft = jointHandLeft.Position.Z * 1000; // m to mm
                float depthRight = jointHandRight.Position.Z * 1000;
                
                for (int i = 0; i < DepthWidth * DepthHeight; ++i)
                {
                    ushort depth = data[i];

                    int depthX = i % DepthWidth;
                    int depthY = i / DepthWidth;

                    bool isInBounds = depth >= MIN_DEPTH && depth <= MAX_DEPTH;

                    bool conditionLeft = depth >= depthLeft - DEPTH_THRESHOLD &&
                                         depth <= depthLeft + DEPTH_THRESHOLD &&
                                         depthX >= minLeftX && depthX <= maxLeftX &&
                                         depthY >= minLeftY && depthY <= maxLeftY;

                    bool conditionRight = depth >= depthRight - DEPTH_THRESHOLD &&
                                          depth <= depthRight + DEPTH_THRESHOLD &&
                                          depthX >= minRightX && depthX <= maxRightX &&
                                          depthY >= minRightY && depthY <= maxRightY;

                    _handPixelsLeft[i] = (byte)(isInBounds && searchForLeftHand && conditionLeft ? 255 : 0);
                    _handPixelsRight[i] = (byte)(isInBounds && searchForRightHand && conditionRight ? 255 : 0);
                }

                List<DepthPointEx> contourLeft = new List<DepthPointEx>();
                List<DepthPointEx> contourRight = new List<DepthPointEx>();

                for (int i = 0; i < DepthWidth * DepthHeight; ++i)
                {
                    ushort depth = data[i];

                    int depthX = i % DepthWidth;
                    int depthY = i / DepthWidth;

                    if (searchForLeftHand)
                    {
                        if (_handPixelsLeft[i] != 0)
                        {
                            byte top = i - DepthWidth >= 0 ? _handPixelsLeft[i - DepthWidth] : (byte)0;
                            byte bottom = i + DepthWidth < _handPixelsLeft.Length ? _handPixelsLeft[i + DepthWidth] : (byte)0;
                            byte left = i - 1 >= 0 ? _handPixelsLeft[i - 1] : (byte)0;
                            byte right = i + 1 < _handPixelsLeft.Length ? _handPixelsLeft[i + 1] : (byte)0;

                            bool isInContour = top == 0 || bottom == 0 || left == 0 || right == 0;

                            if (isInContour)
                            {
                                contourLeft.Add(new DepthPointEx { X = depthX, Y = depthY, Z = depth });
                            }
                        }
                    }

                    if (searchForRightHand)
                    {
                        if (_handPixelsRight[i] != 0)
                        {
                            byte top = i - DepthWidth >= 0 ? _handPixelsRight[i - DepthWidth] : (byte)0;
                            byte bottom = i + DepthWidth < _handPixelsRight.Length ? _handPixelsRight[i + DepthWidth] : (byte)0;
                            byte left = i - 1 >= 0 ? _handPixelsRight[i - 1] : (byte)0;
                            byte right = i + 1 < _handPixelsRight.Length ? _handPixelsRight[i + 1] : (byte)0;

                            bool isInContour = top == 0 || bottom == 0 || left == 0 || right == 0;

                            if (isInContour)
                            {
                                contourRight.Add(new DepthPointEx { X = depthX, Y = depthY, Z = depth });
                            }
                        }
                    }
                }

                if (searchForLeftHand)
                {
                    handLeft = GetHand(body.TrackingId, body.HandLeftState, contourLeft, angleLeft, wristLeftX, wristLeftY,false);
                }

                if (searchForRightHand)
                {
                    handRight = GetHand(body.TrackingId, body.HandRightState, contourRight, angleRight, wristRightX, wristRightY,true);
                }
            }

            if (handLeft != null || handRight != null)
            {
                HandCollection hands = new HandCollection
                {
                    TrackingId = body.TrackingId,
                    HandLeft = handLeft,
                    HandRight = handRight
                };

                if (HandsDetected != null)
                {
                    HandsDetected(this, hands);
                }
            }
        }