using BBIWARG.Recognition.Tracking;
using BBIWARG.Utility;
using System;
namespace BBIWARG.Recognition.TouchRecognition
{
///
/// signature of the touchEvent event
///
/// the event sender
/// the touch event
public delegate void TouchEventHandler(object sender, TouchEvent e);
///
/// Represents a touch that is tracked for several frames
///
public class TrackedTouch : TrackedObject
{
///
/// the kalman filter for the absolute position prediction
///
private Kalman2DPositionFilter absolutePositionKalman;
///
/// the prediction of the absolute position
///
public Vector2D AbsolutePositionPrediction { get { return absolutePositionKalman.getPrediction(); } }
///
/// the track ID of the touching finger
///
public int FingerID { get; private set; }
///
/// indicates if the touch is currently active
///
public bool IsTouchActive { get; private set; }
///
/// the optimized touch (using the predicted absolute position)
///
public Touch OptimizedTouch { get; private set; }
///
/// the event which is fired, if a touchEvent occurs
///
public event TouchEventHandler TouchEvent;
///
/// Initializes a new instance of the TrackedTouch class.
///
/// The track ID.
/// The detected touch.
/// The number of consecutive frames detected until the touch is considered to be tracked (touchDown).
/// The number of consecutive frames lost until the touch is deleted (touchUp).
public TrackedTouch(int id, Touch detectedTouch, int numFramesDetectedUntilTracked, int numFramesLostUntilDeleted)
: base(id, detectedTouch, numFramesDetectedUntilTracked, numFramesLostUntilDeleted)
{
absolutePositionKalman = new Kalman2DPositionFilter(Parameters.TouchmXX, Parameters.TouchmXY, Parameters.TouchmYY);
absolutePositionKalman.setInitialPosition(detectedTouch.AbsolutePosition);
FingerID = detectedTouch.Finger.TrackID;
IsTouchActive = false;
logStateChange();
}
///
/// Updates the tracked touch, logs the state change, updates the optimized touch and the absolute position prediction and triggers touch events.
///
/// the detected touch
public override void updateFrame(Touch detectedTouch)
{
base.updateFrame(detectedTouch);
if (NumFramesInCurrentState == 1)
logStateChange();
if (detectedTouch != null)
{
absolutePositionKalman.getCorrectedPosition(detectedTouch.AbsolutePosition);
updateOptimizedTouch(detectedTouch);
if (CurrentState == TrackingState.Tracked)
{
if (!IsTouchActive)
TriggerTouchDown();
else
TriggerTouchMove();
}
}
else if (IsTouchActive && CurrentState == TrackingState.Deleted)
TriggerTouchUp();
}
///
/// logs the state change
///
private void logStateChange()
{
String stateAsString = CurrentState.ToString().ToLower();
Logger.log(String.Format("Touch #{0} {1}", this.ID, stateAsString), LogSubject.TouchTracker);
}
///
/// Fires a touch event with type = down
///
private void TriggerTouchDown()
{
if (TouchEvent != null)
{
IsTouchActive = true;
TouchEvent(this, new TouchEvent(TouchEventType.Down, OptimizedTouch));
}
}
///
/// Fires a touch event with type = move
///
private void TriggerTouchMove()
{
if (TouchEvent != null)
{
TouchEvent(this, new TouchEvent(TouchEventType.Move, OptimizedTouch));
}
}
///
/// Fires a touch event with type = up
///
private void TriggerTouchUp()
{
if (TouchEvent != null)
{
IsTouchActive = false;
TouchEvent(this, new TouchEvent(TouchEventType.Up, OptimizedTouch));
}
}
///
/// Updates the optimized touch using the absolute position prediction
///
/// the detected touch
private void updateOptimizedTouch(Touch detectedTouch)
{
OptimizedTouch = new Touch(AbsolutePositionPrediction, detectedTouch.Finger, detectedTouch.Palm);
OptimizedTouch.setTracked(ID);
}
}
}