0 | 0 |
import Leap from 'leapjs';
|
1 | 1 |
import * as T from 'three';
|
2 | 2 |
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
|
|
3 |
import { saveAs } from 'file-saver';
|
3 | 4 |
|
4 | 5 |
const clamp = (val, min=0, max=1) => Math.min(max, Math.max(min, val));
|
5 | 6 |
const lerp = (a, b, t) => a.plus(b.minus(a).times(t));
|
|
14 | 15 |
const scene = new T.Scene();
|
15 | 16 |
scene.background = new T.Color().setHSL(0.7, .95, .93);
|
16 | 17 |
|
|
18 |
const grid = new T.GridHelper(250, 10);
|
|
19 |
scene.add(grid);
|
|
20 |
|
17 | 21 |
const hemiLight = new T.HemisphereLight(0xffffff, 0xffffff, 0.6);
|
18 | 22 |
hemiLight.color.setHSL(0.6, 1, 0.6);
|
19 | 23 |
hemiLight.groundColor.setHSL(0.095, 1, 0.75);
|
|
27 | 31 |
scene.add(dirLight);
|
28 | 32 |
|
29 | 33 |
const camera = new T.PerspectiveCamera(75, 1, 0.1, 1000);
|
30 | |
camera.position.set(80, 100, 200);
|
|
34 |
camera.position.set(-30, 400, 80);
|
31 | 35 |
const controls = new OrbitControls(camera, canvas);
|
32 | 36 |
// const context = canvas.getContext('webgl2', { alpha: false });
|
33 | 37 |
const renderer = new T.WebGLRenderer({ canvas }); // , context });
|
|
76 | 80 |
dip: finger.dipPosition,
|
77 | 81 |
pip: finger.pipPosition,
|
78 | 82 |
});
|
79 | |
console.log(this.dataPoints.length);
|
80 | 83 |
}
|
81 | 84 |
|
82 | 85 |
this.tip.position.set(...finger.tipPosition);
|
|
84 | 87 |
this.lineGeometry.vertices[1].set(...finger.dipPosition);
|
85 | 88 |
this.lineGeometry.vertices[2].set(...finger.pipPosition);
|
86 | 89 |
this.lineGeometry.verticesNeedUpdate = true;
|
|
90 |
}
|
|
91 |
|
|
92 |
clear() {
|
|
93 |
this.dataPoints = [];
|
|
94 |
for (let i = 0; i < Finger.MAX_TRACK; i++) {
|
|
95 |
this.trackers.setMatrixAt(i, new T.Matrix4());
|
|
96 |
}
|
|
97 |
|
|
98 |
this.trackers.instanceMatrix.needsUpdate = true;
|
|
99 |
}
|
|
100 |
|
|
101 |
store() {
|
|
102 |
return this.dataPoints;
|
|
103 |
}
|
|
104 |
|
|
105 |
load(dataPoints) {
|
|
106 |
for (const dp of dataPoints) {
|
|
107 |
this.trackers.setMatrixAt(this.dataPoints.length % Finger.MAX_TRACK, new T.Matrix4().makeTranslation(...dp.tip));
|
|
108 |
this.dataPoints.push(dp);
|
|
109 |
}
|
|
110 |
|
|
111 |
this.trackers.instanceMatrix.needsUpdate = true;
|
87 | 112 |
}
|
88 | 113 |
}
|
89 | 114 |
|
|
102 | 127 |
window.F = fingers;
|
103 | 128 |
|
104 | 129 |
window.onkeydown = (e) => {
|
|
130 |
if (e.key === 'r') {
|
|
131 |
e.preventDefault();
|
|
132 |
fingers.forEach(finger => finger.clear());
|
|
133 |
return;
|
|
134 |
} else if (e.key === 's') {
|
|
135 |
e.preventDefault();
|
|
136 |
const data = fingers.map(finger => finger.store());
|
|
137 |
saveAs(new Blob([JSON.stringify(data)]), 'text/json');
|
|
138 |
} else if (e.key === 'l') {
|
|
139 |
e.preventDefault();
|
|
140 |
const input = document.createElement('input');
|
|
141 |
input.type = 'file';
|
|
142 |
input.click();
|
|
143 |
|
|
144 |
input.onchange = e => {
|
|
145 |
const reader = new FileReader();
|
|
146 |
reader.onload = e => {
|
|
147 |
const data = JSON.parse(e.target.result);
|
|
148 |
data.forEach((data, i) => fingers[i].load(data));
|
|
149 |
}
|
|
150 |
reader.readAsText(e.target.files[0]);
|
|
151 |
}
|
|
152 |
}
|
|
153 |
|
105 | 154 |
const i = +e.key;
|
106 | 155 |
|
107 | 156 |
if (i > -1 && i < 6) {
|
|
111 | 160 |
}
|
112 | 161 |
|
113 | 162 |
window.onkeyup = (e) => {
|
114 | |
e.preventDefault();
|
115 | 163 |
const i = +e.key;
|
116 | 164 |
|
117 | 165 |
if (i > -1 && i < 6) {
|