-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
124 lines (95 loc) · 3.75 KB
/
main.cpp
File metadata and controls
124 lines (95 loc) · 3.75 KB
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
#include <iostream>
#include "MovingAverageFilter.hpp"
#include "json.hpp"
#include <serial/serial.h>
#include <threepp/loaders/SVGLoader.hpp>
#include <threepp/threepp.hpp>
using namespace threepp;
namespace {
auto loadSVG() {
SVGLoader loader;
auto svgData = loader.load("knob.svg");
auto svg = Group::create();
svg->position.x = -250;
svg->scale.y *= -1;
for (const auto &data: svgData) {
auto fillColor = data.style.fill;
if (fillColor && *fillColor != "none") {
auto material = MeshBasicMaterial::create(
{{"color", data.path.color},
{"opacity", data.style.fillOpacity}});
const auto shapes = SVGLoader::createShapes(data);
auto geometry = ShapeGeometry::create(shapes);
geometry->computeBoundingBox();
geometry->center();
auto mesh = Mesh::create(geometry, material);
geometry->boundingBox->getCenter(mesh->position);
mesh->name = data.style.id;
mesh->visible = data.style.visibility;
svg->add(mesh);
}
}
return svg;
}
}// namespace
int main(int argc, char **argv) {
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <port>" << std::endl;
return 1;
}
std::string port(argv[1]);
std::unique_ptr<serial::Serial> serial;
try {
serial = std::make_unique<serial::Serial>(port, 115200, serial::Timeout::simpleTimeout(1000));
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
return 1;
}
Canvas canvas("Knob", {{"aa", 4}});
GLRenderer renderer(canvas.size());
Scene scene;
scene.background = Color::grey;
float frustumSize = 1000;
OrthographicCamera camera(-frustumSize * canvas.aspect() / 2, frustumSize * canvas.aspect() / 2, frustumSize / 2, -frustumSize / 2, 0.1, 1000);
camera.position.z = 1;
canvas.onWindowResize([&](WindowSize size) {
camera.left = -frustumSize * size.aspect() / 2;
camera.right = frustumSize * size.aspect() / 2;
camera.updateProjectionMatrix();
renderer.setSize(size);
});
auto circleGeometry = CircleGeometry::create(50, 32);
auto circle = Mesh::create(circleGeometry, MeshBasicMaterial::create({{"color", Color::red}}));
circle->position.set(500, 400, 0);
scene.add(circle);
auto svg1 = loadSVG();
svg1->children.back()->geometry()->rotateZ(math::degToRad(45));
auto knob1 = svg1->getObjectByName("knob");
scene.add(svg1);
auto svg2 = loadSVG();
svg2->position.y = 500;
svg2->children.back()->geometry()->rotateZ(math::degToRad(45));
auto knob2 = svg2->getObjectByName("knob");
scene.add(svg2);
Clock clock;
MovingAverageFilter filter(5);
canvas.animate([&]() {
if (knob1 && serial->isOpen() && serial->available()) {
const auto line = serial->readline();
try {
nlohmann::json j = nlohmann::json::parse(line);
const auto p1 = j["potVal1"].get<float>();
const auto p2 = j["potVal2"].get<float>();
if (j["buttonPressed"].get<int>()) {
circle->material()->as<MaterialWithColor>()->color.randomize();
}
filter.update(p1);
knob1->rotation.z = math::mapLinear(filter.value(), 0, 1023, math::PI, math::PI * 2);
knob2->rotation.z = math::mapLinear(p2, 0, 1023, math::PI, math::PI * 2);
} catch (const std::exception &ex) {
std::cerr << ex.what() << std::endl;
}
}
renderer.render(scene, camera);
});
}