Skip to content

Commit 6809730

Browse files
committed
better curves
1 parent 0d48eba commit 6809730

File tree

4 files changed

+459
-16
lines changed

4 files changed

+459
-16
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
3+
*.json

index.html

Lines changed: 233 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,256 @@
55
<script src="https://cdn.rawgit.com/zcanter/aframe-scatterplot/master/dist/a-scatterplot.min.js"></script>
66
<!-- orbit-controls -->
77
<script src="//cdn.rawgit.com/tizzle/aframe-orbit-controls-component/master/dist/aframe-orbit-controls-component.min.js"></script>
8+
<!-- <script src="https://rawgit.com/protyze/aframe-curve-component/master/dist/aframe-curve-component.min.js"></script> -->
9+
<!-- <script src="https://rawgit.com/protyze/aframe-alongpath-component/master/dist/aframe-alongpath-component.min.js"></script> -->
10+
<script src="https://unpkg.com/aframe-curve-component/dist/aframe-curve-component.min.js"></script>
811
<!-- wasd-controls -->
9-
<script src="//cdn.rawgit.com/donmccurdy/aframe-extras/v3.7.0/dist/aframe-extras.min.js"></script>
12+
<script>
13+
var bind = AFRAME.utils.bind;
14+
var shouldCaptureKeyEvent = AFRAME.utils.shouldCaptureKeyEvent;
15+
16+
var CLAMP_VELOCITY = 0.00001;
17+
var MAX_DELTA = 0.2;
18+
var KEYS = [
19+
'KeyW', 'KeyA', 'KeyS', 'KeyD',
20+
'ArrowUp', 'ArrowDown'
21+
]
22+
AFRAME.registerComponent('stream-wasd-controls', {
23+
schema: {
24+
acceleration: {default: 65},
25+
adAxis: {default: 'x', oneOf: ['x', 'y', 'z']},
26+
adEnabled: {default: true},
27+
adInverted: {default: false},
28+
easing: {default: 20},
29+
enabled: {default: true},
30+
fly: {default: false},
31+
head: {type: 'selector'},
32+
wsAxis: {default: 'z', oneOf: ['x', 'y', 'z']},
33+
wsEnabled: {default: true},
34+
wsInverted: {default: false}
35+
},
36+
37+
init: function () {
38+
// To keep track of the pressed keys.
39+
this.keys = {};
40+
41+
this.position = {};
42+
this.velocity = new THREE.Vector3();
43+
44+
// Bind methods and add event listeners.
45+
this.onBlur = bind(this.onBlur, this);
46+
this.onFocus = bind(this.onFocus, this);
47+
this.onKeyDown = bind(this.onKeyDown, this);
48+
this.onKeyUp = bind(this.onKeyUp, this);
49+
this.onVisibilityChange = bind(this.onVisibilityChange, this);
50+
this.attachVisibilityEventListeners();
51+
},
52+
53+
tick: function (time, delta) {
54+
var currentPosition;
55+
var data = this.data;
56+
var el = this.el;
57+
var movementVector;
58+
var position = this.position;
59+
var velocity = this.velocity;
60+
61+
if (!velocity[data.adAxis] && !velocity[data.wsAxis] &&
62+
isEmptyObject(this.keys)) { return; }
63+
64+
// Update velocity.
65+
delta = delta / 1000;
66+
this.updateVelocity(delta);
67+
68+
if (!velocity[data.adAxis] && !velocity[data.wsAxis]) { return; }
69+
70+
// Get movement vector and translate position.
71+
currentPosition = el.getAttribute('position');
72+
movementVector = this.getMovementVector(delta);
73+
position.x = currentPosition.x + movementVector.x;
74+
position.y = currentPosition.y + movementVector.y;
75+
position.z = currentPosition.z + movementVector.z;
76+
el.setAttribute('position', position);
77+
},
78+
79+
remove: function () {
80+
this.removeKeyEventListeners();
81+
this.removeVisibilityEventListeners();
82+
},
83+
84+
play: function () {
85+
this.attachKeyEventListeners();
86+
},
87+
88+
pause: function () {
89+
this.keys = {};
90+
this.removeKeyEventListeners();
91+
},
92+
93+
updateVelocity: function (delta) {
94+
var acceleration;
95+
var adAxis;
96+
var adSign;
97+
var data = this.data;
98+
var keys = this.keys;
99+
var velocity = this.velocity;
100+
var wsAxis;
101+
var wsSign;
102+
103+
adAxis = data.adAxis;
104+
wsAxis = data.wsAxis;
105+
106+
// If FPS too low, reset velocity.
107+
if (delta > MAX_DELTA) {
108+
velocity[adAxis] = 0;
109+
velocity[wsAxis] = 0;
110+
return;
111+
}
112+
113+
// Decay velocity.
114+
if (velocity[adAxis] !== 0) {
115+
velocity[adAxis] -= velocity[adAxis] * data.easing * delta;
116+
}
117+
if (velocity[wsAxis] !== 0) {
118+
velocity[wsAxis] -= velocity[wsAxis] * data.easing * delta;
119+
}
120+
121+
// Clamp velocity easing.
122+
if (Math.abs(velocity[adAxis]) < CLAMP_VELOCITY) { velocity[adAxis] = 0; }
123+
if (Math.abs(velocity[wsAxis]) < CLAMP_VELOCITY) { velocity[wsAxis] = 0; }
124+
125+
if (!data.enabled) { return; }
126+
127+
// Update velocity using keys pressed.
128+
acceleration = data.acceleration;
129+
if (data.adEnabled) {
130+
adSign = data.adInverted ? -1 : 1;
131+
if (keys.KeyA || keys.ArrowLeft) { velocity[adAxis] -= adSign * acceleration * delta; }
132+
if (keys.KeyD || keys.ArrowRight) { velocity[adAxis] += adSign * acceleration * delta; }
133+
}
134+
if (data.wsEnabled) {
135+
wsSign = data.wsInverted ? -1 : 1;
136+
if (keys.KeyW || keys.ArrowUp) { velocity[wsAxis] -= wsSign * acceleration * delta; }
137+
if (keys.KeyS || keys.ArrowDown) { velocity[wsAxis] += wsSign * acceleration * delta; }
138+
}
139+
},
140+
141+
getMovementVector: (function () {
142+
var directionVector = new THREE.Vector3(0, 0, 0);
143+
var rotationEuler = new THREE.Euler(0, 0, 0, 'YXZ');
144+
145+
return function (delta) {
146+
var rotation = (this.data.head || this.el).getAttribute('rotation');
147+
var velocity = this.velocity;
148+
var xRotation;
149+
150+
directionVector.copy(velocity);
151+
directionVector.multiplyScalar(delta);
152+
153+
// Absolute.
154+
if (!rotation) { return directionVector; }
155+
156+
xRotation = this.data.fly ? rotation.x : 0;
157+
158+
// Transform direction relative to heading.
159+
rotationEuler.set(THREE.Math.degToRad(xRotation), THREE.Math.degToRad(rotation.y), 0);
160+
directionVector.applyEuler(rotationEuler);
161+
console.log(directionVector);
162+
return directionVector;
163+
};
164+
})(),
165+
166+
attachVisibilityEventListeners: function () {
167+
window.addEventListener('blur', this.onBlur);
168+
window.addEventListener('focus', this.onFocus);
169+
document.addEventListener('visibilitychange', this.onVisibilityChange);
170+
},
171+
172+
removeVisibilityEventListeners: function () {
173+
window.removeEventListener('blur', this.onBlur);
174+
window.removeEventListener('focus', this.onFocus);
175+
document.removeEventListener('visibilitychange', this.onVisibilityChange);
176+
},
177+
178+
attachKeyEventListeners: function () {
179+
window.addEventListener('keydown', this.onKeyDown);
180+
window.addEventListener('keyup', this.onKeyUp);
181+
},
182+
183+
removeKeyEventListeners: function () {
184+
window.removeEventListener('keydown', this.onKeyDown);
185+
window.removeEventListener('keyup', this.onKeyUp);
186+
},
187+
188+
onBlur: function () {
189+
this.pause();
190+
},
191+
192+
onFocus: function () {
193+
this.play();
194+
},
195+
196+
onVisibilityChange: function () {
197+
if (document.hidden) {
198+
this.onBlur();
199+
} else {
200+
this.onFocus();
201+
}
202+
},
203+
204+
onKeyDown: function (event) {
205+
var code;
206+
if (!shouldCaptureKeyEvent(event)) { return; }
207+
code = event.code || KEYCODE_TO_CODE[event.keyCode];
208+
if (KEYS.indexOf(code) !== -1) { this.keys[code] = true; }
209+
},
210+
211+
onKeyUp: function (event) {
212+
var code;
213+
code = event.code || KEYCODE_TO_CODE[event.keyCode];
214+
delete this.keys[code];
215+
}
216+
});
217+
218+
function isEmptyObject (keys) {
219+
var key;
220+
for (key in keys) { return false; }
221+
return true;
222+
}
223+
</script>
10224
</head>
11225
<body>
12226
<a-scene>
13-
<a-entity rotation="0 90 0">
14-
<a-camera position="-0.06593725135199813, -0.022338808438985724, -0.046025399083270205"></a-camera>
15-
<a-entity id="circles" >
16-
17-
</a-entity>
227+
<a-entity id="rig" rotation="0 90 0">
228+
<!-- <a-entity camera="zoom: 10" look-controls stream-wasd-controls="acceleration: 10" position="1 1 1"></a-entity> -->
229+
<a-camera look-controls wasd-controls>
230+
<a-curve id="track1"></a-curve>
231+
</a-camera>
232+
<!-- <a-box alongpath="curve: #track1; loop: true"></a-box> -->
233+
<a-draw-curve curveref="#track1" material="shader: line; color: blue;"></a-draw-curve>
234+
<a-entity id="circles"></a-entity>
18235
</a-entity>
19236
<a-sky></a-sky>
20237

