-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
155 lines (140 loc) · 4.54 KB
/
script.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
function htmlToElement(html) {
var template = document.createElement("template");
html = html.trim(); // Never return a text node of whitespace as the result
template.innerHTML = html;
return template.content.firstChild;
}
// add autopilot button
let autopilotEngaged = false;
const optionsElement = document.getElementById("options");
const autopilotButton = htmlToElement(
'<div id="autopilot" title="Engage Autopilot" class="icon">A</div>'
);
autopilotButton.addEventListener("click", () => {
autopilotEngaged = !autopilotEngaged;
});
optionsElement.appendChild(autopilotButton);
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
const shouldMove = (targetVelocity, currentVelocity, pulse) => {
// will moving get me closer to my target velocity
const newVelocity = currentVelocity + pulse;
return (
Math.abs(targetVelocity - newVelocity) <
Math.abs(targetVelocity - currentVelocity)
);
};
const shouldTogglePrecision = (distance) => {
const precisionThreshold = 5;
const precisionStatusElement = document.getElementById(
"precision-translation-status"
);
const precisionToggleButton = document.getElementById("toggle-translation");
if (
distance > precisionThreshold &&
precisionStatusElement.className !== "noselect large"
) {
precisionToggleButton.click();
} else if (
distance <= precisionThreshold &&
precisionStatusElement.className === "noselect large"
) {
precisionToggleButton.click();
}
};
const rotationIncrement = rotationPulseSize * toRAD * 0.01;
// time between each loop
const sleepTime = 20;
// rotation spring constant
const rk = 0.02;
// rotation critical damping constant
const rb = Math.sqrt(4 * rk);
// translation spring constant
const tk = 0.8;
// translation critical damping constant
const tb = Math.sqrt(4 * tk);
const loop = async () => {
console.log("autopilot engaged");
while (true) {
if (autopilotEngaged) {
// should toggle translation precision
// calculate rotaion velocities
const rotationX = camera.rotation.x;
const rotationY = camera.rotation.y;
const rotationZ = camera.rotation.z;
const targetRotationXRate = -rk * rotationX - rb * currentRotationX;
const targetRotationYRate = -rk * rotationY - rb * currentRotationY;
const targetRotationZRate = -rk * rotationZ - rb * currentRotationZ;
// calculate translation velocities
const xRange = camera.position.x - issObject.position.x;
const yRange = camera.position.y - issObject.position.y;
const zRange = camera.position.z - issObject.position.z;
const currentXVelocity = motionVector.x * 50;
const currentYVelocity = motionVector.y * 50;
const currentZVelocity = motionVector.z * 50;
const targetXVelocity = -tk * xRange - tb * currentXVelocity;
const targetYVelocity = -tk * yRange - tb * currentYVelocity;
const targetZVelocity = -tk * zRange - tb * currentZVelocity - 0.01;
shouldTogglePrecision(zRange);
// rotation actuators
if (
shouldMove(targetRotationXRate, currentRotationX, -rotationIncrement)
) {
pitchDown();
}
if (
shouldMove(targetRotationXRate, currentRotationX, rotationIncrement)
) {
pitchUp();
}
if (
shouldMove(targetRotationYRate, currentRotationY, -rotationIncrement)
) {
yawRight();
}
if (
shouldMove(targetRotationYRate, currentRotationY, rotationIncrement)
) {
yawLeft();
}
if (
shouldMove(targetRotationZRate, currentRotationZ, -rotationIncrement)
) {
rollRight();
}
if (
shouldMove(targetRotationZRate, currentRotationZ, rotationIncrement)
) {
rollLeft();
}
// translation actuators
if (
shouldMove(targetXVelocity, currentXVelocity, -translationPulseSize)
) {
translateLeft();
}
if (shouldMove(targetXVelocity, currentXVelocity, translationPulseSize)) {
translateRight();
}
if (
shouldMove(targetYVelocity, currentYVelocity, -translationPulseSize)
) {
translateDown();
}
if (shouldMove(targetYVelocity, currentYVelocity, translationPulseSize)) {
translateUp();
}
if (
shouldMove(targetZVelocity, currentZVelocity, -translationPulseSize)
) {
translateForward();
}
if (shouldMove(targetZVelocity, currentZVelocity, translationPulseSize)) {
translateBackward();
}
}
await sleep(sleepTime);
}
};
loop();