// add isGhost!
        public Person(SkeletonWrapper skeletonData, Color c, bool isGhost)
        {
            hashCode = HASH_CODE;
            HASH_CODE += 1;

            this.skeletonData = skeletonData;
            this.isGhost = isGhost;

            // Retrieve hand data.
            Joint rightHand = skeletonData.getRightHandJoint();
            Joint leftHand = skeletonData.getLeftHandJoint();

            // Retrieve torso data.
            if (isGhost == false)
            {
                Joint shoulderCenter = skeletonData.getCenterShoulderJoint();
                Joint spine = skeletonData.getSpineJoint();

                torsoTop = shoulderCenter.Position;
                torsoBottom = spine.Position;
            }

            leftHandPosition = leftHand.Position;
            rightHandPosition = rightHand.Position;

            this.color = c;

            canSpawnBoids = true;

            this.rightHand = new Hand(rightHand);
            this.leftHand = new Hand(leftHand);
        }
        public SpawnTutorial(DaVinciExhibit stateMachine)
            : base(stateMachine)
        {
            ghostSkeleton = new SkeletonWrapper();

            ghostSkeleton.setHeadJoint(-.2, .4, 2.0);
            ghostSkeleton.setRightShoulderJoint(-.08, .105, 2.0);
            ghostSkeleton.setLeftShoulderJoint(-.350, .095, 2.0);
            ghostSkeleton.setRightFootJoint(-.005, -.905, 1.550);
            ghostSkeleton.setLeftFootJoint(-.325, -.927, 1.550);
            ghostSkeleton.setRightHandJoint(.25, .1, 2.0);
            ghostSkeleton.setLeftHandJoint(-.25, .1, 2.0);
        }
        public void Update(SkeletonWrapper skeleton, int userID)
        {
            stopwatch.Stop();
            long frameTimestamp = stopwatch.ElapsedMilliseconds;

            if (skeleton != null)
            {
                    if (skeleton.getTrackingState() == SkeletonTrackingState.Tracked)
                    {
                        // Check the state of the user's left and right hands to determine the relation of each to a
                        // wave gesture.
                        TrackWave(skeleton, userID, ref this.playerWaveTracker[userID], frameTimestamp);
                    }
                    // If we can't track the user's motions we'll have to reset our data on them;
                    // they may have left and will be replaced by another user.
                    else
                    {
                        this.playerWaveTracker[userID].Reset();
                    } // end if-else

                }

            stopwatch.Start();
        }
        private Person updatePerson(SkeletonWrapper skeletonWrap, Person person, bool isGhost)
        {
            // Retrieve hand data.
            Joint rightHand = skeletonWrap.getRightHandJoint();
            Joint leftHand = skeletonWrap.getLeftHandJoint();

            // Store retrieved data.
            if (person == null)
            {
                person = new Person(skeletonWrap, isGhost);
            }
            else
            {
                person.updateSkeletonData(skeletonWrap);
            }

            person.rightHandLocation = this.kinectSensor.CoordinateMapper.MapSkeletonPointToDepthPoint(person.rightHandPosition, this.kinectSensor.DepthStream.Format);
            person.leftHandLocation = this.kinectSensor.CoordinateMapper.MapSkeletonPointToDepthPoint(person.leftHandPosition, this.kinectSensor.DepthStream.Format);

            //fileWriter.writeLine(file, timestamp, x, y, z)

            person.setRightHandRadius(person.rightHandLocation.Depth / 60);
            person.setLeftHandRadius(person.leftHandLocation.Depth / 60);

            Button b;
            for (int x = 0; x < buttonsCollection.Count; x++)
            {
                b = (Button)buttonsCollection[x];

                if (b != null)
                {
                    b.UpdateHands(users);
                }
            }

            //if (tutorialButton != null)
            //{
              //  tutorialButton.UpdateHands(users);
            //}

            // Update user color.
            if (isGhost == false)
            {
                updateUserColor(person);
            }

            // Update the gesture detectors of the user's physical state.
            //waveGestureDetector.Update(playerSkeleton, i);
            scissorGestureDetector.update(person);
            pressGestureDetector.Update(person);

            return person;
        }
        void kinectSensor_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
            {
                if (skeletonFrame != null)
                {
                    Skeleton[] skeletonData = new Skeleton[skeletonFrame.SkeletonArrayLength];

                    int i = 0; // Defines the number of users that we have extracted data from.

                    skeletonFrame.CopySkeletonDataTo(skeletonData);

                    Person currPerson;
                    foreach (Skeleton playerSkeleton in skeletonData)
                    {
                        if (playerSkeleton != null && playerSkeleton.TrackingState == SkeletonTrackingState.Tracked)
                        {
                            // Wrap the Skelton
                            SkeletonWrapper skeletonWrap = new SkeletonWrapper(playerSkeleton);

                            currPerson = users[i];

                            users[i] = updatePerson(skeletonWrap, currPerson, false);

                            long timestamp = stopwatch.ElapsedMilliseconds;
                            SkeletonPoint right = users[i].rightHandPosition;
                            SkeletonPoint left = users[i].leftHandPosition;
                            //rightWriter.writeLine(timestamp, right.X, right.Y, right.Z);
                            //leftWriter.writeLine(timestamp, left.X, left.Y, left.Z);

                            i++;
                        } // end if
                    } // end foreach

                    // add the ghosts

                    for (int inactiveUser = (i + 1); inactiveUser < users.Length; inactiveUser++)
                    {
                        users[inactiveUser] = null;
                    }

                    //// Deactivate all unused hands
                    //for (int k = j + 1; j < userHands.Count(); j++)
                    //{
                    //    if (userHands[k] != null)
                    //    {
                    //        userHands[k].NotActive();
                    //    }
                    //}
                } // end if
            } // end using
        }
        public void updateGhost(SkeletonWrapper skel)
        {
            if (skel == null)
            {
                ghostUser = null;
                return;
            }

            if (ghostUser == null)
            {
                ghostUser = new Person(skel, GHOST_USER_COLOR, true);
            }

            updatePerson(skel, ghostUser, true);
        }
 public Person(SkeletonWrapper skeletonData,  bool isGhost)
     : this(skeletonData, new Color(), isGhost)
 {
 }
        public void updateSkeletonData(SkeletonWrapper skel)
        {
            skeletonData = skel;

            Joint tempLeftHand, tempRightHand;
            tempLeftHand = skeletonData.getLeftHandJoint();
            tempRightHand = skeletonData.getRightHandJoint();

            this.leftHand.Update(tempLeftHand);
            this.rightHand.Update(tempRightHand);

            leftHandPosition = tempLeftHand.Position;
            rightHandPosition = tempRightHand.Position;
        }
        private void TrackWave(SkeletonWrapper skeleton, int userID, ref WaveGestureTracker tracker, long timestamp)
        {
            // The check for a user wave in this implementation is fairly simple. If the user raises their hand directly above their
            // shoulder then they are merely primed for a wave. If they raise it above and to the left or right of their shoulder,
            // or if they move that hand left or right after having primed it, then we count that as a wave. For such an implementation
            // the WaveGestureState is not genuinley necessary however if we choose to change our approach (eg, require three motions to
            // constitute a valid wave) then the use of this struct will render these changes much simpler.

            // Retrieve the relevent hand and shoulder for the user depending on which hand/shoulder pair that we
            // are checking for a wave.
            Joint leftHand = skeleton.getLeftHandJoint();
            Joint rightHand = skeleton.getRightHandJoint();

            Joint centerOfShoulders = skeleton.getCenterShoulderJoint();

            // Metric measurement
            double distanceBetweenHandsSq = (Math.Pow(leftHand.Position.X - rightHand.Position.X, 2) + Math.Pow(leftHand.Position.Y - rightHand.Position.Y, 2));

            // If the user joints are tracked...
            if (leftHand.TrackingState == JointTrackingState.Tracked && rightHand.TrackingState == JointTrackingState.Tracked)
            {
                // If the user is not taking forever...
                if (tracker.State == WaveGestureState.InProgress && tracker.Timestamp + WAVE_MOVEMENT_TIMEOUT < timestamp)
                {
                    tracker.UpdateState(WaveGestureState.Failure, timestamp);
                }
                // If the user's hands are overlapping...
                else if (distanceBetweenHandsSq <= HAND_DISTANCE_THRESHHOLD_SQ)
                {
                    // If the user is waving to the left...
                    // (We assume that, through the act of overlapping their hands, users will naturally center their hands over their torso.)
                    if (leftHand.Position.X < (centerOfShoulders.Position.X + WAVE_THRESHOLD))
                    {
                        tracker.UpdatePosition(WavePosition.Left, timestamp);
                    }
                    // Check if the user is waving to the right...
                    else if (leftHand.Position.X > (centerOfShoulders.Position.X - WAVE_THRESHOLD))
                    {
                        tracker.UpdatePosition(WavePosition.Right, timestamp);
                    }
                    else
                    {
                        tracker.UpdatePosition(WavePosition.Neutral, timestamp);
                    } // end if-else if-else

                    // If the user has not yet achieved a wave but have satisfied the number of wave iterations...
                    if (tracker.State != WaveGestureState.Success && tracker.IterationCount == REQUIRED_ITERATIONS)
                    {
                        // Then they're waving.
                        tracker.UpdateState(WaveGestureState.Success, timestamp);

                        // If we have observers...
                        if (GestureDetected != null)
                        {
                            // Notify them and let them know which direction the user waved and with which hand they waved.
                            GestureDetected(this, new WaveGestureEventArgs(userID));
                        } // end if

                    } // end if

                }
                else
                {
                    if (tracker.State == WaveGestureState.InProgress)
                    {
                        tracker.UpdateState(WaveGestureState.Failure, timestamp);
                    }
                    else
                    {
                        tracker.Reset();
                    } // end if-else
                } // end if-else if-else
            } // end if
        }