21238

22239
</a-scene>
23240
<script>
24241

25-
const getCircles = () => {
242+
const getCurvePoints = () => {
26243
return fetch('curves.json')
27244
.then(response => response.text())
28245
.then(text => {
29246
const coords = JSON.parse(text);
30-
const circles = [];
247+
const curvePoints = [];
31248
coords.forEach((coord, _) => {
32-
const circle = `<a-circle position="${coord.x} ${coord.y} ${coord.z}" radius=".001" color="red"></a-circle>`;
33-
circles.push(circle);
249+
const curvePoint = `<a-curve-point position="${coord.x} ${coord.y} ${coord.z}"></a-curve-point>`;
250+
curvePoints.push(curvePoint);
34251
});
35-
return circles;
252+
return curvePoints;
36253
});
37254
}
38255

39256
const getPairs = async () => {
40-
const coord_pairs = await fetch('curves.json')
257+
const coord_pairs = await fetch('test.json')
41258
.then(response => response.text())
42259
.then(text => {
43260
const coords = JSON.parse(text);
@@ -64,10 +281,10 @@
64281
return lines;
65282
};
66283

67-
getCircles()
68-
.then((circles) => {
69-
const circle_el = document.getElementById("circles");
70-
circle_el.innerHTML = circles.join(" ");
284+
getCurvePoints()
285+
.then((curvePoints) => {
286+
const curve_el = document.getElementById("track1");
287+
curve_el.innerHTML = curvePoints.join(" ");
71288
});
72289

73290
</script>

0 commit comments

Comments
 (0)