|
@@ -56,6 +56,9 @@ export interface TrackablePointer extends Trackable
|
56
|
56
|
/** the first position of this trackable, given in normalized coordinates */
|
57
|
57
|
readonly initialPosition: Vector2;
|
58
|
58
|
|
|
59
|
+ /** the current velocity, given in normalized coordinates per second */
|
|
60
|
+ readonly velocity: Vector2;
|
|
61
|
+
|
59
|
62
|
/** whether or not this is the primary pointer for this type */
|
60
|
63
|
readonly isPrimary: boolean;
|
61
|
64
|
|
|
@@ -117,6 +120,9 @@ export class PointerTracker implements Tracker
|
117
|
120
|
/** last output */
|
118
|
121
|
private _lastOutput: PointerTrackerOutput;
|
119
|
122
|
|
|
123
|
+ /** time of the last update */
|
|
124
|
+ private _lastUpdateTime: DOMHighResTimeStamp;
|
|
125
|
+
|
120
|
126
|
|
121
|
127
|
|
122
|
128
|
/**
|
|
@@ -129,6 +135,7 @@ export class PointerTracker implements Tracker
|
129
|
135
|
this._activePointers = new Map();
|
130
|
136
|
this._newPointers = new Map();
|
131
|
137
|
this._lastOutput = this._generateOutput();
|
|
138
|
+ this._lastUpdateTime = Number.POSITIVE_INFINITY;
|
132
|
139
|
}
|
133
|
140
|
|
134
|
141
|
/**
|
|
@@ -195,6 +202,10 @@ export class PointerTracker implements Tracker
|
195
|
202
|
const canvas = this._viewport!.canvas;
|
196
|
203
|
const rect = canvas.getBoundingClientRect(); // may be different in different frames!
|
197
|
204
|
|
|
205
|
+ // find the time between this and the last update of this tracker
|
|
206
|
+ const deltaTime = this._updateTime();
|
|
207
|
+ const inverseDeltaTime = (deltaTime > 1e-5) ? 1 / deltaTime : 60; // 1/dt = 1 / (1/60) with 60 fps
|
|
208
|
+
|
198
|
209
|
// remove inactive trackables from the previous frame (update cycle)
|
199
|
210
|
const inactiveTrackables = this._findUnwantedTrackables();
|
200
|
211
|
for(let i = inactiveTrackables.length - 1; i >= 0; i--)
|
|
@@ -290,6 +301,10 @@ export class PointerTracker implements Tracker
|
290
|
301
|
const initialPosition = previous ? previous.initialPosition :
|
291
|
302
|
Object.freeze(new Vector2(position.x, position.y));
|
292
|
303
|
|
|
304
|
+ // determine the velocity
|
|
305
|
+ const velocity = new Vector2(deltaPosition.x, deltaPosition.y)
|
|
306
|
+ ._scale(inverseDeltaTime);
|
|
307
|
+
|
293
|
308
|
// determine whether or not this is the primary pointer for this type
|
294
|
309
|
const isPrimary = event.isPrimary;
|
295
|
310
|
|
|
@@ -298,7 +313,7 @@ export class PointerTracker implements Tracker
|
298
|
313
|
|
299
|
314
|
// we create new trackable instances on each frame;
|
300
|
315
|
// these will be exported and consumed by the user
|
301
|
|
- this._newPointers.set(id, { id, phase, position, deltaPosition, initialPosition, isPrimary, type });
|
|
316
|
+ this._newPointers.set(id, { id, phase, position, deltaPosition, initialPosition, velocity, isPrimary, type });
|
302
|
317
|
|
303
|
318
|
}
|
304
|
319
|
|
|
@@ -369,4 +384,21 @@ export class PointerTracker implements Tracker
|
369
|
384
|
|
370
|
385
|
return trackables;
|
371
|
386
|
}
|
|
387
|
+
|
|
388
|
+ /**
|
|
389
|
+ * Update the time
|
|
390
|
+ * @returns delta time in seconds
|
|
391
|
+ */
|
|
392
|
+ private _updateTime(): DOMHighResTimeStamp
|
|
393
|
+ {
|
|
394
|
+ const now = performance.now() * 0.001;
|
|
395
|
+
|
|
396
|
+ if(this._lastUpdateTime > now)
|
|
397
|
+ this._lastUpdateTime = now;
|
|
398
|
+
|
|
399
|
+ const prev = this._lastUpdateTime;
|
|
400
|
+ this._lastUpdateTime = now;
|
|
401
|
+
|
|
402
|
+ return now - prev;
|
|
403
|
+ }
|
372
|
404
|
}
|