/*
* This file is part of the TraKERS\Middleware package.
*
* (c) IRI <http://www.iri.centrepompidou.fr/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/*
* Projet : TraKERS
* Module : MIDDLEWARE
* Sous-Module : Tracking/Gestures
* Classe : WaveDetector
*
* Auteur : alexandre.bastien@iri.centrepompidou.fr
*
* Fonctionnalités : Permet de détecter si l'utilisateur a effectué un wave, en se basant sur
* des règles appliquées à la positions des noeuds dans le temps.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Kinect;
using Trakers.Debug;
namespace Trakers.Tracking.Gestures
{
public class WaveDetector : GestureDetector
{
public WaveDetector(DebugWindow _debug) : base(_debug)
{
//Temps de gesture maximum.
gesturePeriod = (float)2;
indexesPerSecond = 30;
indexesToCheck = (int)(gesturePeriod * indexesPerSecond);
}
/*
* Méthode de détection de wave
*/
public bool CheckForWave()
{
//Crée un historique de squelette local, puisque l'historique est mis à jour toutes les ~1/30 s.
List<List<Joint>> localHistory = new List<List<Joint>>(history);
//Si il n'y a pas assez de positions dans l'historique local pour vérifier le geste.
if (localHistory.Count < indexesToCheck)
return false;
//La distance de référence est ici la distance entre le milieu du dos et le milieu des épaules.
float refDistance = Math.Abs(localHistory[0][(int)JointType.Spine].Position.Y - localHistory[0][(int)JointType.ShoulderCenter].Position.Y);
//On commence la position pour les indexesToCheck dernières postures (celle à l'index 0 étant la dernière).
float startPosX = localHistory[localHistory.Count - indexesToCheck][(int)JointType.HandRight].Position.X;
bool movedRight = false;
//De la position p1 à pn, on suit l'algorithme.
for (int i = localHistory.Count - indexesToCheck + 1; i < localHistory.Count; i++)
{
/*if (localHistory[i][(int)JointType.HandRight].Position.Y + refDistance / 2 > localHistory[i][(int)JointType.ElbowRight].Position.Y)
debug.onR0(false);
else
debug.onR0(true);
if (localHistory[i][(int)JointType.HandRight].Position.Y > localHistory[i][(int)JointType.HipCenter].Position.Y)
debug.onR1(false);
else
debug.onR1(true);
if (localHistory[i][(int)JointType.HandRight].Position.Y > localHistory[i][(int)JointType.WristRight].Position.Y)
debug.onR2(false);
else
debug.onR2(true);
if (Math.Abs(localHistory[i][(int)JointType.HandRight].Position.Z - localHistory[i][(int)JointType.Head].Position.Z) > 0.20)
debug.onR3(false);
else
debug.onR3(true);*/
//Si la position Y de la main droite est plus haute que le coude + la distance de référence
//OU si la position Y de la main droite est plus basse que la hanche
//OU si la position Y de la main droite est plus haute que le poignet + le quart de la distance de référence
//OU si la distance Y de la main à la tete est plus grande que la distance de référence
//OU si la distance Z de la main à la tete est plus grande que 20 cm.
//Alors la main en question ne fait pas de Wave.
if (localHistory[i][(int)JointType.HandRight].Position.Y + refDistance / 2 > localHistory[i][(int)JointType.ElbowRight].Position.Y ||
localHistory[i][(int)JointType.HandRight].Position.Y > localHistory[i][(int)JointType.HipCenter].Position.Y ||
localHistory[i][(int)JointType.HandRight].Position.Y > localHistory[i][(int)JointType.WristRight].Position.Y ||
Math.Abs(localHistory[i][(int)JointType.HandRight].Position.Z - localHistory[i][(int)JointType.Head].Position.Z) > 0.20)
return false;
//On vérifie si la main à bougé vers la droite.
if (localHistory[i][(int)JointType.HandRight].Position.X >= startPosX + refDistance / 2 && !movedRight)
movedRight = true;
//Si la main a bougé vers la droite, on regarde si elle est retournée à sa position initiale.
if (movedRight && Math.Abs(localHistory[i][(int)JointType.HandRight].Position.X - startPosX) <= refDistance)
{
history.Clear();
return true;
}
}
return false;
}
}
}