-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathgui_client.cpp
More file actions
122 lines (114 loc) · 3.95 KB
/
gui_client.cpp
File metadata and controls
122 lines (114 loc) · 3.95 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
#include <mujoco/mjui.h>
#include <functional>
#include <iostream>
#include "glfw_adapter.h"
#include "gui.h"
#include "platform_ui_adapter.h"
namespace rcs {
namespace sim {
using namespace boost::interprocess;
void event_callback(mjuiState*);
class GuiClient {
public:
GuiClient(const std::string& id);
void render_loop();
mjvCamera cam;
mjvOption opt;
mjvScene scn;
mjModel* m;
mjData* d;
mujoco::PlatformUIAdapter* platform_ui;
private:
const std::string& id;
struct shm shm;
};
GuiClient::GuiClient(const std::string& id)
: shm{.manager{open_only, id.c_str()},
.state_lock{open_only, (id + STATE_LOCK_POSTFIX).c_str()},
.info_lock{open_only, (id + INFO_LOCK_POSTFIX).c_str()}},
id{id} {
// setup shared memory
std::tie(this->shm.info_byte, std::ignore) =
this->shm.manager.find<bool>(INFO_BYTE);
std::tie(this->shm.state.ptr, this->shm.state.size) =
this->shm.manager.find<mjtNum>(STATE);
std::tie(this->shm.model.ptr, this->shm.model.size) =
this->shm.manager.find<char>(MODEL);
// initialize model and data from shared memory
mjVFS* vfs = (mjVFS*)mju_malloc(sizeof(mjVFS));
mj_defaultVFS(vfs);
int failed = mj_addBufferVFS(vfs, "model.mjb", this->shm.model.ptr,
this->shm.model.size);
if (failed != 0) {
mju_free(vfs);
throw std::runtime_error("Could not add file to VFS");
}
this->m = mj_loadModel("model.mjb", vfs);
mju_free(vfs);
this->d = mj_makeData(m);
this->shm.state_lock.lock_sharable();
mj_setState(this->m, this->d, this->shm.state.ptr, MJ_PHYSICS_SPEC);
this->shm.state_lock.unlock_sharable();
mj_step(this->m, this->d);
// start UI window
this->platform_ui = new mujoco::GlfwAdapter();
this->render_loop();
}
void GuiClient::render_loop() {
mjv_defaultFreeCamera(this->m, &this->cam);
mjv_defaultOption(&this->opt);
mjv_defaultScene(&this->scn);
size_t max_geoms = 2000;
mjv_makeScene(this->m, &this->scn, max_geoms);
mjrRect viewport = {0, 0, 0, 0};
this->platform_ui->RefreshMjrContext(this->m, mjFONTSCALE_100);
this->platform_ui->SetVSync(true);
this->platform_ui->state().userdata = this;
this->platform_ui->state().nrect = 1;
this->platform_ui->SetEventCallback(event_callback);
while (!this->platform_ui->ShouldCloseWindow()) {
this->platform_ui->PollEvents();
this->shm.state_lock.lock_sharable();
mj_setState(this->m, this->d, this->shm.state.ptr, MJ_PHYSICS_SPEC);
this->shm.state_lock.unlock_sharable();
mj_step(this->m, this->d);
mjv_updateScene(this->m, this->d, &this->opt, NULL, &this->cam, mjCAT_ALL,
&this->scn);
std::tie(viewport.width, viewport.height) =
this->platform_ui->GetFramebufferSize();
mjr_render(viewport, &this->scn, &this->platform_ui->mjr_context());
this->shm.info_lock.lock();
*this->shm.info_byte = true;
this->shm.info_lock.unlock();
this->platform_ui->SwapBuffers();
}
}
void open_gui_window(std::string& id) {
rcs::sim::GuiClient gui = rcs::sim::GuiClient(id);
gui.render_loop();
}
void event_callback(mjuiState* state) {
GuiClient* client = static_cast<GuiClient*>(state->userdata);
mjrRect viewport = {0, 0, 0, 0};
std::tie(viewport.width, viewport.height) =
client->platform_ui->GetFramebufferSize();
switch (state->type) {
case mjEVENT_SCROLL:
mjv_moveCamera(client->m, mjMOUSE_ZOOM, 0, -0.02 * state->sy,
&client->scn, &client->cam);
case mjEVENT_MOVE:
// determine action based on mouse button
mjtMouse action;
if (state->right) {
action = state->shift ? mjMOUSE_MOVE_H : mjMOUSE_MOVE_V;
} else if (state->left) {
action = state->shift ? mjMOUSE_ROTATE_H : mjMOUSE_ROTATE_V;
} else {
action = mjMOUSE_ZOOM;
}
mjv_moveCamera(client->m, action, state->dx / viewport.height,
-state->dy / viewport.height, &client->scn, &client->cam);
}
}
} // namespace sim
} // namespace rcs