cgv
Loading...
Searching...
No Matches
vr_emulator.cxx
1#include "vr_emulator.h"
2#include <cgv/math/ftransform.h>
3#include <cgv/math/pose.h>
4#include <cgv/utils/scan.h>
5#include <cgv/gui/key_event.h>
6#include <cgv/gui/trigger.h>
7#include <cgv_reflect_types/math/fvec.h>
8#include <cgv_reflect_types/math/quaternion.h>
9#include <cg_vr/vr_server.h>
11#include <cg_gamepad/gamepad_server.h>
12
13const float Body_height = 1740.0f;
14const float Eye_height = 1630.0f;
15const float Chin_height = 1530.0f;
16const float Shoulder_height = 1425.0f;
17const float Shoulder_breadth = 485.0f;
18const float Arm_span = 1790.0f;
19const float Arm_length = 790.0f;
20const float Hip_width = 360.0f;
21const float Hip_height = 935.0f;
22const float Elbow_height = 1090.0f;
23const float Hand_height = 755.0f;
24const float Reach_Upwards = 2060.0f;
25const float Pupillary_distance = 63.0f;
26
28{
29 cgv::mat3 R;
30 orientation.put_matrix(R);
32 P.set_col(0, R.col(0));
33 P.set_col(1, R.col(1));
34 P.set_col(2, R.col(2));
35 P.set_col(3, position);
36 return P;
37}
38
39cgv::mat4 vr_emulated_kit::construct_homogeneous_matrix(const quat& orientation, const cgv::vec3& position)
40{
41 cgv::mat3 R;
42 orientation.put_matrix(R);
43 cgv::mat4 H;
44 H.set_col(0, cgv::vec4(R(0, 0), R(1, 0), R(2, 0), 0));
45 H.set_col(1, cgv::vec4(R(0, 1), R(1, 1), R(2, 1), 0));
46 H.set_col(2, cgv::vec4(R(0, 2), R(1, 2), R(2, 2), 0));
47 H.set_col(3, cgv::vec4(position(0), position(1), position(2), 1.0f));
48 return H;
49}
50
51cgv::vec3 vr_emulated_kit::get_body_direction() const
52{
53 cgv::vec3 up_dir;
54 cgv::vec3 x_dir, z_dir;
55 driver->put_x_direction(&x_dir(0));
56 driver->put_up_direction(&up_dir(0));
57 z_dir = cross(x_dir, up_dir);
58 return -sin(body_direction)*x_dir + cos(body_direction)*z_dir;
59}
60
61void vr_emulated_kit::compute_state_poses()
62{
63 float scale = body_height / Body_height;
64 cgv::vec3 up_dir;
65 cgv::vec3 x_dir, z_dir;
66 driver->put_x_direction(&x_dir(0));
67 driver->put_up_direction(&up_dir(0));
68 z_dir = cross(x_dir, up_dir);
69 cgv::mat4 T_body;
70 T_body.set_col(0, cgv::vec4(cos(body_direction)*x_dir + sin(body_direction)*z_dir, 0));
71 T_body.set_col(1, cgv::vec4(up_dir, 0));
72 T_body.set_col(2, cgv::vec4(-sin(body_direction)*x_dir + cos(body_direction)*z_dir,0));
73 T_body.set_col(3, cgv::vec4(body_position, 1));
74 cgv::mat4 T_hip =
75 cgv::math::translate4<float>(cgv::vec3(0,scale*Hip_height,0))*
76 cgv::math::rotate4<float>(-60*hip_parameter, cgv::vec3(1, 0, 0));
77 cgv::mat4 T_head =
78 cgv::math::translate4<float>(cgv::vec3(0, scale*(Chin_height - Hip_height), 0))*
79 cgv::math::rotate4<float>(-90*yaw_parameter, cgv::vec3(0, 1, 0));
80 cgv::mat4 R;
81 hand_orientation[0].put_homogeneous_matrix(R);
82 cgv::mat4 T_left =
83 cgv::math::translate4<float>(
84 scale* cgv::vec3((-Shoulder_breadth + Arm_length * hand_position[0](0)),
85 Shoulder_height - Hip_height + Arm_length * hand_position[0](1),
86 Arm_length*hand_position[0](2)))*R;
87 hand_orientation[1].put_homogeneous_matrix(R);
88 cgv::mat4 T_right =
89 cgv::math::translate4<float>(
90 scale*cgv::vec3(+(Shoulder_breadth + Arm_length * hand_position[1](0)),
91 Shoulder_height - Hip_height + Arm_length * hand_position[1](1),
92 Arm_length*hand_position[1](2)))*R;
93
94 set_pose_matrix(T_body*T_hip*T_head, state.hmd.pose);
95 set_pose_matrix(T_body*T_hip*T_left, state.controller[0].pose);
96 set_pose_matrix(T_body*T_hip*T_right, state.controller[1].pose);
97 static unsigned ts = 1;
98 ++ts;
99 state.controller[0].time_stamp = ts;
100 state.controller[1].time_stamp = ts;
101 for (int i = 0; i < 4; ++i) {
102 if (!tracker_enabled[i]) {
103 state.controller[2 + i].status = vr::VRS_DETACHED;
104 continue;
105 }
106 cgv::mat4 T = construct_homogeneous_matrix(tracker_orientations[i], tracker_positions[i]);
107 switch (tracker_attachments[i]) {
108 case TA_HEAD: T = T_body * T_hip*T_head*T; break;
109 case TA_LEFT_HAND: T = T_body * T_hip*T_left*T; break;
110 case TA_RIGHT_HAND: T = T_body * T_hip*T_right*T; break;
111 }
112 set_pose_matrix(T, state.controller[2 + i].pose);
113 state.controller[2 + i].status = vr::VRS_TRACKED;
114 state.controller[2 + i].time_stamp = ts;
115 }
116}
117
118vr_emulated_kit::vr_emulated_kit(float _body_direction, const cgv::vec3& _body_position, float _body_height, unsigned _width, unsigned _height, vr::vr_driver* _driver, void* _handle, const std::string& _name, int _nr_trackers)
119 : vr_kit(_driver, _handle, _name, _width, _height)
120{
121 body_position = _body_position;
122 body_direction=_body_direction;
123 body_height = _body_height;
124 hip_parameter= 0;
125 yaw_parameter = 0;
126 fovy = 90;
127 hand_position[0] = cgv::vec3(0, -0.5f, -0.2f);
128 hand_position[1] = cgv::vec3(0, -0.5f, -0.2f);
129 hand_orientation[0] = quat(1, 0, 0, 0);
130 hand_orientation[1] = quat(1, 0, 0, 0);
131 state.hmd.status = vr::VRS_TRACKED;
134
135 for (int i=0; i<4; ++i)
136 tracker_enabled[i] = i < _nr_trackers;
137
138 tracker_positions[0] = cgv::vec3(0.2f, 1.2f, 0.0f);
139 tracker_positions[1] = cgv::vec3(-0.2f, 1.2f, 0.0f);
140 tracker_positions[2] = cgv::vec3(-0.6f, 1.2f, 0.0f);
141 tracker_positions[3] = cgv::vec3(0.6f, 1.2f, 0.0f);
142 tracker_orientations[0] = tracker_orientations[1] = tracker_orientations[2] = tracker_orientations[3] = quat(0.71f,-0.71f,0,0);
143 tracker_attachments[0] = tracker_attachments[1] = tracker_attachments[2] = tracker_attachments[3] = TA_WORLD;
145 info.hmd.device_class = 1234;
146 info.hmd.device_type = "vr kit";
149 info.hmd.ipd = 0.06f;
153 info.hmd.fps = 60;
154 for (int ci = 0; ci < 6; ++ci) {
155 if (ci < 2) {
156 info.controller[ci].type = vr::VRC_CONTROLLER;
157 info.controller[ci].role = ci == 0 ? vr::VRC_LEFT_HAND : vr::VRC_RIGHT_HAND;
158 info.controller[ci].nr_axes = 3;
159 info.controller[ci].nr_inputs = 2;
160 info.controller[ci].input_type[0] = vr::VRI_PAD;
161 info.controller[ci].input_type[1] = vr::VRI_TRIGGER;
162 info.controller[ci].axis_type[0] = vr::VRA_PAD_X;
163 info.controller[ci].axis_type[1] = vr::VRA_PAD_Y;
164 info.controller[ci].axis_type[2] = vr::VRA_TRIGGER;
166 }
167 else
168 info.controller[ci].type = vr::VRC_TRACKER;
169
170 info.controller[ci].model_number = ci < 2 ? 2 : 6;
171 info.controller[ci].is_wireless = true;
172 info.controller[ci].device_class = 444;
173 info.controller[ci].device_type = ci < 2 ? "emul_controller" : "emul_tracker";
175 }
176 compute_state_poses();
177}
178
179const std::vector<std::pair<int, int> >& vr_emulated_kit::get_controller_throttles_and_sticks(int controller_index) const
180{
181 static std::vector<std::pair<int, int> > throttles_and_sticks;
182 if (throttles_and_sticks.empty()) {
183 // add stick
184 throttles_and_sticks.push_back(std::pair<int, int>(0, 1));
185 // add trigger throttle
186 throttles_and_sticks.push_back(std::pair<int, int>(2, -1));
187 }
188 return throttles_and_sticks;
189}
190
191const std::vector<std::pair<float, float> >& vr_emulated_kit::get_controller_throttles_and_sticks_deadzone_and_precision(int controller_index) const
192{
193 static std::vector<std::pair<float, float> > deadzone_and_precision;
194 if (deadzone_and_precision.empty()) {
195 deadzone_and_precision.push_back(std::pair<float, float>(0.1f, 0.01f));
196 deadzone_and_precision.push_back(std::pair<float, float>(0.0f, 0.2f));
197 }
198 return deadzone_and_precision;
199}
200
201
202void vr_emulated_kit::set_pose_matrix(const cgv::mat4& H, float* pose) const
203{
204 pose[0] = H(0, 0);
205 pose[1] = H(1, 0);
206 pose[2] = H(2, 0);
207 pose[3] = H(0, 1);
208 pose[4] = H(1, 1);
209 pose[5] = H(2, 1);
210 pose[6] = H(0, 2);
211 pose[7] = H(1, 2);
212 pose[8] = H(2, 2);
213 pose[9] = H(0, 3);
214 pose[10] = H(1, 3);
215 pose[11] = H(2, 3);
216}
217
219{
220 compute_state_poses();
221 state = this->state;
222 const vr_emulator* vr_em_ptr = dynamic_cast<const vr_emulator*>(get_driver());
223 if (vr_em_ptr) {
224 // transform state with coordinate transformation
225 cgv::mat3x4 coordinate_transform;
226 vr_em_ptr->coordinate_rotation.put_matrix(reinterpret_cast<cgv::mat3&>(coordinate_transform));
227 reinterpret_cast<cgv::vec3&>(coordinate_transform(0, 3)) = vr_em_ptr->coordinate_displacement;
228 cgv::math::pose_transform(coordinate_transform, reinterpret_cast<cgv::mat3x4&>(state.hmd.pose[0]));
229 for (int ci = 0; ci < 6; ++ci)
230 cgv::math::pose_transform(coordinate_transform, reinterpret_cast<cgv::mat3x4&>(state.controller[ci].pose[0]));
231 }
232 return true;
233}
234
235bool vr_emulated_kit::set_vibration(unsigned controller_index, float low_frequency_strength, float high_frequency_strength)
236{
237 state.controller[controller_index].vibration[0] = low_frequency_strength;
238 state.controller[controller_index].vibration[1] = high_frequency_strength;
240}
241
242void vr_emulated_kit::put_eye_to_head_matrix(int eye, float* pose_matrix) const
243{
244 float scale = body_height / Body_height;
245 set_pose_matrix(
246 cgv::math::translate4<float>(
247 scale*cgv::vec3(float(eye - 0.5f)*Pupillary_distance, Eye_height - Chin_height, -Pupillary_distance)
248 ), pose_matrix
249 );
250}
251
252void vr_emulated_kit::put_projection_matrix(int eye, float z_near, float z_far, float* projection_matrix, const float*) const
253{
254 reinterpret_cast<cgv::mat4&>(*projection_matrix) =
255 cgv::math::perspective4<float>(fovy, float(width)/height, z_near, z_far);
256}
257
259{
260
261}
262
264vr_emulator::vr_emulator() : cgv::base::node("vr_emulator")
265{
266 current_kit_index = -1;
267 interaction_mode = IM_BODY;
268
269 left_ctrl = right_ctrl = up_ctrl = down_ctrl = false;
270 home_ctrl = end_ctrl = pgup_ctrl = pgdn_ctrl = false;
271 installed = true;
272 body_speed = 1.0f;
273 body_position = cgv::vec3(0, 0, 1);
274 body_height = 1.75f;
275 body_direction = 0;
276 screen_width = 640;
277 screen_height = 480;
278 counter = 0;
279
280 coordinate_rotation = cgv::quat(1,0,0,0);
281 coordinate_displacement = cgv::vec3(0.0f);
282
283 ref_tracking_reference_state("vr_emulator_base_01").status = vr::VRS_TRACKED;
284 cgv::mat3& ref_ori_1 = reinterpret_cast<cgv::mat3&>(*ref_tracking_reference_state("vr_emulator_base_01").pose);
285
286 base_orientations.push_back(cgv::quat(cgv::math::rotate3<float>(cgv::vec3(-20.0f, 45.0f, 0))));
287 base_positions.push_back(cgv::vec3(1.0f, 2.0f, 1.0f));
288 base_serials.push_back("vr_emulator_base_01");
289
290 base_orientations.push_back(cgv::quat(cgv::math::rotate3<float>(cgv::vec3(-20.0f, -45.0f, 0))));
291 base_positions.push_back(cgv::vec3(-1.0f, 2.0f, 1.0f));
292 base_serials.push_back("vr_emulator_base_02");
293
294 update_reference_states();
295
296 connect(cgv::gui::get_animation_trigger().shoot, this, &vr_emulator::timer_event);
297}
298
301{
302 int ib = i, ie = i + 1;
303 if (i == -1) {
304 ib = 0;
305 ie = (int)base_serials.size();
306 }
307 cgv::mat3x4 coordinate_transform = pose_construct(coordinate_rotation, coordinate_displacement);
308 for (int k = ib; k < ie; ++k) {
309 auto& pose = reinterpret_cast<cgv::mat3x4&>(ref_tracking_reference_state(base_serials[k]).pose[0]);
311 base_orientations[k].put_matrix(pose_orientation(pose));
312 pose_position(pose) = base_positions[k];
313 pose_transform(coordinate_transform, pose);
314 }
315}
316
317void vr_emulator::timer_event(double t, double dt)
318{
319 if (current_kit_index >= 0 && current_kit_index < (int)kits.size()) {
320 switch (interaction_mode)
321 {
322 case IM_BODY:
323 if (left_ctrl || right_ctrl) {
324 if (is_alt)
325 kits[current_kit_index]->body_position -= (float)(left_ctrl ? -dt : dt) * cross(kits[current_kit_index]->get_body_direction(), cgv::vec3(0, 1, 0));
326 else
327 kits[current_kit_index]->body_direction += 3 * (float)(left_ctrl ? -dt : dt);
329 post_redraw();
330 }
331 if (up_ctrl || down_ctrl) {
332 kits[current_kit_index]->body_position -= (float)(down_ctrl ? -dt : dt) * kits[current_kit_index]->get_body_direction();
334 post_redraw();
335 }
336 if (home_ctrl || end_ctrl) {
337 kits[current_kit_index]->yaw_parameter += (float)(home_ctrl ? -dt : dt);
338 if (kits[current_kit_index]->yaw_parameter < -1)
339 kits[current_kit_index]->yaw_parameter = -1;
340 else if (kits[current_kit_index]->yaw_parameter > 1)
341 kits[current_kit_index]->yaw_parameter = 1;
343 post_redraw();
344 }
345 if (pgup_ctrl || pgdn_ctrl) {
346 kits[current_kit_index]->hip_parameter += (float)(pgup_ctrl ? -dt : dt);
347 if (kits[current_kit_index]->hip_parameter < -1)
348 kits[current_kit_index]->hip_parameter = -1;
349 else if (kits[current_kit_index]->hip_parameter > 1)
350 kits[current_kit_index]->hip_parameter = 1;
352 post_redraw();
353 }
354 break;
355 case IM_LEFT_HAND:
356 case IM_RIGHT_HAND:
357 if (home_ctrl || end_ctrl) {
358 float& value = kits[current_kit_index]->state.controller[interaction_mode - IM_LEFT_HAND].axes[2];
359 value += 1.0f * float(home_ctrl ? -dt : dt);
360 value = std::max(std::min(1.0f, value), 0.0f);
361 update_member(&value);
362 post_redraw();
363 break;
364 }
365 case IM_TRACKER_1:
366 case IM_TRACKER_2:
367 case IM_TRACKER_3:
368 case IM_TRACKER_4:
369 case IM_BASE_1:
370 case IM_BASE_2:
371 case IM_BASE_3:
372 case IM_BASE_4:
373 {
374 cgv::quat* orientation_ptr = 0;
375 cgv::vec3* position_ptr = 0;
376 if (interaction_mode < IM_TRACKER_1) {
377 orientation_ptr = &kits[current_kit_index]->hand_orientation[interaction_mode - IM_LEFT_HAND];
378 position_ptr = &kits[current_kit_index]->hand_position[interaction_mode - IM_LEFT_HAND];
379 }
380 else if (interaction_mode < IM_BASE_1) {
381 orientation_ptr = &kits[current_kit_index]->tracker_orientations[interaction_mode - IM_TRACKER_1];
382 position_ptr = &kits[current_kit_index]->tracker_positions[interaction_mode - IM_TRACKER_1];
383 }
384 else {
385 orientation_ptr = &base_orientations[interaction_mode - IM_BASE_1];
386 position_ptr = &base_positions[interaction_mode - IM_BASE_1];
387 }
388 if (left_ctrl || right_ctrl) {
389 if (is_alt)
390 (*position_ptr)[0] += 0.3f * (float)(left_ctrl ? -dt : dt);
391 else
392 *orientation_ptr = cgv::quat(cgv::vec3(0, 1, 0), (float)(right_ctrl ? -dt : dt))*(*orientation_ptr);
394 post_redraw();
395 }
396 if (up_ctrl || down_ctrl) {
397 if (is_alt)
398 (*position_ptr)[1] += 0.3f * (float)(down_ctrl ? -dt : dt);
399 else
400 *orientation_ptr = cgv::quat(cgv::vec3(1, 0, 0), (float)(up_ctrl ? -dt : dt))*(*orientation_ptr);
402 post_redraw();
403 }
404 if (pgup_ctrl || pgdn_ctrl) {
405 if (is_alt)
406 (*position_ptr)[2] += 0.3f * (float)(pgup_ctrl ? -dt : dt);
407 else
408 *orientation_ptr = cgv::quat(cgv::vec3(0, 0, 1), (float)(pgup_ctrl ? -dt : dt))*(*orientation_ptr);
410 post_redraw();
411 }
412 if (interaction_mode >= IM_BASE_1) {
413 if (is_alt)
414 on_set(position_ptr);
415 else
416 on_set(orientation_ptr);
417 }
418 break;
419 }
420 }
421 }
422}
423
425void vr_emulator::on_set(void* member_ptr)
426{
427 if (member_ptr == &current_kit_index) {
428 while (current_kit_index >= (int)kits.size())
429 add_new_kit();
430 }
431 if (!base_serials.empty()) {
432 for (int i = 0; i < (int)base_serials.size(); ++i)
433 if (member_ptr >= &base_orientations[i] && member_ptr < &base_orientations[i]+1 ||
434 member_ptr >= &base_positions[i] && member_ptr < &base_positions[i]+1)
436 }
437 update_member(member_ptr);
438 post_redraw();
439}
440
443{
444 return name;
445}
446
449{
450 return installed;
451}
452
453bool vr_emulator::gamepad_connected = false;
454
455void vr_emulator::add_new_kit()
456{
457 if (!gamepad_connected) {
458 gamepad_connected = true;
460 }
461 ++counter;
462 void* handle = 0;
463 (unsigned&)handle = counter;
464 vr_emulated_kit* new_kit = new vr_emulated_kit(body_direction, body_position, body_height,
465 screen_width, screen_height, this, handle,
466 std::string("vr_emulated_kit[") + cgv::utils::to_string(counter) + "]", nr_trackers);
467 kits.push_back(new_kit);
468 register_vr_kit(handle, new_kit);
469 if (current_kit_index == -1) {
470 current_kit_index = int(kits.size()) - 1;
471 update_member(&current_kit_index);
472 }
475}
476
478std::vector<void*> vr_emulator::scan_vr_kits()
479{
480 std::vector<void*> result;
481 if (is_installed())
482 for (auto kit_ptr : kits)
483 result.push_back(kit_ptr->get_handle());
484 return result;
485}
486
489{
490 if (!is_installed())
491 return 0;
492
493 for (auto kit_ptr : kits) {
494 if (index == 0) {
495 replace_vr_kit(kit_ptr->get_handle(), new_kit_ptr);
496 return kit_ptr;
497 }
498 else
499 --index;
500 }
501 return 0;
502}
505{
506 if (!is_installed())
507 return false;
508
509 for (auto kit_ptr : kits) {
510 if (kit_ptr == old_kit_ptr || vr::get_vr_kit(kit_ptr->get_handle()) == old_kit_ptr) {
511 replace_vr_kit(kit_ptr->get_handle(), new_kit_ptr);
512 return true;
513 }
514 }
515 return false;
516}
517
519void vr_emulator::put_up_direction(float* up_dir) const
520{
521 reinterpret_cast<cgv::vec3&>(*up_dir) = cgv::vec3(0, 1, 0);
522}
523
526{
527 return 0;
528}
529
532{
533 return 2.5f;
534}
535
537void vr_emulator::put_action_zone_bounary(std::vector<float>& boundary) const
538{
539 boundary.resize(18);
540 for (unsigned i = 0; i < 6; ++i) {
541 float angle = float(2 * M_PI*i / 6);
542 cgv::vec3 pi(1.5f*cos(angle), 0, 2.5f*sin(angle));
543 reinterpret_cast<cgv::vec3&>(boundary[3 * i]) = pi;
544 }
545}
546bool vr_emulator::check_for_button_toggle(cgv::gui::key_event& ke, int controller_index, vr::VRButtonStateFlags button, float touch_x, float touch_y)
547{
548 if (current_kit_index == -1)
549 return false;
550 if (current_kit_index >= (int)kits.size())
551 return false;
552 if (ke.get_action() != cgv::gui::KA_PRESS)
553 return false;
554 if (ke.get_modifiers() == cgv::gui::EM_SHIFT) {
555 kits[current_kit_index]->state.controller[controller_index].axes[0] = touch_x;
556 kits[current_kit_index]->state.controller[controller_index].axes[1] = touch_y;
557 }
558 else if (ke.get_modifiers() == 0)
559 kits[current_kit_index]->state.controller[controller_index].button_flags ^= button;
560 else
561 return false;
563 return true;
564}
565
566bool vr_emulator::handle_ctrl_key(cgv::gui::key_event& ke, bool& fst_ctrl, bool* snd_ctrl_ptr)
567{
568 if (current_kit_index == -1)
569 return false;
570
571 if (snd_ctrl_ptr && (ke.get_modifiers() & cgv::gui::EM_SHIFT) != 0) {
572 *snd_ctrl_ptr = (ke.get_action() != cgv::gui::KA_RELEASE);
573 update_member(snd_ctrl_ptr);
574 }
575 else {
576 fst_ctrl = (ke.get_action() != cgv::gui::KA_RELEASE);
577 update_member(&fst_ctrl);
578 }
579 is_alt = (ke.get_action() != cgv::gui::KA_RELEASE) && ((ke.get_modifiers() & cgv::gui::EM_ALT) != 0);
580 update_member(&is_alt);
581 return true;
582}
583
586{
587 if (e.get_kind() != cgv::gui::EID_KEY)
588 return false;
589 cgv::gui::key_event& ke = static_cast<cgv::gui::key_event&>(e);
590 switch (ke.get_key()) {
591 case 'N' :
592 if (ke.get_action() == cgv::gui::KA_PRESS &&
594 add_new_kit();
595 return true;
596 }
597 return false;
598 case '0':
599 case '1':
600 case '2':
601 case '3':
602 if (ke.get_modifiers() == cgv::gui::EM_SHIFT) {
603 if (ke.get_action() != cgv::gui::KA_RELEASE) {
604 current_kit_index = ke.get_key() - '0';
605 if (current_kit_index >= (int)kits.size())
606 current_kit_index = -1;
607 update_member(&current_kit_index);
608 }
609 return true;
610 }
611 case '4':
612 case '5':
613 case '6':
614 case '7':
615 case '8':
616 case '9':
617 interaction_mode = InteractionMode(IM_BODY + ke.get_key() - '0');
618 update_member(&interaction_mode);
619 return true;
620 case 'Q': return check_for_button_toggle(ke, 0, vr::VRF_SYSTEM, -1, 1);
621 case 'W': return check_for_button_toggle(ke, 0, vr::VRF_MENU, 0, 1);
622 case 'E': return check_for_button_toggle(ke, 0, vr::VRF_A, 1, 1);
623
624 case 'A': return check_for_button_toggle(ke, 0, vr::VRF_INPUT0_TOUCH, -1, 0);
625 case 'S': return check_for_button_toggle(ke, 0, vr::VRF_INPUT0, 0, 0);
626 case 'D': return check_for_button_toggle(ke, 0, vr::VRF_INPUT1_TOUCH, 1, 0);
627
628 case 'Y': return check_for_button_toggle(ke, 0, vr::VRF_GRIP, -1, -1);
629 case 'X': return check_for_button_toggle(ke, 0, vr::VRF_GRIP, 0, -1);
630 case 'C': return check_for_button_toggle(ke, 0, vr::VRF_INPUT1, 1, -1);
631
632
633 case 'U': return check_for_button_toggle(ke, 1, vr::VRF_SYSTEM, -1, 1);
634 case 'I': return check_for_button_toggle(ke, 1, vr::VRF_MENU, 0, 1);
635 case 'O': return check_for_button_toggle(ke, 1, vr::VRF_A, 1, 1);
636
637 case 'J': return check_for_button_toggle(ke, 1, vr::VRF_INPUT0_TOUCH, -1, 0);
638 case 'K': return check_for_button_toggle(ke, 1, vr::VRF_INPUT0, 0, 0);
639 case 'L': return check_for_button_toggle(ke, 1, vr::VRF_INPUT1_TOUCH, 1, 0);
640
641 case 'M': return check_for_button_toggle(ke, 1, vr::VRF_GRIP, -1, -1);
642 case ',': return check_for_button_toggle(ke, 1, vr::VRF_GRIP, 0, -1);
643 case '.': return check_for_button_toggle(ke, 1, vr::VRF_INPUT1, 1, -1);
644
647 return handle_ctrl_key(ke, left_ctrl, &home_ctrl);
650 return handle_ctrl_key(ke, right_ctrl, &end_ctrl);
651 case cgv::gui::KEY_Up:
653 return handle_ctrl_key(ke, up_ctrl, &pgup_ctrl);
656 return handle_ctrl_key(ke, down_ctrl, &pgdn_ctrl);
659 return handle_ctrl_key(ke, home_ctrl);
662 return handle_ctrl_key(ke, end_ctrl);
665 return handle_ctrl_key(ke, pgup_ctrl);
668 return handle_ctrl_key(ke, pgdn_ctrl);
669 }
670 return false;
671}
673void vr_emulator::stream_help(std::ostream& os)
674{
675 os << "vr_emulator:\n"
676 << " Ctrl-Alt-N to create vr kit indexed from 0\n"
677 << " Shift-<0-3> to select to be controlled vr kit (unselect if key's kit not exits)\n"
678 << " <0-9> select <body|left hand|right hand|tracker 1|tracker 2|tracker 3|tracker 4|base 1|base 2|base 3> for control\n"
679 << " body: <up|down> .. move, <left|right> .. turn, <pgup|pgdn> .. bend, \n"
680 << " <home|end> .. gear, <alt>+<left|right> .. side step\n"
681 << " hand: <home|end> .. trigger\n"
682 << " hand&tracker: <left|right|up|down|pgdn|pgup> .. rotate or with <alt> translate\n"
683 << " <Q|W|E|A|S|D|Y|X|C:U|I|O|J|K|L|M|,|.> toggle left:right controller buttons\n"
684 << " <System|Menu|A|Touch0|Press0|Touch1|Grip|Grip|Press1>; adjust TP position with Shift\n"
685 << " <Shift>-<QWE:ASD:YXC>|<UIO:HJK:BNM> to set left:right controller touch xy to -1|0|+1\n"
686 << std::endl;
687}
689std::string vr_emulator::get_type_name() const
690{
691 return "vr_emulator";
692}
694void vr_emulator::stream_stats(std::ostream& os)
695{
696 static std::string i_modes("body,left hand,right hand,tracker 1,tracker 2,tracker 3,tracker 4,base 1, base 2,base 3, base 4");
697 os << "vr_emulator: [" << cgv::utils::get_element(i_modes, (int)interaction_mode, ',') << "]" << std::endl;
698}
701{
702 return true;
703}
708{
709 for (auto kit_ptr : kits) {
710 }
711}
716{
717 bool res =
718 srh.reflect_member("current_kit_index", current_kit_index) &&
719 srh.reflect_member("installed", installed) &&
720 srh.reflect_member("create_body_direction", body_direction) &&
721 srh.reflect_member("create_body_position", body_position) &&
722 srh.reflect_member("create_nr_trackers", nr_trackers) &&
723 srh.reflect_member("body_height", body_height) &&
724 srh.reflect_member("screen_height", screen_height) &&
725 srh.reflect_member("screen_width", screen_width);
726 if (res && current_kit_index != -1 && current_kit_index < (int)kits.size()) {
727 vr_emulated_kit* kit_ptr = kits[current_kit_index];
728 res =
729 srh.reflect_member("body_direction", kit_ptr->body_direction) &&
730 srh.reflect_member("body_height", kit_ptr->body_height) &&
731 srh.reflect_member("hip_parameter", kit_ptr->hip_parameter) &&
732 srh.reflect_member("yaw_parameter", kit_ptr->yaw_parameter) &&
733 srh.reflect_member("fovy", kit_ptr->fovy) &&
734 srh.reflect_member("body_position", kit_ptr->body_position) &&
735 srh.reflect_member("left_hand_position", kit_ptr->hand_position[0]) &&
736 srh.reflect_member("right_hand_position", kit_ptr->hand_position[1]) &&
737 srh.reflect_member("tracker_1_position", kit_ptr->tracker_positions[0]) &&
738 srh.reflect_member("tracker_2_position", kit_ptr->tracker_positions[1]) &&
739 srh.reflect_member("tracker_3_position", kit_ptr->tracker_positions[2]) &&
740 srh.reflect_member("tracker_4_position", kit_ptr->tracker_positions[3]) &&
741 srh.reflect_member("tracker_1_enabled", kit_ptr->tracker_enabled[0]) &&
742 srh.reflect_member("tracker_2_enabled", kit_ptr->tracker_enabled[1]) &&
743 srh.reflect_member("tracker_3_enabled", kit_ptr->tracker_enabled[2]) &&
744 srh.reflect_member("tracker_4_enabled", kit_ptr->tracker_enabled[3]) &&
745 srh.reflect_member("tracker_1_orientation", kit_ptr->tracker_orientations[0]) &&
746 srh.reflect_member("tracker_2_orientation", kit_ptr->tracker_orientations[1]) &&
747 srh.reflect_member("tracker_3_orientation", kit_ptr->tracker_orientations[2]) &&
748 srh.reflect_member("tracker_4_orientation", kit_ptr->tracker_orientations[3]) &&
749 srh.reflect_member("left_hand_orientation", kit_ptr->hand_orientation[0]) &&
750 srh.reflect_member("right_hand_orientation", kit_ptr->hand_orientation[1]) &&
751 srh.reflect_member("tracker_1_attachment", (int&)kit_ptr->tracker_attachments[0]) &&
752 srh.reflect_member("tracker_2_attachment", (int&)kit_ptr->tracker_attachments[1]) &&
753 srh.reflect_member("tracker_3_attachment", (int&)kit_ptr->tracker_attachments[2]) &&
754 srh.reflect_member("tracker_4_attachment", (int&)kit_ptr->tracker_attachments[3]);
755 }
756 return res;
757}
758void vr_emulator::create_trackable_gui(const std::string& name, vr::vr_trackable_state& ts)
759{
760 add_decorator(name, "heading", "level=3");
761 add_member_control(this, "status", ts.status, "dropdown", "enums='detached,attached,tracked'");
762 if (begin_tree_node("pose", ts.pose[0], false, "level=3")) {
763 align("\a");
764 add_view("x.x", ts.pose[0], "value", "w=50;step=0.0001", " ");
765 add_view("x.y", ts.pose[1], "value", "w=50;step=0.0001", " ");
766 add_view("x.z", ts.pose[2], "value", "w=50;step=0.0001");
767 add_view("y.x", ts.pose[3], "value", "w=50;step=0.0001", " ");
768 add_view("y.y", ts.pose[4], "value", "w=50;step=0.0001", " ");
769 add_view("y.z", ts.pose[5], "value", "w=50;step=0.0001");
770 add_view("z.x", ts.pose[6], "value", "w=50;step=0.0001", " ");
771 add_view("z.y", ts.pose[7], "value", "w=50;step=0.0001", " ");
772 add_view("z.z", ts.pose[8], "value", "w=50;step=0.0001");
773 add_view("0.x", ts.pose[9], "value", "w=50;step=0.0001", " ");
774 add_view("0.y", ts.pose[10], "value", "w=50;step=0.0001", " ");
775 add_view("0.z", ts.pose[11], "value", "w=50;step=0.0001");
776 align("\b");
777 end_tree_node(ts.pose[0]);
778 }
779}
781{
782 create_trackable_gui(std::string("controller") + cgv::utils::to_string(i), cs);
784 add_view("time_stamp", cs.time_stamp);
785 add_member_control(this, "touch.x", cs.axes[0], "value_slider", "min=-1;max=1;ticks=true");
786 add_member_control(this, "touch.y", cs.axes[1], "value_slider", "min=-1;max=1;ticks=true");
787 add_member_control(this, "trigger", cs.axes[2], "value_slider", "min=0;max=1;ticks=true");
788 //add_view("axes[3]", cs.axes[3], "value", "w=50", " ");
789 //add_view("axes[4]", cs.axes[4], "value", "w=50", " ");
790 //add_view("axes[5]", cs.axes[5], "value", "w=50");
791 //add_view("axes[6]", cs.axes[6], "value", "w=50", " ");
792 //add_view("axes[7]", cs.axes[7], "value", "w=50");
793 add_view("vibration[0]", cs.vibration[0], "value", "w=50", " ");
794 add_view("[1]", cs.vibration[1], "value", "w=50");
795}
796void vr_emulator::create_tracker_gui(vr_emulated_kit* kit, int i)
797{
798 if (begin_tree_node(std::string("tracker_") + cgv::utils::to_string(i+1), kit->tracker_enabled[i], false, "level=3")) {
799 add_member_control(this, "enabled", kit->tracker_enabled[i], "check");
800 add_member_control(this, "attachment", kit->tracker_attachments[i], "dropdown", "enums='world,head,left hand,right hand'");
801 add_decorator("position", "heading", "level=3");
802 add_gui("position", kit->tracker_positions[i], "vector", "gui_type='value_slider';options='min=-3;max=3;step=0.0001;ticks=true'");
803 add_decorator("orientation", "heading", "level=3");
804 add_gui("orientation", reinterpret_cast<cgv::vec4&>(kit->tracker_orientations[i]), "direction", "gui_type='value_slider';options='min=-1;max=1;step=0.0001;ticks=true'");
805 end_tree_node(kit->tracker_enabled[i]);
806 }
807}
809{
810 add_decorator("vr emulator", "heading", "level=2");
811 add_member_control(this, "installed", installed, "check");
812 if (begin_tree_node("base and calib", coordinate_rotation, false, "level=2")) {
813 align("\a");
814 add_decorator("coordinate transform", "heading", "level=3");
815 add_gui("coordinate_rotation", reinterpret_cast<cgv::vec4&>(coordinate_rotation), "direction", "options='min=-1;max=1;step=0.0001;ticks=true'");
816 add_gui("coordinate_displacement", coordinate_displacement, "", "options='min=-2;max=2;step=0.0001;ticks=true'");
817 add_decorator("base stations", "heading", "level=3");
818 for (uint32_t i = 0; i < base_serials.size(); ++i) {
819 add_member_control(this, "serial", base_serials[i]);
820 add_gui("orientation", reinterpret_cast<cgv::vec4&>(base_orientations[i]), "direction", "options='min=-1;max=1;step=0.0001;ticks=true'");
821 add_gui("position", base_positions[i], "", "options='min=-2;max=2;step=0.0001;ticks=true'");
822 }
823 align("\b");
824 end_tree_node(coordinate_rotation);
825 }
826 if (begin_tree_node("create kit", screen_width, false, "level=2")) {
827 align("\a");
828 add_member_control(this, "screen_width", screen_width, "value_slider", "min=320;max=1920;ticks=true");
829 add_member_control(this, "screen_height", screen_height, "value_slider", "min=240;max=1920;ticks=true");
830 add_gui("body_position", body_position, "", "options='min=-1;max=1;step=0.0001;ticks=true'");
831 add_member_control(this, "body_direction", body_direction, "min=0;max=6.3;ticks=true");
832 add_member_control(this, "body_height", body_height, "min=1.2;max=2.0;step=0.001;ticks=true");
833 add_member_control(this, "nr_trackers", nr_trackers, "min=0;max=4;ticks=true");
834 connect_copy(add_button("create new kit")->click, cgv::signal::rebind(this, &vr_emulator::add_new_kit));
835 align("\b");
836 end_tree_node(screen_width);
837 }
838 add_view("current_kit", current_kit_index, "", "w=50", " ");
839 add_member_control(this, "mode", interaction_mode, "dropdown", "w=100;enums='body,left hand,right hand,tracker 1,tracker 2,tracker 3,tracker 4,base 1, base 2,base 3, base 4'");
840 add_member_control(this, "alt", is_alt, "toggle", "w=15", " ");
841 add_member_control(this, "L", left_ctrl, "toggle", "w=15", "");
842 add_member_control(this, "R", right_ctrl, "toggle", "w=15", " ");
843 add_member_control(this, "U", up_ctrl, "toggle", "w=15", "");
844 add_member_control(this, "D", down_ctrl, "toggle", "w=15", " ");
845 add_member_control(this, "H", home_ctrl, "toggle", "w=15", "");
846 add_member_control(this, "E", end_ctrl, "toggle", "w=15", " ");
847 add_member_control(this, "P", pgup_ctrl, "toggle", "w=15", "");
848 add_member_control(this, "p", pgdn_ctrl, "toggle", "w=15");
849
850 for (unsigned i = 0; i < kits.size(); ++i) {
851 if (begin_tree_node(kits[i]->get_name(), *kits[i], true, "level=2")) {
852 align("\a");
853 add_view("buttons left", kits[i]->fovy, "", "w=0", "");
854 add_gui("button_flags", kits[i]->state.controller[0].button_flags, "bit_field_control",
855 "enums='SY=1,ME=2,GR=4,A=128,PT=256,PP=512,TT=1024,TP=2048';options='w=16;tooltip=\""
856 "SYstem button<Q> \nMEnu button <W>\nA button <E>\n"
857 "Pad Touch <A>\nPad Press <S>\nTrigger Touch\n<D>"
858 "GRip button <Y|X>\nTrigger Press <C>\"';"
859 "align='';gui_type='toggle'");
860 align(" ");
861 add_view("Pxy", kits[i]->state.controller[0].axes[0], "", "w=16", "");
862 add_view("", kits[i]->state.controller[0].axes[1], "", "w=16");
863 add_view("buttons right", kits[i]->fovy, "", "w=0", "");
864 add_gui("button_flags", kits[i]->state.controller[1].button_flags, "bit_field_control",
865 "enums='SY=1,ME=2,GR=4,A=128,PT=256,PP=512,TT=1024,TP=2048';options='w=16;tooltip=\""
866 "SYstem button<U>\nMEnu button <I>\nA button <O>\n"
867 "Pad Touch <J>\nPad Press <K>\nTrigger Touch\n"
868 "GRip button <M|,>\nTrigger Press\"';"
869 "align='';gui_type='toggle'");
870 align(" ");
871 add_view("Pxy", kits[i]->state.controller[1].axes[0], "", "w=16", "");
872 add_view("", kits[i]->state.controller[1].axes[1], "", "w=16");
873
874 add_member_control(this, "fovy", kits[i]->fovy, "value_slider", "min=30;max=180;ticks=true;log=true");
875 if (begin_tree_node("body pose", kits[i]->body_position, false, "level=3")) {
876 align("\a");
877 add_decorator("body position", "heading", "level=3");
878 add_gui("body_position", kits[i]->body_position, "", "options='min=-5;max=5;ticks=true'");
879 add_member_control(this, "body_direction", kits[i]->body_direction, "value_slider", "min=0;max=6.3;ticks=true");
880 add_member_control(this, "body_height", kits[i]->body_height, "value_slider", "min=1.2;max=2.0;ticks=true");
881 add_member_control(this, "hip_parameter", kits[i]->hip_parameter, "value_slider", "min=-1;max=1;step=0.0001;ticks=true");
882 add_member_control(this, "yaw_parameter", kits[i]->yaw_parameter, "value_slider", "min=-1;max=1;step=0.0001;ticks=true");
883 for (int j = 0; j < 2; ++j) {
884 if (begin_tree_node(j == 0 ? "left hand" : "right hand", kits[i]->hand_position[j], false, "level=3")) {
885 align("\a");
886 add_decorator("position", "heading", "level=3");
887 add_gui("position", kits[i]->hand_position[j], "vector", "gui_type='value_slider';options='min=-3;max=3;step=0.0001;ticks=true'");
888 add_decorator("orientation", "heading", "level=3");
889 add_gui("orientation", reinterpret_cast<cgv::vec4&>(kits[i]->hand_orientation[j]), "direction", "gui_type='value_slider';options='min=-1;max=1;step=0.0001;ticks=true'");
890 align("\b");
891 end_tree_node(kits[i]->hand_position[j]);
892 }
893 }
894 align("\b");
895 end_tree_node(kits[i]->body_position);
896 }
897 create_tracker_gui(kits[i], 0);
898 create_tracker_gui(kits[i], 1);
899 create_tracker_gui(kits[i], 2);
900 create_tracker_gui(kits[i], 3);
901 if (begin_tree_node("state", kits[i]->state.controller[0].pose[1], false, "level=3")) {
902 align("\a");
903 if (begin_tree_node("hmd", kits[i]->state.hmd.pose[0], false, "level=3")) {
904 align("\a");
905 create_trackable_gui("hmd", kits[i]->state.hmd);
906 align("\b");
907 end_tree_node(kits[i]->state.hmd.pose[1]);
908 }
909 for (unsigned ci = 0; ci < 2; ++ci) {
910 if (begin_tree_node((ci==0?"left controller":"right controller"), kits[i]->state.controller[ci], false, "level=3")) {
911 align("\a");
912 create_controller_gui(ci, kits[i]->state.controller[ci]);
913 align("\b");
914 end_tree_node(kits[i]->state.controller[ci]);
915 }
916 }
917 align("\b");
918 end_tree_node(kits[i]->state.controller[0].pose[1]);
919 }
920 align("\b");
921 end_tree_node(*kits[i]);
922 }
923 }
924}
925
927{
928 register_driver_and_object(const std::string& options)
929 {
930 vr_emulator* vr_emu_ptr = new vr_emulator();
931 vr::register_driver(vr_emu_ptr);
932 register_object(cgv::base::base_ptr(vr_emu_ptr), options);
933 }
934};
935
936register_driver_and_object vr_emu_reg("vr_test");
const std::string & get_name() const
return the parent node
Definition named.cxx:9
std::string name
store the name as a string
Definition named.h:25
unsigned get_kind() const
return, what kind of event this is, typically a value from the EventId enum
Definition event.cxx:202
unsigned char get_modifiers() const
return the active modifiers as values from EventModifier combined with a logical or-operation
Definition event.cxx:237
class to represent all possible keyboard events with the EID_KEY
Definition key_event.h:23
unsigned short get_key() const
return the key being a capital letter, digit or a value from the Keys enum
Definition key_event.cxx:51
KeyAction get_action() const
return the key event action
Definition key_event.cxx:71
bool add_gui(const std::string &label, T &value, const std::string &gui_type="", const std::string &options="")
Add a composed gui of the given gui_type for the given value.
Definition provider.h:247
cgv::base::base_ptr add_decorator(const std::string &label, const std::string &decorator_type, const std::string &options="", const std::string &align="\n")
add a newly created decorator to the group
Definition provider.cxx:168
void align(const std::string &_align)
send pure alignment information
Definition provider.cxx:36
virtual void update_all_members()
call this to update all views and controls of all member
Definition provider.cxx:116
bool begin_tree_node(const std::string &label, const T &value, bool initial_visibility=false, const std::string &options="", gui_group_ptr ggp=gui_group_ptr())
Begin a sub tree of a tree structured gui.
Definition provider.h:212
virtual void update_member(void *member_ptr)
call this to update all views and controls of a member
Definition provider.cxx:72
data::ref_ptr< control< T > > add_member_control(cgv::base::base *base_ptr, const std::string &label, T &value, const std::string &gui_type="", const std::string &options="", const std::string &align="\n")
add control with callback to cgv::base::on_set method on cgv::gui::control::value_change
Definition provider.h:137
void end_tree_node(const T &value)
template specialization that allows to specify value reference plus node_instance by using the result...
Definition provider.h:222
virtual void post_recreate_gui()
delayed recreation of gui
Definition provider.cxx:509
data::ref_ptr< view< T > > add_view(const std::string &label, const T &value, const std::string &gui_type="", const std::string &options="", const std::string &align="\n")
use this to add a new view to the gui with a given value type, gui type and init options
Definition provider.h:112
button_ptr add_button(const std::string &label, const std::string &options="", const std::string &align="\n")
use the current gui driver to append a new button with the given label
Definition provider.cxx:176
static double get_current_time()
return the current time
Definition trigger.cxx:70
void check_device_changes(double time)
check which vr_kits are present and emit on_device_change events
fvec< T, N > & col(unsigned j)
reference a column of the matrix as a vector
Definition fmat.h:209
void set_col(unsigned j, const fvec< T, N > &v)
set column j of the matrix to vector v
Definition fmat.h:217
void put_homogeneous_matrix(hmat_type &M) const
compute equivalent homogeneous 4x4 rotation matrix
Definition quaternion.h:154
void put_matrix(mat_type &M) const
compute equivalent 3x3 rotation matrix
Definition quaternion.h:139
the self reflection handler is passed to the virtual self_reflect() method of cgv::base::base.
bool reflect_member(const std::string &member_name, T &member_ref, bool hard_cast=false)
call this to reflect a member by member name and reference to the member.
base class for all drawables, which is independent of the used rendering API.
Definition context.h:621
void post_redraw()
posts a redraw event to the current context if one is available
Definition drawable.cxx:43
unsigned width
pixel dimensions of render targets
interface class for vr drivers.
Definition vr_driver.h:57
void replace_vr_kit(void *handle, vr_kit *kit)
call this method during replacement of vr kits. In case vr kit handle had been registered before it i...
void register_vr_kit(void *handle, vr_kit *kit)
call this method during scanning of vr kits. In case vr kit handle had been registered before,...
vr_trackable_state & ref_tracking_reference_state(const std::string &serial_nummer)
provide reference to tracking reference states
Definition vr_driver.cxx:22
void put_x_direction(float *x_dir) const
put a 3d x direction into passed array
virtual void put_up_direction(float *up_dir) const =0
put a 3d up direction into passed array
a vr kit is composed of headset, two controllers, and two trackers, where all devices can be attached...
Definition vr_kit.h:69
vr_trackable_state & ref_tracking_reference_state(const std::string &serial_nummer)
write access to the state of the tracking reference with given serial number
Definition vr_kit.cxx:13
vr_kit_info info
store vr kit info to be filled and updated by driver implementations
Definition vr_kit.h:82
const vr_driver * get_driver() const
return driver
Definition vr_kit.cxx:48
vr_driver * driver
pointer to driver that created the vr kit
Definition vr_kit.h:72
bool set_vibration(unsigned controller_index, float low_frequency_strength, float high_frequency_strength)
set the vibration strength between 0 and 1 of low and high frequency motors, return false if device i...
void submit_frame()
submit the rendered stereo frame to the hmd
cgv::mat3x4 construct_pos_matrix(const quat &orientation, const cgv::vec3 &position)
helper functions to construct matrices
void put_projection_matrix(int eye, float z_near, float z_far, float *projection_matrix, const float *hmd_pose) const
access to 4x4 matrix in column major format for perspective transformation from eye (0....
bool query_state_impl(vr::vr_kit_state &state, int pose_query=2)
derived kits implement this without caring about calibration; vr_kit::query_state() will apply driver...
void put_eye_to_head_matrix(int eye, float *pose_matrix) const
access to 3x4 matrix in column major format for transformation from eye (0..left, 1....
bool handle(cgv::gui::event &e)
overload and implement this method to handle events
void put_up_direction(float *up_dir) const
put a 3d up direction into passed array
void update_reference_states(int i=-1)
update a single renference state or all from base_orientations, base_positions and base_serials
vr::vr_kit * replace_by_index(int &index, vr::vr_kit *new_kit_ptr)
scan all connected vr kits and return a vector with their ids
bool self_reflect(cgv::reflect::reflection_handler &srh)
used for simple self reflection
bool replace_by_pointer(vr::vr_kit *old_kit_ptr, vr::vr_kit *new_kit_ptr)
scan all connected vr kits and return a vector with their ids
void finish_frame(cgv::render::context &)
this method is called in one pass over all drawables after drawing
std::string get_type_name() const
return the type name
bool init(cgv::render::context &ctx)
this method is called after creation or recreation of the context, return whether all necessary funct...
void init_frame(cgv::render::context &)
this method is called in one pass over all drawables before the draw method
bool is_installed() const
return whether driver is installed
std::string get_driver_name() const
return name of driver
float get_action_zone_height() const
return height of action zone in meters
std::vector< void * > scan_vr_kits()
scan all connected vr kits and return a vector with their ids
void stream_stats(std::ostream &)
overload to show the content of this object
void create_controller_gui(int i, vr::vr_controller_state &cs)
void draw(cgv::render::context &)
overload to draw the content of this drawable
void stream_help(std::ostream &os)
overload to stream help information to the given output stream
void on_set(void *member_ptr)
this callback is called when the set_void method has changed a member and can be overloaded in derive...
float get_floor_level() const
return the floor level relativ to the world origin
void put_action_zone_bounary(std::vector< float > &boundary) const
return a vector of floor points defining the action zone boundary as a closed polygon
void create_gui()
you must overload this for gui creation
Helper functions to convert numeric types into strings using std streams.
vr_server & ref_vr_server()
return a reference to gamepad server singleton
@ KA_PRESS
key press action
Definition key_event.h:14
@ KA_RELEASE
key release action
Definition key_event.h:13
@ EM_SHIFT
shift modifier
Definition event.h:42
@ EM_ALT
alt modifier
Definition event.h:43
@ EM_CTRL
ctrl modifier
Definition event.h:44
@ KEY_Num_4
num pad key 4
Definition shortcut.h:63
@ KEY_Left
left arrow key
Definition shortcut.h:42
@ KEY_Num_2
num pad key 2
Definition shortcut.h:61
@ KEY_Num_3
num pad key 3
Definition shortcut.h:62
@ KEY_Num_1
num pad key 1
Definition shortcut.h:60
@ KEY_Num_7
num pad key 7
Definition shortcut.h:66
@ KEY_Page_Up
page up key
Definition shortcut.h:48
@ KEY_Page_Down
page down key
Definition shortcut.h:49
@ KEY_Num_8
num pad key 8
Definition shortcut.h:67
@ KEY_Num_9
num pad key 9
Definition shortcut.h:68
@ KEY_End
end key
Definition shortcut.h:47
@ KEY_Right
right arrow key
Definition shortcut.h:43
@ KEY_Home
home key
Definition shortcut.h:46
@ KEY_Num_6
num pad key 6
Definition shortcut.h:65
@ KEY_Up
up arrow key
Definition shortcut.h:44
@ KEY_Down
down arrow key
Definition shortcut.h:45
@ EID_KEY
id for key event
Definition event.h:17
trigger & get_animation_trigger()
return the global trigger used for animation, which runs by default with 60 Hz
Definition trigger.cxx:81
void connect_gamepad_server(cgv::gui::window_ptr w)
connect the gamepad server to the given window or the first window of the application,...
std::string get_element(const std::string &s, int element_index, char sep)
interpret s as a list separated by sep and return the element with the given element index.
Definition scan.cxx:301
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
the cgv namespace
Definition print.h:11
cgv::math::quaternion< float > quat
declare type of quaternion
Definition quaternion.h:370
cgv::math::fvec< float, 3 > vec3
declare type of 3d single precision floating point vectors
Definition fvec.h:669
VRButtonStateFlags
one flag for each vr controller button
Definition vr_state.h:62
@ VRF_INPUT0
button of input 0
Definition vr_state.h:72
@ VRF_MENU
application menu button
Definition vr_state.h:64
@ VRF_A
A button.
Definition vr_state.h:70
@ VRF_INPUT1_TOUCH
touch sensor for input 1 which often is touchpad or stick
Definition vr_state.h:73
@ VRF_GRIP
grip button
Definition vr_state.h:65
@ VRF_INPUT1
button of input 1
Definition vr_state.h:74
@ VRF_SYSTEM
system button
Definition vr_state.h:63
@ VRF_INPUT0_TOUCH
touch sensor for input 0 which often is touchpad or stick
Definition vr_state.h:71
vr_kit * get_vr_kit(void *handle)
query a pointer to a vr kit by its device handle, function can return null pointer in case that no vr...
void register_driver(vr_driver *vrd)
register a new driver
@ VRS_TRACKED
trackable is connected and tracked
Definition vr_state.h:88
@ VRS_DETACHED
trackable is not reachable via wireless
Definition vr_state.h:86
helper functions to work with poses that can be represented with 3x4 matrix or quaternion plus vector
Helper functions to process strings.
int32_t nr_axes
total number of axes provided by all inputs
Definition vr_info.h:130
VRControllerType type
controller type
Definition vr_info.h:122
VRButtonStateFlags supported_buttons
one flag per button telling whether it is supported
Definition vr_info.h:137
VRControllerRole role
controller role
Definition vr_info.h:124
VRInputType input_type[max_nr_controller_inputs]
type of up to 5vr::max_nr_controller_inputs inputs built into the controller
Definition vr_info.h:128
VRAxisType axis_type[max_nr_controller_axes]
axis type for each of the vr::max_nr_controller_axes axes in the state
Definition vr_info.h:135
int32_t nr_inputs
number of used inputs
Definition vr_info.h:126
Extends the trackable state by information on the buttons, input axes and vibration strengths.
Definition vr_state.h:118
float axes[max_nr_controller_axes]
up to vr::max_nr_controller_axes axis values in the range [-1,1] or [0,1] (VIVE: 0|1....
Definition vr_state.h:124
unsigned time_stamp
a unique time stamp for fast test whether state changed
Definition vr_state.h:120
float vibration[2]
strength of the vibration motors
Definition vr_state.h:126
std::string serial_number
unique identifier of device
Definition vr_info.h:18
std::string model_number
number describing the device type
Definition vr_info.h:20
float fps
frame rate
Definition vr_info.h:60
float ipd
interpupilar distance measured in meters
Definition vr_info.h:62
float head_to_eye_distance
distance from head origin to eye centers in meters
Definition vr_info.h:64
int32_t number_cameras
number of cameras
Definition vr_info.h:66
vr_hmd_info hmd
information for head mounted display
Definition vr_info.h:150
vr_controller_info controller[max_nr_controllers]
information for attached controllers and trackers
Definition vr_info.h:152
bool force_feedback_support
whether force feedback is supported
Definition vr_info.h:148
structure that stores all information describing the state of a VR kit
Definition vr_state.h:139
vr_controller_state controller[max_nr_controllers]
status, pose, button, axes, and vibration information of up to vr::max_nr_controllers controller and ...
Definition vr_state.h:143
vr_trackable_state hmd
status and pose of hmd
Definition vr_state.h:141
bool has_proximity_sensor
whether device has proximity sensor
Definition vr_info.h:44
std::string device_type
type name of device
Definition vr_info.h:34
int32_t device_class
index of device class
Definition vr_info.h:36
bool is_wireless
whether device is wireless
Definition vr_info.h:38
a trackable knows whether it is tracked and its 6d pose stored as 3x4 matrix in column major format
Definition vr_state.h:94
VRStatus status
whether trackable is currently tracked, only in case of true, the pose member contains useful informa...
Definition vr_state.h:96
float pose[12]
pose as 3x4 matrix in column major format, where each column is a vector in world coordinates
Definition vr_state.h:104
provides vr_emulator and vr_emulated_kit classes.