Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
GestureRecognizer.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 
4 using System;
5 using System.Collections.Generic;
6 
7 using SiliconStudio.Core.Mathematics;
8 
9 namespace SiliconStudio.Paradox.Input
10 {
11  internal abstract class GestureRecognizer
12  {
13  protected virtual GestureConfig Config { get; private set; }
14 
15  protected List<GestureEvent> CurrentGestureEvents = new List<GestureEvent>();
16 
17  protected readonly Dictionary<int, Vector2> FingerIdToBeginPositions = new Dictionary<int, Vector2>();
18 
19  protected readonly Dictionary<int, Vector2> FingerIdsToLastPos = new Dictionary<int, Vector2>();
20 
21  protected TimeSpan ElapsedSinceBeginning;
22  protected TimeSpan ElapsedSinceLast;
23 
24  private readonly static List<int> FingerIdsCache = new List<int>();
25 
26  protected bool HasGestureStarted
27  {
28  get { return hasGestureStarted; }
29  set
30  {
31  if (value && !hasGestureStarted)
32  {
33  ElapsedSinceBeginning = TimeSpan.Zero;
34  ElapsedSinceLast = TimeSpan.Zero;
35  }
36 
37  hasGestureStarted = value;
38  }
39  }
40  private bool hasGestureStarted;
41 
42  protected virtual int NbOfFingerOnScreen
43  {
44  get { return FingerIdsToLastPos.Count; }
45  }
46 
47  internal float ScreenRatio { get; set; }
48 
49  protected GestureRecognizer(GestureConfig config, float screenRatio)
50  {
51  Config = config;
52  ScreenRatio = screenRatio;
53  }
54 
55  public List<GestureEvent> ProcessPointerEvents(TimeSpan deltaTime, List<PointerEvent> events)
56  {
57  CurrentGestureEvents.Clear();
58 
59  ElapsedSinceBeginning += deltaTime;
60  ElapsedSinceLast += deltaTime;
61 
62  ProcessPointerEventsImpl(deltaTime, events);
63 
64  return CurrentGestureEvents;
65  }
66 
67  protected virtual void ProcessPointerEventsImpl(TimeSpan deltaTime, List<PointerEvent> events)
68  {
69  AnalysePointerEvents(events);
70  }
71 
72  protected Vector2 ComputeMeanPosition(IEnumerable<Vector2> positions)
73  {
74  var count = 0;
75  var accuPos = Vector2.Zero;
76  foreach (var position in positions)
77  {
78  accuPos += position;
79  ++count;
80  }
81 
82  return accuPos / count;
83  }
84 
85  // avoid reallocation of the dictionary at each update call
86  private readonly Dictionary<int, Vector2> fingerIdsToLastMovePos = new Dictionary<int, Vector2>();
87 
88  protected void AnalysePointerEvents(List<PointerEvent> events)
89  {
90  foreach (var pointerEvent in events)
91  {
92  var state = pointerEvent.State;
93  var id = pointerEvent.PointerId;
94  var pos = pointerEvent.Position;
95 
96  switch (state)
97  {
98  case PointerState.Down:
99  ProcessDownEventPointer(id, UnnormalizeVector(pos));
100  break;
101  case PointerState.Move:
102  // just memorize the last position to avoid useless processing on move events
103  fingerIdsToLastMovePos[id] = pos;
104  break;
105  case PointerState.Up:
106  case PointerState.Out:
107  case PointerState.Cancel:
108  // process previous move events
109  ProcessAndClearMovePointerEvents();
110 
111  // process the up event
112  ProcessUpEventPointer(id, UnnormalizeVector(pos));
113  break;
114  default:
115  throw new ArgumentOutOfRangeException();
116  }
117  }
118 
119  // process move events not followed by an 'up' event
120  ProcessAndClearMovePointerEvents();
121  }
122 
123  protected Vector2 NormalizeVector(Vector2 inputVector)
124  {
125  return ScreenRatio > 1 ?
126  new Vector2(inputVector.X, inputVector.Y * ScreenRatio) :
127  new Vector2(inputVector.X / ScreenRatio, inputVector.Y);
128  }
129 
130  protected Vector2 UnnormalizeVector(Vector2 inputVector)
131  {
132  return ScreenRatio > 1 ?
133  new Vector2(inputVector.X, inputVector.Y / ScreenRatio) :
134  new Vector2(inputVector.X * ScreenRatio, inputVector.Y);
135  }
136 
137  private void ProcessAndClearMovePointerEvents()
138  {
139  if (fingerIdsToLastMovePos.Count > 0)
140  {
141  FingerIdsCache.Clear();
142  FingerIdsCache.AddRange(fingerIdsToLastMovePos.Keys);
143 
144  // Unnormalizes vectors here before utilization
145  foreach (var id in FingerIdsCache)
146  fingerIdsToLastMovePos[id] = UnnormalizeVector(fingerIdsToLastMovePos[id]);
147 
148  ProcessMoveEventPointers(fingerIdsToLastMovePos);
149  fingerIdsToLastMovePos.Clear();
150  }
151  }
152 
153  protected abstract void ProcessDownEventPointer(int id, Vector2 pos);
154 
155  protected abstract void ProcessMoveEventPointers(Dictionary<int, Vector2> fingerIdsToMovePos);
156 
157  protected abstract void ProcessUpEventPointer(int id, Vector2 pos);
158  }
159 }
SiliconStudio.Paradox.Games.Mathematics.Vector2 Vector2
Represents a two dimensional mathematical vector.
Definition: Vector2.cs:42
Keys
Enumeration for keys.
Definition: Keys.cs:8
_In_ size_t count
Definition: DirectXTexP.h:174
float Y
The Y component of the vector.
Definition: Vector2.cs:79
float X
The X component of the vector.
Definition: Vector2.cs:73