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); } } }