remote-calibrator 0.3.0 → 0.5.0-beta.3
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +12 -0
- package/README.md +29 -19
- package/homepage/example.js +9 -3
- package/i18n/fetch-languages-sheets.js +5 -4
- package/lib/RemoteCalibrator.min.js +1 -1
- package/lib/RemoteCalibrator.min.js.LICENSE.txt +1 -1
- package/lib/RemoteCalibrator.min.js.map +1 -1
- package/package.json +15 -15
- package/src/WebGazer4RC/.gitattributes +10 -0
- package/src/WebGazer4RC/LICENSE.md +15 -0
- package/src/WebGazer4RC/README.md +142 -0
- package/src/WebGazer4RC/gnu-lgpl-v3.0.md +163 -0
- package/src/WebGazer4RC/gplv3.md +636 -0
- package/src/WebGazer4RC/package-lock.json +1133 -0
- package/src/WebGazer4RC/package.json +28 -0
- package/src/WebGazer4RC/src/dom_util.mjs +27 -0
- package/src/WebGazer4RC/src/facemesh.mjs +150 -0
- package/src/WebGazer4RC/src/index.mjs +1235 -0
- package/src/WebGazer4RC/src/mat.mjs +301 -0
- package/src/WebGazer4RC/src/params.mjs +29 -0
- package/src/WebGazer4RC/src/pupil.mjs +109 -0
- package/src/WebGazer4RC/src/ridgeReg.mjs +104 -0
- package/src/WebGazer4RC/src/ridgeRegThreaded.mjs +161 -0
- package/src/WebGazer4RC/src/ridgeWeightedReg.mjs +125 -0
- package/src/WebGazer4RC/src/ridgeWorker.mjs +135 -0
- package/src/WebGazer4RC/src/util.mjs +348 -0
- package/src/WebGazer4RC/src/util_regression.mjs +240 -0
- package/src/WebGazer4RC/src/worker_scripts/mat.js +306 -0
- package/src/WebGazer4RC/src/worker_scripts/util.js +398 -0
- package/src/WebGazer4RC/test/regression_test.js +182 -0
- package/src/WebGazer4RC/test/run_tests_and_server.sh +24 -0
- package/src/WebGazer4RC/test/util_test.js +60 -0
- package/src/WebGazer4RC/test/webgazerExtract_test.js +40 -0
- package/src/WebGazer4RC/test/webgazer_test.js +160 -0
- package/src/WebGazer4RC/test/www_page_test.js +41 -0
- package/src/const.js +3 -0
- package/src/core.js +8 -0
- package/src/css/distance.scss +40 -0
- package/src/css/panel.scss +32 -1
- package/src/distance/distance.js +4 -4
- package/src/distance/distanceCheck.js +115 -0
- package/src/distance/distanceTrack.js +99 -41
- package/src/{interpupillaryDistance.js → distance/interPupillaryDistance.js} +14 -12
- package/src/gaze/gazeTracker.js +16 -1
- package/src/i18n.js +1 -1
- package/src/index.js +2 -1
- package/src/panel.js +32 -3
- package/webpack.config.js +4 -4
@@ -48,11 +48,14 @@ RemoteCalibrator.prototype.trackDistance = function (
|
|
48
48
|
showVideo: true,
|
49
49
|
showFaceOverlay: false,
|
50
50
|
decimalPlace: 1,
|
51
|
-
framerate: 3, //
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
51
|
+
framerate: 3, // tracking rate
|
52
|
+
desiredDistanceCm: undefined,
|
53
|
+
desiredDistanceTolerance: 0.1,
|
54
|
+
desiredDistanceMonitor: false,
|
55
|
+
nearPoint: true,
|
56
|
+
showNearPoint: false,
|
57
|
+
headline: '🙂 ' + phrases.RC_distanceTrackingTitle[this.L],
|
58
|
+
description: phrases.RC_distanceTrackingIntro[this.L],
|
56
59
|
},
|
57
60
|
options
|
58
61
|
)
|
@@ -111,6 +114,10 @@ RemoteCalibrator.prototype.trackDistance = function (
|
|
111
114
|
trackingOptions.nearPoint = options.nearPoint
|
112
115
|
trackingOptions.showNearPoint = options.showNearPoint
|
113
116
|
|
117
|
+
trackingOptions.desiredDistanceCm = options.desiredDistanceCm
|
118
|
+
trackingOptions.desiredDistanceTolerance = options.desiredDistanceTolerance
|
119
|
+
trackingOptions.desiredDistanceMonitor = options.desiredDistanceMonitor
|
120
|
+
|
114
121
|
originalStyles.video = options.showVideo
|
115
122
|
|
116
123
|
this.gazeTracker._init(
|
@@ -148,17 +155,14 @@ const startTrackingPupils = async (RC, beforeCallbackTrack, callbackTrack) => {
|
|
148
155
|
}
|
149
156
|
|
150
157
|
const eyeDist = (a, b) => {
|
151
|
-
return Math.
|
152
|
-
Math.pow(a[0] - b[0], 2) +
|
153
|
-
Math.pow(a[1] - b[1], 2) +
|
154
|
-
Math.pow(a[2] - b[2], 2)
|
155
|
-
)
|
158
|
+
return Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2])
|
156
159
|
}
|
157
160
|
|
158
161
|
const cyclopean = (video, a, b) => {
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
+
return [
|
163
|
+
(-a[0] - b[0] + video.videoWidth) / 2,
|
164
|
+
(-a[1] - b[1] + video.videoHeight) / 2,
|
165
|
+
]
|
162
166
|
}
|
163
167
|
|
164
168
|
/* -------------------------------------------------------------------------- */
|
@@ -168,6 +172,9 @@ const trackingOptions = {
|
|
168
172
|
framerate: 3,
|
169
173
|
nearPoint: true,
|
170
174
|
showNearPoint: false,
|
175
|
+
desiredDistanceCm: undefined,
|
176
|
+
desiredDistanceTolerance: 0.1,
|
177
|
+
desiredDistanceMonitor: false,
|
171
178
|
}
|
172
179
|
|
173
180
|
const stdDist = { current: null }
|
@@ -178,6 +185,10 @@ let iRepeatOptions = { framerate: 20, break: true }
|
|
178
185
|
let nearPointDot = null
|
179
186
|
/* -------------------------------------------------------------------------- */
|
180
187
|
|
188
|
+
let readyToGetFirstData = false
|
189
|
+
let averageDist = 0
|
190
|
+
let distCount = 1
|
191
|
+
|
181
192
|
const _tracking = async (RC, trackingOptions, callbackTrack) => {
|
182
193
|
const video = document.querySelector('#webgazerVideoFeed')
|
183
194
|
|
@@ -185,15 +196,15 @@ const _tracking = async (RC, trackingOptions, callbackTrack) => {
|
|
185
196
|
// const canvas = RC.gazeTracker.webgazer.videoCanvas
|
186
197
|
let model, faces
|
187
198
|
|
188
|
-
// Get the average of
|
189
|
-
|
190
|
-
|
199
|
+
// Get the average of 5 estimates for one measure
|
200
|
+
averageDist = 0
|
201
|
+
distCount = 1
|
191
202
|
const targetCount = 5
|
192
203
|
|
193
204
|
model = await RC.gazeTracker.webgazer.getTracker().model
|
194
205
|
|
195
206
|
// Near point
|
196
|
-
let ppi = RC.screenPpi ? RC.screenPpi.value :
|
207
|
+
let ppi = RC.screenPpi ? RC.screenPpi.value : RC._CONST.N.PPI_DONT_USE
|
197
208
|
if (!RC.screenPpi && trackingOptions.nearPoint)
|
198
209
|
console.error(
|
199
210
|
'Screen size measurement is required to get accurate near point tracking.'
|
@@ -216,16 +227,30 @@ const _tracking = async (RC, trackingOptions, callbackTrack) => {
|
|
216
227
|
})
|
217
228
|
}
|
218
229
|
|
230
|
+
readyToGetFirstData = false
|
231
|
+
const {
|
232
|
+
desiredDistanceCm,
|
233
|
+
desiredDistanceTolerance,
|
234
|
+
desiredDistanceMonitor,
|
235
|
+
} = trackingOptions
|
236
|
+
|
219
237
|
viewingDistanceTrackingFunction = async () => {
|
238
|
+
//
|
239
|
+
const videoTimestamp = new Date().getTime()
|
240
|
+
//
|
220
241
|
faces = await model.estimateFaces(video)
|
221
242
|
if (faces.length) {
|
222
243
|
// There's at least one face in video
|
223
|
-
|
244
|
+
RC._tackingVideoFrameTimestamps.distance += videoTimestamp
|
224
245
|
// https://github.com/tensorflow/tfjs-models/blob/master/facemesh/mesh_map.jpg
|
246
|
+
const mesh = faces[0].scaledMesh
|
247
|
+
|
225
248
|
if (targetCount === distCount) {
|
226
249
|
averageDist += eyeDist(mesh[133], mesh[362])
|
227
|
-
averageDist /=
|
250
|
+
averageDist /= targetCount
|
251
|
+
RC._tackingVideoFrameTimestamps.distance /= targetCount
|
228
252
|
|
253
|
+
// TODO Add more samples for the first estimate
|
229
254
|
if (stdDist.current !== null) {
|
230
255
|
if (!stdFactor) {
|
231
256
|
// ! First time estimate
|
@@ -235,11 +260,15 @@ const _tracking = async (RC, trackingOptions, callbackTrack) => {
|
|
235
260
|
// ! FINISH
|
236
261
|
RC._removeBackground()
|
237
262
|
RC._trackingSetupFinishedStatus.distance = true
|
263
|
+
readyToGetFirstData = true
|
238
264
|
}
|
239
265
|
|
240
266
|
/* -------------------------------------------------------------------------- */
|
241
267
|
|
242
268
|
const timestamp = new Date()
|
269
|
+
const latency = Math.round(
|
270
|
+
timestamp.getTime() - RC._tackingVideoFrameTimestamps.distance
|
271
|
+
)
|
243
272
|
|
244
273
|
const data = (RC.newViewingDistanceData = {
|
245
274
|
value: toFixedNumber(
|
@@ -248,8 +277,16 @@ const _tracking = async (RC, trackingOptions, callbackTrack) => {
|
|
248
277
|
),
|
249
278
|
timestamp: timestamp,
|
250
279
|
method: RC._CONST.VIEW_METHOD.F,
|
280
|
+
latencyMs: latency,
|
251
281
|
})
|
252
282
|
|
283
|
+
if (readyToGetFirstData || desiredDistanceMonitor) {
|
284
|
+
// Check distance
|
285
|
+
if (desiredDistanceCm)
|
286
|
+
RC.checkDistance(desiredDistanceCm, desiredDistanceTolerance)
|
287
|
+
readyToGetFirstData = false
|
288
|
+
}
|
289
|
+
|
253
290
|
/* -------------------------------------------------------------------------- */
|
254
291
|
|
255
292
|
// Near point
|
@@ -262,7 +299,8 @@ const _tracking = async (RC, trackingOptions, callbackTrack) => {
|
|
262
299
|
mesh,
|
263
300
|
averageDist,
|
264
301
|
timestamp,
|
265
|
-
ppi
|
302
|
+
ppi,
|
303
|
+
latency
|
266
304
|
)
|
267
305
|
}
|
268
306
|
|
@@ -274,6 +312,7 @@ const _tracking = async (RC, trackingOptions, callbackTrack) => {
|
|
274
312
|
value: {
|
275
313
|
viewingDistanceCm: data.value,
|
276
314
|
nearPointCm: nPData ? nPData.value : [null, null],
|
315
|
+
latencyMs: latency,
|
277
316
|
},
|
278
317
|
timestamp: timestamp,
|
279
318
|
method: RC._CONST.VIEW_METHOD.F,
|
@@ -283,6 +322,8 @@ const _tracking = async (RC, trackingOptions, callbackTrack) => {
|
|
283
322
|
|
284
323
|
averageDist = 0
|
285
324
|
distCount = 1
|
325
|
+
|
326
|
+
RC._tackingVideoFrameTimestamps.distance = 0
|
286
327
|
} else {
|
287
328
|
averageDist += eyeDist(mesh[133], mesh[362])
|
288
329
|
++distCount
|
@@ -291,7 +332,7 @@ const _tracking = async (RC, trackingOptions, callbackTrack) => {
|
|
291
332
|
}
|
292
333
|
|
293
334
|
iRepeatOptions.break = false
|
294
|
-
iRepeatOptions.framerate = targetCount * trackingOptions.framerate // Default
|
335
|
+
iRepeatOptions.framerate = targetCount * trackingOptions.framerate // Default 5 * 3
|
295
336
|
iRepeat(viewingDistanceTrackingFunction, iRepeatOptions)
|
296
337
|
}
|
297
338
|
|
@@ -305,45 +346,42 @@ const _getNearPoint = (
|
|
305
346
|
mesh,
|
306
347
|
averageDist,
|
307
348
|
timestamp,
|
308
|
-
ppi
|
349
|
+
ppi,
|
350
|
+
latency
|
309
351
|
) => {
|
310
|
-
let
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
const videoFactor = video.videoHeight / video.clientHeight
|
317
|
-
offsetToVideoMid.forEach((e, i) => {
|
318
|
-
// Average interpupillary distance - 6.4cm
|
319
|
-
offsetToVideoMid[i] =
|
320
|
-
((RC.PDCm ? RC.PDCm.value : 6.4) * e) /
|
321
|
-
(averageDist * (videoFactor / 2)) /* Should this be videoFactor? */
|
352
|
+
let offsetToVideoCenter = cyclopean(video, mesh[133], mesh[362])
|
353
|
+
offsetToVideoCenter.forEach((offset, i) => {
|
354
|
+
// Average inter-pupillary distance - 6.4cm
|
355
|
+
offsetToVideoCenter[i] =
|
356
|
+
((RC.PDCm ? RC.PDCm.value : RC._CONST.N.PD_DONT_USE) * offset) /
|
357
|
+
averageDist
|
322
358
|
})
|
323
359
|
|
324
360
|
let nPData = (RC.newNearPointData = {
|
325
361
|
value: {
|
326
|
-
x: toFixedNumber(
|
362
|
+
x: toFixedNumber(offsetToVideoCenter[0], trackingOptions.decimalPlace),
|
327
363
|
y: toFixedNumber(
|
328
|
-
|
364
|
+
offsetToVideoCenter[1] + ((screen.height / 2) * 2.54) / ppi, // Commonly the webcam is 0.5cm above the screen
|
329
365
|
trackingOptions.decimalPlace
|
330
366
|
),
|
367
|
+
latencyMs: latency,
|
331
368
|
},
|
332
369
|
timestamp: timestamp,
|
333
370
|
})
|
334
371
|
|
335
372
|
// SHOW
|
373
|
+
const dotR = 5
|
336
374
|
if (trackingOptions.showNearPoint) {
|
337
375
|
let offsetX = (nPData.value.x * ppi) / 2.54
|
338
376
|
let offsetY = (nPData.value.y * ppi) / 2.54
|
339
377
|
Object.assign(nearPointDot.style, {
|
340
|
-
left: `${screen.width / 2 - window.screenLeft
|
378
|
+
left: `${screen.width / 2 - window.screenLeft + offsetX - dotR}px`,
|
341
379
|
top: `${
|
342
380
|
screen.height / 2 -
|
343
381
|
window.screenTop -
|
344
|
-
|
345
|
-
|
346
|
-
|
382
|
+
(window.outerHeight - window.innerHeight) -
|
383
|
+
offsetY -
|
384
|
+
dotR
|
347
385
|
}px`,
|
348
386
|
})
|
349
387
|
}
|
@@ -355,6 +393,7 @@ RemoteCalibrator.prototype.pauseDistance = function () {
|
|
355
393
|
if (this.gazeTracker.checkInitialized('distance', true)) {
|
356
394
|
iRepeatOptions.break = true
|
357
395
|
if (nearPointDot) nearPointDot.style.display = 'none'
|
396
|
+
this._tackingVideoFrameTimestamps.distance = 0
|
358
397
|
return this
|
359
398
|
}
|
360
399
|
return null
|
@@ -364,6 +403,11 @@ RemoteCalibrator.prototype.resumeDistance = function () {
|
|
364
403
|
if (this.gazeTracker.checkInitialized('distance', true)) {
|
365
404
|
iRepeatOptions.break = false
|
366
405
|
if (nearPointDot) nearPointDot.style.display = 'block'
|
406
|
+
|
407
|
+
averageDist = 0
|
408
|
+
distCount = 1
|
409
|
+
this._tackingVideoFrameTimestamps.distance = 0
|
410
|
+
|
367
411
|
iRepeat(viewingDistanceTrackingFunction, iRepeatOptions)
|
368
412
|
return this
|
369
413
|
}
|
@@ -381,10 +425,17 @@ RemoteCalibrator.prototype.endDistance = function (endAll = false, _r = true) {
|
|
381
425
|
trackingOptions.nearPoint = true
|
382
426
|
trackingOptions.showNearPoint = false
|
383
427
|
|
428
|
+
trackingOptions.desiredDistanceCm = undefined
|
429
|
+
trackingOptions.desiredDistanceTolerance = 0.1
|
430
|
+
trackingOptions.desiredDistanceMonitor = false
|
431
|
+
|
384
432
|
stdDist.current = null
|
385
433
|
stdFactor = null
|
386
434
|
viewingDistanceTrackingFunction = null
|
387
435
|
|
436
|
+
readyToGetFirstData = false
|
437
|
+
this._tackingVideoFrameTimestamps.distance = 0
|
438
|
+
|
388
439
|
// Near point
|
389
440
|
if (nearPointDot) {
|
390
441
|
document.body.removeChild(nearPointDot)
|
@@ -411,6 +462,7 @@ RemoteCalibrator.prototype.getDistanceNow = async function (callback = null) {
|
|
411
462
|
|
412
463
|
let v = document.querySelector('#webgazerVideoFeed')
|
413
464
|
let m = await this.gazeTracker.webgazer.getTracker().model
|
465
|
+
const videoTimestamp = new Date().getTime()
|
414
466
|
let f = await m.estimateFaces(v)
|
415
467
|
|
416
468
|
if (f.length) {
|
@@ -418,11 +470,15 @@ RemoteCalibrator.prototype.getDistanceNow = async function (callback = null) {
|
|
418
470
|
const dist = eyeDist(mesh[133], mesh[362])
|
419
471
|
|
420
472
|
let timestamp = new Date()
|
473
|
+
//
|
474
|
+
const latency = timestamp.getTime() - videoTimestamp
|
475
|
+
//
|
421
476
|
|
422
477
|
const data = (this.newViewingDistanceData = {
|
423
478
|
value: toFixedNumber(stdFactor / dist, trackingOptions.decimalPlace),
|
424
479
|
timestamp: timestamp,
|
425
480
|
method: this._CONST.VIEW_METHOD.F,
|
481
|
+
latencyMs: latency,
|
426
482
|
})
|
427
483
|
|
428
484
|
let nPData
|
@@ -434,7 +490,8 @@ RemoteCalibrator.prototype.getDistanceNow = async function (callback = null) {
|
|
434
490
|
mesh,
|
435
491
|
dist,
|
436
492
|
timestamp,
|
437
|
-
this.screenPpi ? this.screenPpi.value :
|
493
|
+
this.screenPpi ? this.screenPpi.value : this._CONST.N.PPI_DONT_USE,
|
494
|
+
latency
|
438
495
|
)
|
439
496
|
}
|
440
497
|
|
@@ -442,6 +499,7 @@ RemoteCalibrator.prototype.getDistanceNow = async function (callback = null) {
|
|
442
499
|
value: {
|
443
500
|
viewingDistanceCm: data.value,
|
444
501
|
nearPointCm: nPData ? nPData.value : null,
|
502
|
+
latencyMs: latency,
|
445
503
|
},
|
446
504
|
timestamp: timestamp,
|
447
505
|
method: this._CONST.VIEW_METHOD.F,
|
@@ -1,20 +1,20 @@
|
|
1
1
|
import Swal from 'sweetalert2'
|
2
2
|
|
3
|
-
import RemoteCalibrator from '
|
3
|
+
import RemoteCalibrator from '../core'
|
4
4
|
|
5
5
|
import {
|
6
6
|
blurAll,
|
7
7
|
constructInstructions,
|
8
8
|
safeExecuteFunc,
|
9
9
|
toFixedNumber,
|
10
|
-
} from '
|
11
|
-
import { swalInfoOptions } from '
|
12
|
-
import Arrow from '
|
13
|
-
import PD from '
|
14
|
-
import { bindKeys, unbindKeys } from '
|
15
|
-
import { addButtons } from '
|
16
|
-
import { setDefaultVideoPosition } from '
|
17
|
-
import { phrases } from '
|
10
|
+
} from '../components/utils'
|
11
|
+
import { swalInfoOptions } from '../components/swalOptions'
|
12
|
+
import Arrow from '../media/arrow.svg'
|
13
|
+
import PD from '../media/pd.png?width=480&height=240'
|
14
|
+
import { bindKeys, unbindKeys } from '../components/keyBinder'
|
15
|
+
import { addButtons } from '../components/buttons'
|
16
|
+
import { setDefaultVideoPosition } from '../components/video'
|
17
|
+
import { phrases } from '../i18n'
|
18
18
|
|
19
19
|
// let selfVideo = false // No WebGazer video available and an extra video element needs to be created
|
20
20
|
|
@@ -40,7 +40,7 @@ RemoteCalibrator.prototype._measurePD = function (options = {}, callback) {
|
|
40
40
|
{
|
41
41
|
fullscreen: false,
|
42
42
|
headline: '👁️ ' + phrases.RC_nearPointTitle[this.L],
|
43
|
-
description: phrases.
|
43
|
+
description: phrases.RC_nearPointIntro[this.L],
|
44
44
|
shortDescription: phrases.RC_nearPointIntro[this.L],
|
45
45
|
},
|
46
46
|
options
|
@@ -51,9 +51,11 @@ RemoteCalibrator.prototype._measurePD = function (options = {}, callback) {
|
|
51
51
|
this._replaceBackground()
|
52
52
|
|
53
53
|
this._replaceBackground(
|
54
|
-
constructInstructions(options.headline, options.shortDescription)
|
54
|
+
constructInstructions(options.headline, options.shortDescription, true)
|
55
55
|
)
|
56
|
-
const screenPpi = this.screenPpi
|
56
|
+
const screenPpi = this.screenPpi
|
57
|
+
? this.screenPpi.value
|
58
|
+
: this._CONST.N.PPI_DONT_USE
|
57
59
|
|
58
60
|
let [videoWidth, videoHeight] = setupVideo(this)
|
59
61
|
let [ruler, rulerListener] = setupRuler(
|
package/src/gaze/gazeTracker.js
CHANGED
@@ -100,6 +100,8 @@ GazeTracker.prototype._init = function (
|
|
100
100
|
// this.webgazer.saveDataAcrossSessions(false)
|
101
101
|
this.webgazer.params.greedyLearner = greedyLearner
|
102
102
|
this.webgazer.params.framerate = framerate
|
103
|
+
this.webgazer.params.getLatestVideoFrameTimestamp =
|
104
|
+
this._getLatestVideoTimestamp.bind(this)
|
103
105
|
this.showGazer(showGazer)
|
104
106
|
}
|
105
107
|
|
@@ -127,12 +129,15 @@ GazeTracker.prototype.checkInitialized = function (task, warning = false) {
|
|
127
129
|
}
|
128
130
|
|
129
131
|
GazeTracker.prototype.getData = function (d) {
|
132
|
+
let t = new Date()
|
130
133
|
return {
|
131
134
|
value: {
|
132
135
|
x: toFixedNumber(d.x, this._toFixedN),
|
133
136
|
y: toFixedNumber(d.y, this._toFixedN),
|
137
|
+
latencyMs:
|
138
|
+
t.getTime() - this.calibrator._tackingVideoFrameTimestamps.gaze, // latency
|
134
139
|
},
|
135
|
-
timestamp:
|
140
|
+
timestamp: t,
|
136
141
|
}
|
137
142
|
}
|
138
143
|
|
@@ -156,6 +161,8 @@ GazeTracker.prototype.end = function (type, endAll = false) {
|
|
156
161
|
this._endGaze()
|
157
162
|
if (endEverything && this.checkInitialized('distance'))
|
158
163
|
this.calibrator.endDistance(false, false)
|
164
|
+
|
165
|
+
this.calibrator._tackingVideoFrameTimestamps.gaze = 0
|
159
166
|
} else {
|
160
167
|
// Distance
|
161
168
|
this.defaultDistanceTrackCallback = null
|
@@ -188,8 +195,16 @@ GazeTracker.prototype._endGaze = function () {
|
|
188
195
|
|
189
196
|
this.webgazer.params.greedyLearner = false
|
190
197
|
this.webgazer.params.framerate = 60
|
198
|
+
|
199
|
+
this.webgazer.params.getLatestVideoFrameTimestamp = () => {}
|
200
|
+
}
|
201
|
+
|
202
|
+
GazeTracker.prototype._getLatestVideoTimestamp = function (t) {
|
203
|
+
this.calibrator._tackingVideoFrameTimestamps.gaze = t.getTime()
|
191
204
|
}
|
192
205
|
|
206
|
+
/* -------------------------------------------------------------------------- */
|
207
|
+
|
193
208
|
GazeTracker.prototype.startStoringPoints = function () {
|
194
209
|
this.webgazer.params.storingPoints = true
|
195
210
|
}
|