private void TrackEngagedPlayersViaHandOverHead() { this.engagementPeopleHaveChanged = false; var currentlyEngagedHands = KinectCoreWindow.KinectManualEngagedHands; this.handsToEngage.Clear(); // check to see if anybody who is currently engaged should be disengaged foreach (var bodyHandPair in currentlyEngagedHands) { var bodyTrackingId = bodyHandPair.BodyTrackingId; foreach (var body in this.bodies) { if (body.TrackingId == bodyTrackingId) { // check for disengagement JointType engagedHandJoint = (bodyHandPair.HandType == HandType.LEFT) ? JointType.HandLeft : JointType.HandRight; bool toBeDisengaged = HandOverheadEngagementModel.IsHandBelowHip(engagedHandJoint, body); if (toBeDisengaged) { this.engagementPeopleHaveChanged = true; } else { this.handsToEngage.Add(bodyHandPair); } } } } // check to see if anybody should be engaged, if not already engaged foreach (var body in this.bodies) { if (this.handsToEngage.Count < this.engagedPeopleAllowed) { bool alreadyEngaged = false; foreach (var bodyHandPair in this.handsToEngage) { alreadyEngaged = (body.TrackingId == bodyHandPair.BodyTrackingId); } if (!alreadyEngaged) { // check for engagement if (HandOverheadEngagementModel.IsHandOverhead(JointType.HandLeft, body)) { // engage the left hand this.handsToEngage.Add( new BodyHandPair(body.TrackingId, HandType.LEFT)); this.engagementPeopleHaveChanged = true; } else if (HandOverheadEngagementModel.IsHandOverhead(JointType.HandRight, body)) { // engage the right hand this.handsToEngage.Add( new BodyHandPair(body.TrackingId, HandType.RIGHT)); this.engagementPeopleHaveChanged = true; } } } } if (this.engagementPeopleHaveChanged) { BodyHandPair firstPersonToEngage = null; BodyHandPair secondPersonToEngage = null; Debug.Assert(this.handsToEngage.Count <= 2, "handsToEngage should be <= 2"); switch (this.handsToEngage.Count) { case 0: break; case 1: firstPersonToEngage = this.handsToEngage[0]; break; case 2: firstPersonToEngage = this.handsToEngage[0]; secondPersonToEngage = this.handsToEngage[1]; break; } switch (this.EngagedPeopleAllowed) { case 1: KinectCoreWindow.SetKinectOnePersonManualEngagement(firstPersonToEngage); break; case 2: KinectCoreWindow.SetKinectTwoPersonManualEngagement(firstPersonToEngage, secondPersonToEngage); break; } } }
/// <summary> /// Méthode déclenchée ~30 fois par seconde par Kinect. On y trouve les infos mise à jour relatives à la position des mains/curseur kinect /// </summary> /// <param name="sender">L'objet appelant</param> /// <param name="e">Les paramètres d'une frame de body</param> private void MainWindow_PointerMoved(object sender, KinectPointerEventArgs e) { #region Méthode d'engagement "Dans l'écran" //On définit qui a l'autorité sur le pointeur (quelle main est engagée) //Celui dont la main est dans l'écran est engagé if (KinectCoreWindow.KinectManualEngagedHands.Count == 0) //Personne n'est engagé { if (IsInScreen(e.CurrentPoint.Properties.UnclampedPosition)) //Vérifie que le point est sur l'écran { KinectCoreWindow.SetKinectOnePersonManualEngagement(new BodyHandPair(e.CurrentPoint.Properties.BodyTrackingId, e.CurrentPoint.Properties.HandType)); (this.Resources["CursorShow"] as Storyboard).Begin(); //On affiche le pointeur } else { this.lastPoint = null; } } else //Une personne est engagée { //Vérifie si on doit désengager-- if (!IsInScreen(e.CurrentPoint.Properties.UnclampedPosition, 0.2f) && // si le point est en dehors de l'écran (avec une tolérance de 0.2, on peut sortir un peu de l'écran et dessiner) et que e.CurrentPoint.Properties.IsEngaged) // celui-ci est engagé { KinectCoreWindow.SetKinectOnePersonManualEngagement(null); this.lastPoint = null; (this.Resources["CursorHide"] as Storyboard).Begin(); //On cache le pointeur } } #endregion KinectPointerPoint kinectPoint = e.CurrentPoint; if (kinectPoint.Properties.IsEngaged) //On ne peut dessiner que si le point est engagé { //Vérification Dessin - Choix de couleur switch (isPanelOpen) { case true: //On doit choisir la couleur Canvas.SetLeft(colorChoicePanel, kinectPoint.Position.X * colorChoicePanel.ActualWidth - colorChoicePanel.ActualWidth); this.UsedBrush = this.colorBrushes[this.colorBrushes.Count - 1 - (int)Math.Floor(kinectPoint.Position.X * this.colorBrushes.Count)]; this.lastPoint = null; break; case false: //On doit dessiner //Diamètre du cercle changeant avec la pression double diameter = 30; diameter = diameter * Math.Pow(kinectPoint.Properties.HandReachExtent + 0.5, 3); //On modifie la position du curseur double posX = Math.Max(e.CurrentPoint.Properties.UnclampedPosition.X, 0); posX = Math.Min(posX, 1); // Position relative 0->1 compris posX *= this.drawCanvas.ActualWidth; posX -= diameter / 2; double posY = Math.Max(e.CurrentPoint.Properties.UnclampedPosition.Y, 0); posY = Math.Min(posY, 1); // Position relative 0->1 compris posY *= this.drawCanvas.ActualHeight; posY -= diameter / 2; //On modifie le curseur this.cursorInfo.PosX = posX; this.cursorInfo.PosY = posY; this.cursorInfo.Diameter = diameter; #region Dessin //Les deux possition à dessiner if (kinectPoint.Properties.HandReachExtent > 0.5) // Plus que 50 cm de l'épaule { if (lastPoint != null) //On ne dessine une ligne que si on connait le dernier point { //Création d'une nouvelle ligne Line line = new Line() { //Premier point à partir du dernier point X1 = this.lastPoint.Value.X + diameter / 2, Y1 = this.lastPoint.Value.Y + diameter / 2, //Deuxième point à partir du point courant X2 = posX + diameter / 2, Y2 = posY + diameter / 2, //Design de la ligne StrokeThickness = diameter, //Largeur de la ligne Stroke = this.UsedBrush, //La couleur de la ligne StrokeStartLineCap = PenLineCap.Round, //Ligne dont les deux côtés sont rond StrokeEndLineCap = PenLineCap.Round }; //Ajout de la ligne drawCanvas.Children.Add(line); } //Update the last position this.lastPoint = new Point(posX, posY); } else { //Si on est moins que 0.5cm, on met le dernier point à null pour ne plus dessiner this.lastPoint = null; } #endregion //----Dessin break; } } }
private void TrackEngagedPlayersViaHandInScreen() { if (this.stopped) { return; } this.engagementPeopleHaveChanged = false; var currentlyEngagedHands = KinectCoreWindow.KinectManualEngagedHands; this.handsToEngage.Clear(); foreach (var bodyHandPair in currentlyEngagedHands) { foreach (var kinectPointerPoint in this.pointerPoints) { if (kinectPointerPoint.Properties.BodyTrackingId == bodyHandPair.BodyTrackingId && kinectPointerPoint.Properties.HandType == bodyHandPair.HandType) { bool toBeDisengaged = this.IsHandBelowScreen(kinectPointerPoint.Properties.UnclampedPosition, kinectPointerPoint.PointerId); if (toBeDisengaged) { this.engagementPeopleHaveChanged = true; } else { this.handsToEngage.Add(bodyHandPair); } } } } foreach (var kinectPointerPoint in this.pointerPoints) { if (this.handsToEngage.Count < this.engagedPeopleAllowed) { bool alreadyEngaged = false; foreach (var bodyHandPair in this.handsToEngage) { alreadyEngaged = (kinectPointerPoint.Properties.BodyTrackingId == bodyHandPair.BodyTrackingId); } if (!alreadyEngaged) { if (HandInScreenEngagementModel.IsHandInScreen(kinectPointerPoint.Properties.UnclampedPosition)) { this.handsToEngage.Add( new BodyHandPair(kinectPointerPoint.Properties.BodyTrackingId, kinectPointerPoint.Properties.HandType)); this.engagementPeopleHaveChanged = true; } } } } if (this.engagementPeopleHaveChanged) { BodyHandPair firstPersonToEngage = null; BodyHandPair secondPersonToEngage = null; Debug.Assert(this.handsToEngage.Count <= 2, "handsToEngage should be <= 2"); switch (this.handsToEngage.Count) { case 0: break; case 1: firstPersonToEngage = this.handsToEngage[0]; break; case 2: firstPersonToEngage = this.handsToEngage[0]; secondPersonToEngage = this.handsToEngage[1]; break; } switch (this.EngagedPeopleAllowed) { case 0: case 1: KinectCoreWindow.SetKinectOnePersonManualEngagement(firstPersonToEngage); break; case 2: KinectCoreWindow.SetKinectTwoPersonManualEngagement(firstPersonToEngage, secondPersonToEngage); break; } } }
/// <summary> /// Méthode appelée lorsque le pointeur kinect, c'est à dire la main, a bougé. /// </summary> /// <param name="sender">L'objet appelant</param> /// <param name="e">Les arguments de l'évenements</param> private void KinectPowerPoint_PointerMoved(object sender, KinectPointerEventArgs e) { KinectPointerPoint point = e.CurrentPoint; //On vérifie si on doit afficher le pointeur---- if (this.slideShow != null) { lock (this.pointerLock) { if (this.pointer != null) { #region Engagement "tendre le bras" avec HandReachExtent //* if (KinectCoreWindow.KinectManualEngagedHands.Count == 0) //On vérifie que personne n'est engagé { //Quand on montre du doigt, le doigt est a une certaine distance du coude. On peut l'utiliser pour activer le pointeur if (point.Properties.HandReachExtent > FLT_POINTER_DISTANCE_ENGAGEMENT) { this.pointer.Visible = Office.MsoTriState.msoTrue; KinectCoreWindow.SetKinectOnePersonManualEngagement(new BodyHandPair(point.Properties.BodyTrackingId, point.Properties.HandType)); } } else //Si une personne est engagée, on peut peut-être la désengager { if (point.Properties.IsEngaged) //Le point courant doit être engagé pour désengager { if (point.Properties.HandReachExtent <= FLT_POINTER_DISTANCE_DISENGAGEMENT) { KinectCoreWindow.SetKinectOnePersonManualEngagement(null); this.pointer.Visible = Office.MsoTriState.msoFalse; } } } //*/ //Change la position du curseur en fonction de la position des mains if (KinectCoreWindow.KinectManualEngagedHands.Count > 0 && point.Properties.IsEngaged && this.pointer != null) { PointF position = point.Properties.UnclampedPosition; RectF size = new RectF { X = 0, Y = 0, Width = this.Application.ActivePresentation.SlideMaster.Width, Height = this.Application.ActivePresentation.SlideMaster.Height }; //This.pointer == null -> Problème de thread ? :/ this.pointer.Left = Math.Min(Math.Max(position.X * size.Width, size.X), size.Width - this.pointer.Width); this.pointer.Top = Math.Min(Math.Max(position.Y * size.Height, size.Y), size.Height - this.pointer.Height); this.pointer.Visible = Office.MsoTriState.msoTrue; } #endregion } } #region méthode d'engagement "Dans l'écran" //On définit qui a l'autorité sur le pointeur (quelle main est engagée) //Celui dont la main est dans l'écran est engagé /*if(KinectCoreWindow.KinectManualEngagedHands.Count == 0) //Personne n'est engagé * { * if(isInScreen(e.CurrentPoint.Properties.UnclampedPosition)) //Vérifie que le point est sur l'écran * { * KinectCoreWindow.SetKinectOnePersonManualEngagement(new BodyHandPair(e.CurrentPoint.Properties.BodyTrackingId, e.CurrentPoint.Properties.HandType)); * Debug.WriteLine("Engagé"); * } * } * else //Une personne est engagée * { * //Vérifie si on doit désengager-- * * if(!isInScreen(e.CurrentPoint.Properties.UnclampedPosition) && // si le point est en dehors de l'écran et que * e.CurrentPoint.Properties.IsEngaged) // celui-ci est engagé * { * KinectCoreWindow.SetKinectOnePersonManualEngagement(null); * Debug.WriteLine("Désengagé"); * } * }*/ #endregion } }