forked from c-frame/aframe-extras
-
Notifications
You must be signed in to change notification settings - Fork 0
/
checkpoint-controls.js
86 lines (68 loc) · 2.3 KB
/
checkpoint-controls.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
const EPS = 0.1;
module.exports = AFRAME.registerComponent('checkpoint-controls', {
schema: {
enabled: {default: true},
mode: {default: 'teleport', oneOf: ['teleport', 'animate']},
animateSpeed: {default: 3.0}
},
init: function () {
this.active = true;
this.checkpoint = null;
this.isNavMeshConstrained = false;
this.offset = new THREE.Vector3();
this.position = new THREE.Vector3();
this.targetPosition = new THREE.Vector3();
},
play: function () { this.active = true; },
pause: function () { this.active = false; },
setCheckpoint: function (checkpoint) {
const el = this.el;
if (!this.active) return;
if (this.checkpoint === checkpoint) return;
if (this.checkpoint) {
el.emit('navigation-end', {checkpoint: this.checkpoint});
}
this.checkpoint = checkpoint;
this.sync();
// Ignore new checkpoint if we're already there.
if (this.position.distanceTo(this.targetPosition) < EPS) {
this.checkpoint = null;
return;
}
el.emit('navigation-start', {checkpoint: checkpoint});
if (this.data.mode === 'teleport') {
this.el.setAttribute('position', this.targetPosition);
this.checkpoint = null;
el.emit('navigation-end', {checkpoint: checkpoint});
el.components['movement-controls'].updateNavLocation();
}
},
isVelocityActive: function () {
return !!(this.active && this.checkpoint);
},
getVelocity: function () {
if (!this.active) return;
const data = this.data;
const offset = this.offset;
const position = this.position;
const targetPosition = this.targetPosition;
const checkpoint = this.checkpoint;
this.sync();
if (position.distanceTo(targetPosition) < EPS) {
this.checkpoint = null;
this.el.emit('navigation-end', {checkpoint: checkpoint});
return offset.set(0, 0, 0);
}
offset.setLength(data.animateSpeed);
return offset;
},
sync: function () {
const offset = this.offset;
const position = this.position;
const targetPosition = this.targetPosition;
position.copy(this.el.getAttribute('position'));
targetPosition.copy(this.checkpoint.object3D.getWorldPosition());
targetPosition.add(this.checkpoint.components.checkpoint.getOffset());
offset.copy(targetPosition).sub(position);
}
});