|
@@ -82,6 +82,9 @@ export class PointerTracker implements Tracker
|
82
|
82
|
/** new pointers */
|
83
|
83
|
private _newPointers: Map<number, TrackablePointer>;
|
84
|
84
|
|
|
85
|
+ /** helper map for normalizing IDs */
|
|
86
|
+ private _idMap: Map<number, number>;
|
|
87
|
+
|
85
|
88
|
/** previous output */
|
86
|
89
|
private _previousOutput: PointerTrackerOutput;
|
87
|
90
|
|
|
@@ -91,6 +94,9 @@ export class PointerTracker implements Tracker
|
91
|
94
|
/** helper flag */
|
92
|
95
|
private _wantToReset: boolean;
|
93
|
96
|
|
|
97
|
+ /** auto-increment ID */
|
|
98
|
+ private _nextId: number;
|
|
99
|
+
|
94
|
100
|
|
95
|
101
|
|
96
|
102
|
/**
|
|
@@ -102,6 +108,8 @@ export class PointerTracker implements Tracker
|
102
|
108
|
this._viewport = null;
|
103
|
109
|
this._activePointers = new Map();
|
104
|
110
|
this._newPointers = new Map();
|
|
111
|
+ this._idMap = new Map();
|
|
112
|
+ this._nextId = 1;
|
105
|
113
|
this._previousOutput = this._generateOutput();
|
106
|
114
|
this._previousUpdateTime = Number.POSITIVE_INFINITY;
|
107
|
115
|
this._wantToReset = false;
|
|
@@ -161,6 +169,7 @@ export class PointerTracker implements Tracker
|
161
|
169
|
this._viewport = null;
|
162
|
170
|
this._activePointers.clear();
|
163
|
171
|
this._newPointers.clear();
|
|
172
|
+ this._idMap.clear();
|
164
|
173
|
|
165
|
174
|
document.removeEventListener('visibilitychange', this._resetInTheNextUpdate);
|
166
|
175
|
|
|
@@ -210,9 +219,7 @@ export class PointerTracker implements Tracker
|
210
|
219
|
return Speedy.Promise.reject(new IllegalOperationError('Invalid PointerEvent type ' + event.type));
|
211
|
220
|
|
212
|
221
|
// determine the ID
|
213
|
|
- // XXX different hardware devices acting simultaneously may produce
|
214
|
|
- // events with the same pointerId - handling this seems overkill?
|
215
|
|
- const id = event.pointerId;
|
|
222
|
+ const id = this._normalizeId(event.pointerId, event.pointerType);
|
216
|
223
|
|
217
|
224
|
// determine the previous states, if any, of the trackable
|
218
|
225
|
const previous = this._activePointers.get(id); // state in the previous frame
|
|
@@ -289,7 +296,7 @@ export class PointerTracker implements Tracker
|
289
|
296
|
|
290
|
297
|
// determine the initial position
|
291
|
298
|
const initialPosition = previous ? previous.initialPosition :
|
292
|
|
- Object.freeze(position._clone());
|
|
299
|
+ Object.freeze(position._clone()) as Vector2;
|
293
|
300
|
|
294
|
301
|
// determine the velocity
|
295
|
302
|
const velocity = deltaPosition._clone()._scale(inverseDeltaTime);
|
|
@@ -314,6 +321,10 @@ export class PointerTracker implements Tracker
|
314
|
321
|
this._newPointers.clear();
|
315
|
322
|
this._advanceAllStationaryTrackables(deltaTime);
|
316
|
323
|
|
|
324
|
+ // discard unused IDs
|
|
325
|
+ if(this._activePointers.size == 0 && this._idMap.size > 0)
|
|
326
|
+ this._idMap.clear();
|
|
327
|
+
|
317
|
328
|
// generate output
|
318
|
329
|
this._previousOutput = this._generateOutput();
|
319
|
330
|
|
|
@@ -392,6 +403,25 @@ export class PointerTracker implements Tracker
|
392
|
403
|
}
|
393
|
404
|
|
394
|
405
|
/**
|
|
406
|
+ * Normalize pointer IDs across browsers
|
|
407
|
+ * @param pointerId browser-provided pointer ID
|
|
408
|
+ * @param pointerType pointer type
|
|
409
|
+ * @returns a normalized pointer ID
|
|
410
|
+ */
|
|
411
|
+ private _normalizeId(pointerId: number, pointerType: string): number
|
|
412
|
+ {
|
|
413
|
+ // XXX different hardware devices acting simultaneously may produce
|
|
414
|
+ // events with the same pointerId - handling this seems overkill?
|
|
415
|
+ if(pointerType == 'mouse')
|
|
416
|
+ return 0;
|
|
417
|
+
|
|
418
|
+ if(!this._idMap.has(pointerId))
|
|
419
|
+ this._idMap.set(pointerId, this._nextId++);
|
|
420
|
+
|
|
421
|
+ return this._idMap.get(pointerId)!;
|
|
422
|
+ }
|
|
423
|
+
|
|
424
|
+ /**
|
395
|
425
|
* Cancel all active pointers and consume all events
|
396
|
426
|
* @param deltaTime
|
397
|
427
|
*/
|