cgv
Loading...
Searching...
No Matches
vr_view_interactor.cxx
1#include "vr_view_interactor.h"
2#include "vr_render_helpers.h"
3#include <cgv/render/attribute_array_binding.h>
4#include <cgv/render/shader_program.h>
5#include <cgv/gui/trigger.h>
6#include <cgv/signal/rebind.h>
7#include <cgv/math/ftransform.h>
8#include <cgv/base/import.h>
9#include <cgv/math/inv.h>
10#include <cgv/math/pose.h>
11#include <iostream>
12#include <sstream>
13#include <vr/vr_kit.h>
14#include <vr/vr_driver.h>
15#include <cg_vr/vr_events.h>
16#include <cg_vr/vr_calib.h>
17
19{
20 return cgv::reflect::enum_reflection_traits<VRkitVisType>("none,sphere,mesh,both");
21}
22
24vr_view_interactor::vr_view_interactor(const char* name) : stereo_view_interactor(name),
25 fence_color1(0,0,1), fence_color2(1,1,0)
26{
27 pose_query = 2;
28 blit_aspect_scale = 1;
29 none_separate_view = 3;
30 head_tracker_orientation.identity();
31 head_tracker_position = cgv::vec3(0.0f);
32 tracking_origin = cgv::vec3(0.0f);
33 tracking_rotation_origin = cgv::vec3(0.0f);
34 tracking_rotation = 0;
35 head_tracker = -1;
36 debug_vr_events = false;
37 separate_view = true;
38 dont_render_kits = false;
39 blit_vr_views = true;
40 blit_width = 160;
42 rendered_display_ptr = 0;
43 rendered_eye = 0;
44 rendered_display_index = -1;
45
46 fence_frequency = 5;
47 fence_line_width = 3;
48 vis_type = hmd_vis_type = controller_vis_type = tracker_vis_type = base_vis_type = VVT_MESH;
49
50 mesh_scales[0] = mesh_scales[1] = mesh_scales[2] = mesh_scales[3] = 1;
51
52 show_action_zone = false;
53 current_vr_handle = 0;
54 current_vr_handle_index = -1;
55 kit_enum_definition = "enums='none=-1'";
56
57 brs.map_color_to_material = cgv::render::CM_COLOR;
58 srs.map_color_to_material = cgv::render::CM_COLOR;
59 srs.blend_width_in_pixel = 0;
60
61 cgv::signal::connect(cgv::gui::ref_vr_server().on_device_change, this, &vr_view_interactor::on_device_change);
62 cgv::signal::connect(cgv::gui::ref_vr_server().on_status_change, this, &vr_view_interactor::on_status_change);
63}
64
67{
68 if (debug_vr_events != enable) {
69 debug_vr_events = enable;
70 on_set(&debug_vr_events);
71 }
72}
73
76{
77 if (separate_view != do_draw) {
78 separate_view = do_draw;
79 on_set(&separate_view);
80 }
81}
82
85{
86 if ((vis_type != VVT_NONE) != do_draw) {
87 vis_type = do_draw ? VVT_MESH : VVT_NONE;
88 on_set(&vis_type);
89 }
90}
91
94{
95 if ((controller_vis_type != VVT_NONE) != do_draw) {
96 controller_vis_type = do_draw ? VVT_MESH : VVT_NONE;
97 on_set(&controller_vis_type);
98 }
99}
100
103{
104 if (show_action_zone != do_draw) {
105 show_action_zone = do_draw;
106 on_set(&show_action_zone);
107 }
108}
111{
112 if (blit_vr_views != enable) {
113 blit_vr_views = enable;
114 on_set(&blit_vr_views);
115 }
116}
119{
120 if (blit_width != width) {
121 blit_width = width;
122 on_set(&blit_width);
123 }
124}
125
128{
129 if (current_vr_handle_index >= 0 && current_vr_handle_index < int(kit_states.size()))
130 return &kit_states[current_vr_handle_index];
131 return 0;
132}
133
136{
137 if (current_vr_handle_index >= 0 && current_vr_handle_index < int(kit_states.size()))
138 return get_vr_kit_from_index(current_vr_handle_index);
139 return 0;
140}
141
143{
144 if (vr_kit_idx == -1)
145 vr_kit_idx = current_vr_handle_index;
146 if (vr_kit_idx < 0 || vr_kit_idx >= (int) kit_states.size())
147 return get_view_dir();
148 return -reinterpret_cast<const cgv::vec3&>(kit_states[vr_kit_idx].hmd.pose[6]);
149}
150
152{
153 if (vr_kit_idx == -1)
154 vr_kit_idx = current_vr_handle_index;
155 if (vr_kit_idx < 0 || vr_kit_idx >= (int) kit_states.size()) {
156 // ensure that view up is orthogonal to view dir
157 return cross(get_view_dir(), cross(get_view_up_dir(), get_view_dir()));
158 }
159 return reinterpret_cast<const cgv::vec3&>(kit_states[vr_kit_idx].hmd.pose[3]);
160}
161
162cgv::dvec3 vr_view_interactor::get_eye_of_kit(int eye, int vr_kit_idx) const
163{
164 if (vr_kit_idx == -1)
165 vr_kit_idx = current_vr_handle_index;
166 if (vr_kit_idx < 0 || vr_kit_idx >= (int) kit_states.size())
167 return get_eye();
168 return reinterpret_cast<const cgv::vec3&>(kit_states[vr_kit_idx].hmd.pose[9]);
169}
170
178{
179 event_flags = flags;
180 on_set(&event_flags);
181}
182
184void vr_view_interactor::on_status_change(void* handle, int controller_index, vr::VRStatus old_status, vr::VRStatus new_status)
185{
186 post_redraw();
187 if (debug_vr_events)
188 std::cout << "on status change(" << handle << ","
189 << controller_index << "," << vr::get_status_string(old_status)
190 << "," << vr::get_status_string(new_status) << ")" << std::endl;
191}
192
194void vr_view_interactor::on_device_change(void* handle, bool attach)
195{
196 if (attach)
197 new_kits.push_back(handle);
198 else
199 old_kits.push_back(handle);
200 post_redraw();
201 if (debug_vr_events)
202 std::cout << "on device change(" << handle << ","
203 << (attach?"attach":"detach") << ")" << std::endl;
204}
205
208{
209 vr::vr_kit* kit_ptr = get_current_vr_kit();
210 if (!kit_ptr)
211 return;
212 const vr::vr_driver* driver_ptr = kit_ptr->get_driver();
213 float calibration_matrix[12];
214 cgv::mat3x4& C = reinterpret_cast<cgv::mat3x4&>(calibration_matrix[0]);
215 pose_orientation(C) = cgv::math::rotate3<float>(tracking_rotation, cgv::vec3(0, 1, 0));
216 pose_position(C) = tracking_origin - pose_orientation(C)*tracking_rotation_origin;
217 set_driver_calibration_matrix(const_cast<vr::vr_driver*>(driver_ptr), calibration_matrix);
218 const_cast<vr::vr_driver*>(driver_ptr)->enable_calibration_transformation();
219}
220
223{
224 return "vr_view_interactor";
225}
227void vr_view_interactor::on_set(void* member_ptr)
228{
229 if (member_ptr == &calibration_file_path) {
230 if (ref_tree_node_visible_flag(calibration_file_path)) {
233 }
234 else
236 }
237 if (member_ptr == &hmd_mesh_file_name)
238 vr::set_vrmesh_file_name(vr::VRM_HMD, hmd_mesh_file_name);
239 if (member_ptr == &controller_mesh_file_name)
240 vr::set_vrmesh_file_name(vr::VRM_CONTROLLER, controller_mesh_file_name);
241 if (member_ptr == &tracker_mesh_file_name)
242 vr::set_vrmesh_file_name(vr::VRM_TRACKER, tracker_mesh_file_name);
243 if (member_ptr == &base_mesh_file_name) {
244 vr::set_vrmesh_file_name(vr::VRM_BASE, base_mesh_file_name);
245 update_member(&base_mesh_file_name);
246 }
247
248 if (member_ptr == &vis_type) {
249 hmd_vis_type = controller_vis_type = tracker_vis_type = vis_type;
250 update_member(&hmd_vis_type);
251 update_member(&controller_vis_type);
252 update_member(&tracker_vis_type);
253 update_member(&base_vis_type);
254 }
255
256 if (member_ptr == &current_vr_handle_index) {
257 if (current_vr_handle_index == -1) {
258 current_vr_handle = 0;
259 if (!separate_view) {
260 separate_view = true;
261 update_member(&separate_view);
262 }
263 }
264 else
265 if (current_vr_handle_index < int(kits.size()))
266 current_vr_handle = kits[current_vr_handle_index];
267 }
268 if (member_ptr == &tracking_rotation ||
269 (member_ptr >= &tracking_origin && member_ptr < &tracking_origin + 1) ||
270 (member_ptr >= &tracking_rotation_origin && member_ptr < &tracking_rotation_origin + 1)) {
272 }
273 if (member_ptr == &head_tracker) {
274 if (current_vr_handle_index >= 0) {
275 const auto& cs = kit_states[current_vr_handle_index].controller[head_tracker];
276 if (cs.status == vr::VRS_TRACKED) {
277 const cgv::mat3& O = reinterpret_cast<const cgv::mat3&>(cs.pose[0]);
278 const cgv::vec3& p = reinterpret_cast<const cgv::vec3&>(cs.pose[9]);
279 cgv::mat3 V;
280 cgv::vec3& x = reinterpret_cast<cgv::vec3&>(V[0]);
281 cgv::vec3& y = reinterpret_cast<cgv::vec3&>(V[3]);
282 cgv::vec3& z = reinterpret_cast<cgv::vec3&>(V[6]);
283 cgv::vec3 e = get_eye();
284 put_coordinate_system(x, y, z);
285 head_tracker_orientation = V * transpose(O);
287 }
288 }
289 }
290 stereo_view_interactor::on_set(member_ptr);
291}
292
295{
296 os << "vr_view_interactor: Ctrl-0|1|2|3 to select player; Ctrl-Space to toggle draw separate view\n"
297 << " Shift-Ctrl-0|1|2|3 to identify current focus point with conroller or tracker\n";
298 stereo_view_interactor::stream_help(os);
299}
300
303{
304 stereo_view_interactor::stream_stats(os);
305}
306
307bool vr_view_interactor::init(cgv::render::context& ctx)
308{
310
311#ifndef _DEBUG
312 // set mesh file names only in release configuration
313 if (vr::get_vrmesh_file_name(vr::VRM_HMD).empty())
314 vr::set_vrmesh_file_name(vr::VRM_HMD, "generic_hmd.obj");
315 if (vr::get_vrmesh_file_name(vr::VRM_CONTROLLER).empty())
316 vr::set_vrmesh_file_name(vr::VRM_CONTROLLER, "vr_controller_vive_1_5.obj");
317 if (vr::get_vrmesh_file_name(vr::VRM_TRACKER).empty()) {
318 vr::set_vrmesh_file_name(vr::VRM_TRACKER, "HTC_Vive_Tracker_2017.obj");
319 mesh_scales[vr::VRM_TRACKER] = 0.001f;
320 }
321 if (vr::get_vrmesh_file_name(vr::VRM_BASE).empty())
322 vr::set_vrmesh_file_name(vr::VRM_BASE, "lh_basestation_vive.obj");
323#endif
324 return stereo_view_interactor::init(ctx);
325}
326
327void vr_view_interactor::clear(cgv::render::context& ctx)
328{
330}
331
334{
335 return false;
336 if (e.get_kind() == cgv::gui::EID_KEY) {
337 auto& vrke = reinterpret_cast<cgv::gui::vr_key_event&>(e);
338 if (vrke.get_key() == vr::VR_INPUT0 && vrke.get_controller_index() == 1) {
339 if (vrke.get_action() == cgv::gui::KA_PRESS) {
340 start_pose = reinterpret_cast<const cgv::mat3x4&>(*vrke.get_state().controller[1].pose);
341 }
342 else if (vrke.get_action() == cgv::gui::KA_RELEASE) {
343 cgv::mat3x4 end_pose = reinterpret_cast<const cgv::mat3x4&>(*vrke.get_state().controller[1].pose);
344 tracking_origin += pose_position(end_pose) - pose_position(start_pose);
345 }
346 return true;
347 }
348 }
349}
350
353{
354 if ((e.get_flags() & cgv::gui::EF_VR) != 0) {
355 if (debug_vr_events) {
356 e.stream_out(std::cout);
357 std::cout << std::endl;
358 }
359 return handle_vr_events(e);
360 }
361
362 if (head_tracker != -1) {
363 if ( ((e.get_flags() & cgv::gui::EF_VR) != 0) && (e.get_kind() == cgv::gui::EID_POSE) ) {
364 cgv::gui::vr_pose_event& vrpe = dynamic_cast<cgv::gui::vr_pose_event&>(e);
365 if (vrpe.get_trackable_index() == head_tracker) {
366 const cgv::mat3& O = reinterpret_cast<const cgv::mat3&>(vrpe.get_orientation());
367 const cgv::vec3& p = reinterpret_cast<const cgv::vec3&>(vrpe.get_position());
369 set_view_up_dir(V.col(1));
370 set_view_dir(-V.col(2));
371
372 cgv::vec3 dv = get_focus() - get_eye();
374 set_focus(e+dv);
375 }
376 }
377 }
378 if (e.get_kind() == cgv::gui::EID_KEY) {
379 cgv::gui::key_event& ke = static_cast<cgv::gui::key_event&>(e);
380 if ((ke.get_action() == cgv::gui::KA_PRESS)) {
381 if (ke.get_modifiers() == cgv::gui::EM_CTRL) {
382 if (ke.get_key() >= '0' && ke.get_key() < '4') {
383 unsigned player_index = ke.get_key() - '0';
384 if (player_index < kits.size()) {
385 current_vr_handle_index = player_index;
386 current_vr_handle = kits[player_index];
387 update_member(&current_vr_handle_index);
388 return true;
389 }
390 }
391 if (ke.get_key() == cgv::gui::KEY_Space) {
393 on_set(&separate_view);
394 return true;
395 }
396 }
398 if (ke.get_key() >= '0' && ke.get_key() < '1'+vr::max_nr_controllers) {
399 int ci = ke.get_key() - '0';
400 if (ci == vr::max_nr_controllers)
401 ci = 0;
402 if (current_vr_handle_index >= 0) {
403 vr::vr_kit_state& state = kit_states[current_vr_handle_index];
404 if (state.controller[ci].status == vr::VRS_TRACKED) {
405 // p = R * (q-r) + t
406 // f = R * (q-r') + t'
407 // p - f = R*(r'-r)+t-t'
408 // t' = f
409 // p - f = R*(r'-r)+t-f
410 // r' = r = R^*(p - t)
411 cgv::vec3& p = reinterpret_cast<cgv::vec3&>(state.controller[ci].pose[9]);
412 cgv::mat3 invR = cgv::math::rotate3<float>(-tracking_rotation, cgv::vec3(0, 1, 0));
414 tracking_origin = get_focus();
415 p = get_focus();
416 for (int i = 0; i < 3; ++i) {
417 update_member(&tracking_origin[i]);
418 update_member(&tracking_rotation_origin[i]);
419 }
421 }
422 }
423 }
424 }
425 }
426 }
427 return stereo_view_interactor::handle(e);
428}
429
430
433{
434 stereo_view_interactor::finish_frame(ctx);
435}
436
438{
439 stereo_view_interactor::after_finish(ctx);
441 if (rendered_display_ptr) {
442 rendered_display_ptr->disable_fbo(rendered_eye);
445 if (!separate_view) {
446
447 int x0 = 0, width = ctx.get_width(), eye = 0, eye_end = 2;
448 switch (none_separate_view) {
449 case 1: eye_end = 1; break;
450 case 2: eye = 1; break;
451 case 3: width /= 2; break;
452 }
453 for (; eye < eye_end; ++eye) {
454 rendered_display_ptr->blit_fbo(eye, x0, 0, width, ctx.get_height());
455 x0 += width;
456 }
457 }
458 rendered_eye = 0;
459 rendered_display_ptr = 0;
460 rendered_display_index = -1;
461 }
462 // submit frames to active vr kits and blit vr kit views in main framebuffer if activated
463 if (!dont_render_kits) {
464 int y0 = 0;
465 for (size_t ki = 0; ki < kits.size(); ++ki) {
466 // check if kit is attached and its pointer valid
467 if (kit_states[ki].hmd.status == vr::VRS_DETACHED)
468 continue;
469 vr::vr_kit* kit_ptr = get_vr_kit_from_index((int)ki);
470 if (!kit_ptr)
471 continue;
472
473 if (blit_vr_views && (separate_view || ki != current_vr_handle_index)) {
474 int x0 = 0;
475 int blit_height = (int)(blit_width * kit_ptr->get_height() / (blit_aspect_scale*kit_ptr->get_width()));
476 for (int eye = 0; eye < 2; ++eye) {
477 kit_ptr->blit_fbo(eye, x0, y0, blit_width, blit_height);
478 x0 += blit_width + 5;
479 }
480 y0 += blit_height + 5;
481 }
482 kit_ptr->submit_frame();
483 }
484 }
485 if (current_vr_handle)
486 post_redraw();
487 }
488}
489
490vr::vr_kit* vr_view_interactor::get_vr_kit_from_index(int i) const
491{
492 return vr::get_vr_kit(kits[i]);
493}
494
495void vr_view_interactor::configure_kits()
496{
497 bool update_kits = false;
498 void* last_current_vr_handle = current_vr_handle;
499 // check for old kits, destruct their render objects, unregister them and delete them
500 while (!old_kits.empty()) {
501 if (current_vr_handle == old_kits.back())
502 current_vr_handle = 0;
503 vr::vr_kit* kit_ptr = vr::get_vr_kit(old_kits.back());
504 if (kit_ptr) {
505 if (kit_ptr->fbos_initialized())
506 kit_ptr->destruct_fbos();
507 if (!vr::unregister_vr_kit(old_kits.back(), kit_ptr)) {
508 std::cerr << "unable to unregister removed kit <" << old_kits.back() << ">" << std::endl;
509 }
510 delete kit_ptr;
511 }
512 auto iter = std::find(kits.begin(), kits.end(), old_kits.back());
513 if (iter != kits.end()) {
514 kits.erase(iter);
515 update_kits = true;
516 }
517 old_kits.pop_back();
518 }
519 if (current_vr_handle == 0 && !kits.empty())
520 current_vr_handle = kits.front();
521 // check for new kits and initialize their render objects in current context
522 while (!new_kits.empty()) {
523 vr::vr_kit* kit_ptr = vr::get_vr_kit(new_kits.back());
524 if (kit_ptr) {
525 if (!kit_ptr->fbos_initialized())
526 if (kit_ptr->init_fbos()) {
527 std::cout << "initialized fbos of " << kit_ptr->get_name() << " in context " << (void*)get_context() << std::endl;
528 if (current_vr_handle == 0)
529 current_vr_handle = new_kits.back();
530 }
531 kits.push_back(new_kits.back());
532 update_kits = true;
533 }
534 new_kits.pop_back();
535 }
536 kit_states.resize(kits.size());
537 //
538 if (update_kits) {
539 kit_enum_definition = "enums='none=-1";
540 for (auto handle : kits) {
541 vr::vr_kit* kit_ptr = vr::get_vr_kit(handle);
542 std::string kit_name;
543 if (kit_ptr)
544 kit_name = kit_ptr->get_name();
545 else {
546 std::stringstream ss;
547 ss << handle;
548 kit_name = ss.str();
549 }
550 kit_enum_definition += ";";
551 kit_enum_definition += kit_name;
552 }
553 kit_enum_definition += "'";
554 if (find_control(current_vr_handle_index))
555 find_control(current_vr_handle_index)->multi_set(kit_enum_definition);
556 std::cout << kit_enum_definition << std::endl;
557 }
558 if (update_kits || current_vr_handle != last_current_vr_handle) {
559 if (current_vr_handle == 0)
560 current_vr_handle_index = -1;
561 else {
562 for (unsigned i = 0; i < kits.size(); ++i)
563 if (kits[i] == current_vr_handle) {
564 current_vr_handle_index = i;
565 if (calibration_file_path.empty())
567 break;
568 }
569 }
570 update_member(&current_vr_handle_index);
571 }
572}
573
574// query vr state
575void vr_view_interactor::query_vr_states()
576{
577 // query states
578 vr::vr_kit* current_kit_ptr = 0;
579 if (current_vr_handle_index >= 0) {
580 current_kit_ptr = get_vr_kit_from_index(current_vr_handle_index);
581 if (current_kit_ptr) {
582 vr::vr_kit_state& state = kit_states[current_vr_handle_index];
583 current_kit_ptr->query_state(state, 2);
584 cgv::gui::ref_vr_server().check_new_state(current_vr_handle, state, cgv::gui::trigger::get_current_time(), event_flags);
585 }
586 }
587 for (unsigned i = 0; i < kits.size(); ++i) {
588 vr::vr_kit* kit_ptr = get_vr_kit_from_index(i);
589 if (!kit_ptr)
590 continue;
591 if (kit_ptr == current_kit_ptr)
592 continue;
593 kit_ptr->query_state(kit_states[i], 1);
594 if (kit_states[i].hmd.status == vr::VRS_DETACHED)
595 continue;
596 cgv::gui::ref_vr_server().check_new_state(kits[i], kit_states[i], cgv::gui::trigger::get_current_time(), event_flags);
597 }
598}
599
600// render the views for the kits in nested render passes
601void vr_view_interactor::render_vr_kits(cgv::render::context& ctx)
602{
604 // first render all but current vr kit views
605 for (rendered_display_index = 0; rendered_display_index<int(kits.size()); ++rendered_display_index) {
606 if (rendered_display_index == current_vr_handle_index)
607 continue;
608 rendered_display_ptr = get_vr_kit_from_index(rendered_display_index);
609 if (!rendered_display_ptr)
610 continue;
611 if (kit_states[rendered_display_index].hmd.status == vr::VRS_DETACHED)
612 continue;
613 void* fbo_handle;
614 cgv::ivec4 cgv_viewport;
615 for (rendered_eye = 0; rendered_eye < 2; ++rendered_eye) {
616 rendered_display_ptr->enable_fbo(rendered_eye);
618 ctx.announce_external_viewport_change(cgv_viewport);
620 rendered_display_ptr->disable_fbo(rendered_eye);
623 }
624 }
625 // then render current vr kit
626 rendered_display_index = current_vr_handle_index;
627 rendered_display_ptr = get_vr_kit_from_index(rendered_display_index);
628 if (rendered_display_ptr && kit_states[rendered_display_index].hmd.status != vr::VRS_DETACHED) {
629 void* fbo_handle;
630 cgv::ivec4 cgv_viewport;
631 //rendered_eye: 0...monitor,1...left eye,2...right eye
632 for (rendered_eye = 0; rendered_eye < 2; ++rendered_eye) {
633 rendered_display_ptr->enable_fbo(rendered_eye);
635 ctx.announce_external_viewport_change(cgv_viewport);
636 // we break here in the case of no separate to use main render pass to render second eye of current vr kit
637 if (rendered_eye == 1 && !separate_view) {
638 this->fbo_handle = fbo_handle;
639 this->cgv_viewport = cgv_viewport;
640 break;
641 }
643 rendered_display_ptr->disable_fbo(rendered_eye);
646 }
647 }
648 else {
649 rendered_display_ptr = 0;
650 rendered_display_index = -1;
651 }
652 if (separate_view) {
653 rendered_display_ptr = 0;
654 rendered_display_index = -1;
655 }
656}
657
660{
662 // update current vr kits
663 configure_kits();
664 // perform rendering from the vr kits
665 if (kits.size() > 0) {
666 // query vr state
667 query_vr_states();
668 // render the views for the kits in nested render passes
669 if (!dont_render_kits)
670 render_vr_kits(ctx);
671 }
672 }
673 // set model view projection matrices for currently rendered eye of rendered vr kit
674 if (rendered_display_ptr) {
675 vr::vr_kit* rendered_vr_kit = get_rendered_vr_kit();
676 compute_clipping_planes(z_near_derived, z_far_derived, clip_relative_to_extent);
677 ctx.set_projection_matrix(vr::get_eye_projection_transform(rendered_vr_kit, kit_states[rendered_display_index], float(z_near_derived), float(z_far_derived), rendered_eye));
678 ctx.set_modelview_matrix(vr::get_world_to_eye_transform(rendered_vr_kit, kit_states[rendered_display_index], rendered_eye));
679 }
680 else {
681 // use standard rendering for separate view or if no vr kit is available
682 if (kits.empty() || separate_view)
683 stereo_view_interactor::init_frame(ctx);
684 }
685}
686
687void vr_view_interactor::add_trackable_spheres(const float* pose, int i, std::vector<cgv::vec4>& spheres, std::vector<cgv::rgb>& sphere_colors)
688{
689 const cgv::mat3& R_ci = reinterpret_cast<const cgv::mat3&>(pose[0]);
690 const cgv::vec3& p_ci = reinterpret_cast<const cgv::vec3&>(pose[9]);
691 spheres.push_back(cgv::vec4(p_ci, 0.04f));
692 spheres.push_back(cgv::vec4(p_ci + 0.05f*R_ci.col(0), 0.01f));
693 spheres.push_back(cgv::vec4(p_ci - 0.05f*R_ci.col(0), 0.01f));
694 spheres.push_back(cgv::vec4(p_ci + 0.05f*R_ci.col(1), 0.01f));
695 spheres.push_back(cgv::vec4(p_ci - 0.05f*R_ci.col(1), 0.01f));
696 spheres.push_back(cgv::vec4(p_ci + 0.05f*R_ci.col(2), 0.01f));
697 spheres.push_back(cgv::vec4(p_ci - 0.05f*R_ci.col(2), 0.01f));
698 sphere_colors.push_back(cgv::rgb(0.5f + (1 - i)*0.5f, 0.5f, 0.5f + 0.5f*i));
699 sphere_colors.push_back(cgv::rgb(1, 0, 0));
700 sphere_colors.push_back(cgv::rgb(1, 0.5f, 0.5f));
701 sphere_colors.push_back(cgv::rgb(0, 1, 0));
702 sphere_colors.push_back(cgv::rgb(0.5f, 1, 0.5f));
703 sphere_colors.push_back(cgv::rgb(0, 0, 1));
704 sphere_colors.push_back(cgv::rgb(0.5f, 0.5f, 1));
705}
708{
709 std::vector<cgv::vec4> spheres;
710 std::vector<cgv::rgb> sphere_colors;
711 cgv::render::mesh_render_info* MI_hmd_ptr = 0;
712 cgv::render::mesh_render_info* MI_controller_ptr = 0;
713 cgv::render::mesh_render_info* MI_tracker_ptr = 0;
714 cgv::render::mesh_render_info* MI_base_ptr = 0;
715 std::set<const vr::vr_driver*> driver_set;
716 for (int i = 0; i < (int)kits.size(); ++i) {
717 // skip removed kits
718 vr::vr_kit* kit_ptr = get_vr_kit_from_index(i);
719 if (!kit_ptr)
720 continue;
721 // extract drivers of which the bases should be drawn
722 if (base_vis_type != VVT_NONE)
723 driver_set.insert(kit_ptr->get_driver());
724 // ignore completely hidden vr kits
725 if (hmd_vis_type == VVT_NONE && controller_vis_type == VVT_NONE && tracker_vis_type == VVT_NONE)
726 continue;
727 // determine state of vr kit and skip kit if no state is available
728 vr::vr_kit_state state;
729 vr::vr_kit_state* state_ptr = &state;
730 if (i == current_vr_handle_index)
731 state_ptr = &kit_states[current_vr_handle_index];
732 else
733 if (!kit_ptr->query_state(state, 1))
734 continue;
735 // render other hmds
736 if (kit_ptr != rendered_display_ptr) {
737 // either as mesh
738 if ((hmd_vis_type & VVT_MESH) != 0) {
739 if (!MI_hmd_ptr) {
740 MI_hmd_ptr = vr::get_vrmesh_render_info(ctx, vr::VRM_HMD);
741 // try to read meshes and turn off mesh rendering and potentially switch to sphere rendering in case meshes are not available
742 if (MI_hmd_ptr) {
743 hmd_mesh_file_name = vr::get_vrmesh_file_name(vr::VRM_HMD);
744 update_member(&hmd_mesh_file_name);
745 }
746 else {
747 hmd_vis_type = VVT_SPHERE;
748 on_set(&hmd_vis_type);
749 }
750 }
751 if (MI_hmd_ptr != 0) {
754 cgv::math::pose4<float>(reinterpret_cast<const cgv::mat3x4&>(state_ptr->hmd.pose[0]))*
755 cgv::math::translate4<float>(0, 0.1f, -0.1f)*
756 cgv::math::scale4<float>(cgv::vec3(mesh_scales[vr::VRM_HMD]))
757 );
758 MI_hmd_ptr->draw_all(ctx);
760 }
761 }
762 // and or as spheres
763 if ((hmd_vis_type & VVT_SPHERE) != 0) {
764 float left_eye_to_head[12];
765 float right_eye_to_head[12];
766 kit_ptr->put_eye_to_head_matrix(0, left_eye_to_head);
767 kit_ptr->put_eye_to_head_matrix(1, right_eye_to_head);
768 const cgv::mat3& R_w_h = reinterpret_cast<const cgv::mat3&>(state_ptr->hmd.pose[0]);
769 const cgv::vec3& p_w_h = reinterpret_cast<const cgv::vec3&>(state_ptr->hmd.pose[9]);
770 const cgv::mat3& R_h_l = reinterpret_cast<const cgv::mat3&>(left_eye_to_head[0]);
771 const cgv::vec3& p_h_l = reinterpret_cast<const cgv::vec3&>(left_eye_to_head[9]);
772 const cgv::mat3& R_h_r = reinterpret_cast<const cgv::mat3&>(right_eye_to_head[0]);
773 const cgv::vec3& p_h_r = reinterpret_cast<const cgv::vec3&>(right_eye_to_head[9]);
774 cgv::vec4 s_l(0, 0, 0, 0.012f);
775 cgv::vec4 s_r = s_l;
776 reinterpret_cast<cgv::vec3&>(s_l) = R_w_h * p_h_l + p_w_h;
777 reinterpret_cast<cgv::vec3&>(s_r) = R_w_h * p_h_r + p_w_h;
778 spheres.push_back(s_l);
779 sphere_colors.push_back(cgv::rgb(1, 0, 0));
780 spheres.push_back(s_r);
781 sphere_colors.push_back(cgv::rgb(0, 0, 1));
782 }
783 }
784 for (unsigned ci = 0; ci < vr::max_nr_controllers; ++ci) {
785 if (state_ptr->controller[ci].status != vr::VRS_TRACKED || state_ptr->controller[ci].time_stamp == 0)
786 continue;
787 bool show_trackable_spheres;
789 float mesh_scale = 1;
790 if (kit_ptr->get_device_info().controller[ci].type == vr::VRC_CONTROLLER) {
791 show_trackable_spheres = (controller_vis_type & VVT_SPHERE) != 0;
792 if ((controller_vis_type & VVT_MESH) != 0) {
793 if (!MI_controller_ptr) {
794 MI_controller_ptr = vr::get_vrmesh_render_info(ctx, vr::VRM_CONTROLLER);
795 if (MI_controller_ptr) {
796 controller_mesh_file_name = vr::get_vrmesh_file_name(vr::VRM_CONTROLLER);
797 update_member(&controller_mesh_file_name);
798 }
799 else {
800 controller_vis_type = VVT_SPHERE;
801 on_set(&controller_vis_type);
802 }
803 }
804 if (MI_controller_ptr) {
805 M_info = MI_controller_ptr;
806 mesh_scale = mesh_scales[vr::VRM_CONTROLLER];
807 }
808 }
809 }
810 else {
811 show_trackable_spheres = (tracker_vis_type & VVT_SPHERE) != 0;
812 if ((tracker_vis_type & VVT_MESH) != 0) {
813 if (!MI_tracker_ptr) {
814 MI_tracker_ptr = vr::get_vrmesh_render_info(ctx, vr::VRM_TRACKER);
815 if (MI_tracker_ptr) {
816 tracker_mesh_file_name = vr::get_vrmesh_file_name(vr::VRM_TRACKER);
817 update_member(&tracker_mesh_file_name);
818 }
819 else {
820 tracker_vis_type = VVT_SPHERE;
821 on_set(&tracker_vis_type);
822 }
823 }
824 if (MI_tracker_ptr) {
825 M_info = MI_tracker_ptr;
826 mesh_scale = mesh_scales[vr::VRM_TRACKER];
827 }
828 }
829 }
830 if (show_trackable_spheres)
831 add_trackable_spheres(state_ptr->controller[ci].pose, i, spheres, sphere_colors);
832 if (M_info) {
834 ctx.mul_modelview_matrix(cgv::math::pose4<float>(reinterpret_cast<const cgv::mat3x4&>(state_ptr->controller[ci].pose[0])));
835 ctx.mul_modelview_matrix(cgv::math::scale4<float>(cgv::vec3(mesh_scale)));
836 M_info->draw_all(ctx);
838 }
839 }
840 }
841 for (auto& dp : driver_set) {
842 auto ss = dp->get_tracking_reference_states();
843 for (const auto& s : ss) {
844 if (s.second.status == vr::VRS_TRACKED) {
845 if ((base_vis_type & VVT_SPHERE) != 0)
846 add_trackable_spheres(s.second.pose, -1, spheres, sphere_colors);
847 if ((base_vis_type & VVT_MESH) != 0) {
848 if (!MI_base_ptr) {
849 MI_base_ptr = vr::get_vrmesh_render_info(ctx, vr::VRM_BASE);
850 if (MI_base_ptr) {
851 base_mesh_file_name = vr::get_vrmesh_file_name(vr::VRM_BASE);
852 update_member(&base_mesh_file_name);
853 }
854 else {
855 base_vis_type = VVT_SPHERE;
856 on_set(&base_vis_type);
857 }
858 }
859 if (MI_base_ptr) {
861 ctx.mul_modelview_matrix(cgv::math::pose4<float>(reinterpret_cast<const cgv::mat3x4&>(s.second.pose[0])));
862 ctx.mul_modelview_matrix(cgv::math::scale4<float>(cgv::vec3(mesh_scales[vr::VRM_BASE])));
863 MI_base_ptr->draw_all(ctx);
865 }
866 }
867 }
868 }
869 }
870 if (!spheres.empty()) {
872 sr.set_y_view_angle(float(get_y_view_angle()));
873 sr.set_render_style(srs);
874 sr.set_sphere_array(ctx, spheres);
875 sr.set_color_array(ctx, sphere_colors);
876 sr.render(ctx, 0, spheres.size());
877 }
878}
879
882{
883 if (show_action_zone && current_vr_handle) {
885 vr::vr_kit* kit_ptr = get_vr_kit_from_index(current_vr_handle_index);
886 if (kit_ptr) {
887 const vr::vr_driver* driver_ptr = kit_ptr->get_driver();
888 if (driver_ptr) {
889 float h = driver_ptr->get_action_zone_height();
890 cgv::vec3 up_dir;
891 driver_ptr->put_up_direction(&up_dir[0]);
892 std::vector<float> boundary;
893 driver_ptr->put_action_zone_bounary(boundary);
894 size_t n = boundary.size() / 3;
895 std::vector<cgv::vec3> G;
896 G.resize(5 * n);
897 unsigned i;
898 for (i = 0; i < 5; ++i) {
899 for (size_t j = 0; j < n; ++j) {
900 cgv::vec3 p = reinterpret_cast<const cgv::vec3&>(boundary[3 * j]);
901 p += 0.25f*i*h*up_dir;
902 G[i*n + j] = p;
903 }
904 }
905 glLineStipple(3, GLushort(0xF0F0));
906 glEnable(GL_LINE_STIPPLE);
907 glLineWidth(fence_line_width);
908 auto& prog = ctx.ref_default_shader_program();
909 int pos_idx = prog.get_position_index();
912 prog.enable(ctx);
913 float lambda = float(cos(fence_frequency*time));
914 lambda *= lambda;
915 ctx.set_color((1 - lambda)*fence_color1 + lambda * fence_color2);
916 for (i = 0; i < 5; ++i)
917 glDrawArrays(GL_LINE_LOOP, GLint(i*n), (GLsizei)n);
918 prog.disable(ctx);
920 glDisable(GL_LINE_STIPPLE);
921 glLineWidth(1.0f);
922 post_redraw();
923 }
924 }
925 }
926}
927
930{
931 draw_vr_kits(ctx);
932 draw_action_zone(ctx);
933 stereo_view_interactor::draw(ctx);
934}
935
938{
939 add_member_control(this, "current vr kit", (cgv::type::DummyEnum&)current_vr_handle_index, "dropdown", kit_enum_definition);
940 if (begin_tree_node("VR calibration", tracking_rotation, false, "level=2")) {
941 align("\a");
942 add_gui("calibration_file_path", calibration_file_path, "file_name",
943 "open=true;open_title='open calibration file';filter='calib (cal):*.cal|all files:*.*';"
944 "save=true;save_title='save calibration file';w=140");
945
946 add_member_control(this, "tracking_rotation", tracking_rotation, "value_slider", "min=-180;max=180;ticks=true");
947 if (begin_tree_node("translational", tracking_origin, false, "level=2")) {
948 align("\a");
949 add_decorator("origin", "heading", "level=3");
950 add_gui("tracking_origin", tracking_origin, "", "gui_type='value_slider';options='min=-2;max=2;ticks=true'");
951 add_decorator("rotation origin", "heading", "level=3");
952 add_gui("tracking_rotation_origin", tracking_rotation_origin, "", "gui_type='value_slider';options='min=-2;max=2;ticks=true'");
953 align("\b");
954 end_tree_node(tracking_origin);
955 }
956 align("\b");
957 end_tree_node(tracking_rotation);
958 }
959 if (begin_tree_node("VR rendering", separate_view, false, "level=2")) {
960 align("\a");
961 add_member_control(this, "scale", mesh_scales[0], "value", "w=42;align='B'", " ");
962 add_gui("hmd_mesh_file_name", hmd_mesh_file_name, "file_name", "w=132;align='B';title='read tracker mesh from file';filter='mesh (obj):*.obj|all files:*.*'");
963 add_member_control(this, "scale", mesh_scales[1], "value", "w=42;align='B'", " ");
964 add_gui("controller_mesh_file_name", controller_mesh_file_name, "file_name", "w=132;align='B';title='read tracker mesh from file';filter='mesh (obj):*.obj|all files:*.*'");
965 add_member_control(this, "scale", mesh_scales[2], "value", "w=42;align='B'", " ");
966 add_gui("tracker_mesh_file_name", tracker_mesh_file_name, "file_name", "w=132;align='B';title='read tracker mesh from file';filter='mesh (obj):*.obj|all files:*.*'");
967 add_member_control(this, "scale", mesh_scales[3], "value", "w=42;align='B'", " ");
968 add_gui("base_mesh_file_name", base_mesh_file_name, "file_name", "w=132;align='B';title='read tracker mesh from file';filter='mesh (obj):*.obj|all files:*.*'");
969 add_member_control(this, "separate_view", separate_view, "check");
970 add_member_control(this, "none_separate_view", (cgv::type::DummyEnum&)none_separate_view, "dropdown", "enums='left=1,right=2,both=3'");
971 add_member_control(this, "head_tracker", head_tracker, "value_slider", "min=-1;max=3");
972 add_member_control(this, "dont_render_kits", dont_render_kits, "check");
973 add_member_control(this, "blit_vr_views", blit_vr_views, "check");
974 add_member_control(this, "blit_width", blit_width, "value_slider", "min=120;max=640;ticks=true;log=true");
975 add_member_control(this, "blit_aspect_scale", blit_aspect_scale, "value_slider", "min=0.5;max=2;ticks=true;log=true");
976 add_member_control(this, "show_action_zone", show_action_zone, "check");
977 if (begin_tree_node("fence styles", fence_color1, false, "level=3")) {
978 align("\a");
979 add_member_control(this, "fence_color1", fence_color1);
980 add_member_control(this, "fence_color2", fence_color2);
981 add_member_control(this, "fence_line_width", fence_line_width, "value_slider", "min=1;max=20;ticks=true;log=true");
982 add_member_control(this, "fence_frequency", fence_frequency, "value_slider", "min=0.1;max=10;ticks=true;log=true");
983 align("\b");
984 end_tree_node(fence_color1);
985 }
986 add_decorator("visualization type", "heading", "level=3");
987 add_member_control(this, "complete kits", vis_type, "dropdown", "enums='hide,sphere,mesh,both'");
988 add_member_control(this, "hmd", hmd_vis_type, "dropdown", "enums='hide,sphere,mesh,both'");
989 add_member_control(this, "controller", controller_vis_type, "dropdown", "enums='hide,sphere,mesh,both'");
990 add_member_control(this, "tracker", tracker_vis_type, "dropdown", "enums='hide,sphere,mesh,both'");
991 add_member_control(this, "base", base_vis_type, "dropdown", "enums='hide,sphere,mesh,both'");
992
993 if (begin_tree_node("sphere styles", srs, false, "level=3")) {
994 align("\a");
995 add_gui("sphere style", srs);
996 align("\b");
997 end_tree_node(srs);
998 }
999 align("\b");
1000 end_tree_node(separate_view);
1001 }
1002 if (begin_tree_node("VR events", event_flags, false, "level=2")) {
1003 align("\a");
1004 add_member_control(this, "pose_query", pose_query, "value_slider", "min=0;max=2;ticks=true");
1005
1006 add_member_control(this, "debug_vr_events", debug_vr_events, "check");
1007 add_gui("event_flags", event_flags, "bit_field_control", "enums='dev=1,sta=2,key=4,1ax=8,2ax=16,1_k=32,2_k=64,pos=128';gui_type='toggle';options='w=30';align=''");
1008 align("\n\b");
1009 end_tree_node(event_flags);
1010 }
1011 stereo_view_interactor::create_gui();
1012}
1013
1016{
1017 return stereo_view_interactor::self_reflect(srh) &&
1018 srh.reflect_member("calibration_file_path", calibration_file_path) &&
1019 srh.reflect_member("vis_type", vis_type) &&
1020 srh.reflect_member("hmd_vis_type", hmd_vis_type) &&
1021 srh.reflect_member("controller_vis_type", controller_vis_type) &&
1022 srh.reflect_member("tracker_vis_type", tracker_vis_type) &&
1023 srh.reflect_member("base_vis_type", base_vis_type) &&
1024 srh.reflect_member("hmd_scale", mesh_scales[0]) &&
1025 srh.reflect_member("controller_scale", mesh_scales[1]) &&
1026 srh.reflect_member("tracker_scale", mesh_scales[2]) &&
1027 srh.reflect_member("base_scale", mesh_scales[3]) &&
1028 srh.reflect_member("hmd_mesh_file_name", hmd_mesh_file_name) &&
1029 srh.reflect_member("controller_mesh_file_name", controller_mesh_file_name) &&
1030 srh.reflect_member("tracker_mesh_file_name", tracker_mesh_file_name) &&
1031 srh.reflect_member("base_mesh_file_name", base_mesh_file_name) &&
1032 srh.reflect_member("separate_view", separate_view) &&
1033 srh.reflect_member("blit_vr_views", blit_vr_views) &&
1034 srh.reflect_member("blit_width", blit_width) &&
1035 srh.reflect_member("blit_aspect_scale", blit_aspect_scale) &&
1036 srh.reflect_member("none_separate_view", none_separate_view) &&
1037 srh.reflect_member("tracking_rotation", tracking_rotation) &&
1038 srh.reflect_member("tracking_rotation_origin_x", tracking_rotation_origin[0]) &&
1039 srh.reflect_member("tracking_rotation_origin_y", tracking_rotation_origin[1]) &&
1040 srh.reflect_member("tracking_rotation_origin_z", tracking_rotation_origin[2]) &&
1041 srh.reflect_member("tracking_origin_x", tracking_origin[0])&&
1042 srh.reflect_member("tracking_origin_y", tracking_origin[1])&&
1043 srh.reflect_member("tracking_origin_z", tracking_origin[2]);
1044}
1045
1046#ifndef NO_VR_VIEW_INTERACTOR
1047
1048#include <cgv/base/register.h>
1049
1052 vr_interactor_reg("vr interactor", "registration of vr interactor");
1053
1054// make sure shaders are embedded for single executable builds
1055#ifdef REGISTER_SHADER_FILES
1056#include <crg_vr_view_shader_inc.h>
1057#endif
1058
1059#endif
complete implementation of method actions that only call one method when entering a node
Definition action.h:113
unsigned get_kind() const
return, what kind of event this is, typically a value from the EventId enum
Definition event.cxx:202
virtual void stream_out(std::ostream &os) const
write to stream
Definition event.cxx:139
unsigned get_flags() const
return the event flags
Definition event.cxx:214
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
const mat3 & get_orientation() const
return current orientation matrix
const vec3 & get_position() const
return current position
int get_trackable_index() const
return trackable index
static double get_current_time()
return the current time
Definition trigger.cxx:70
bool read_calibration(const std::string &file_path, bool update_drivers=true)
read calibration from calibration file
Definition vr_calib.cxx:120
void update_calibration_info()
iterate vr drivers and copy calibration information into map
Definition vr_calib.cxx:16
bool write_calibration(const std::string &file_path) const
write calibration to calibration file
Definition vr_calib.cxx:179
vr key events use the key codes defined in vr::VRKeys
Definition vr_events.h:40
vr extension of pose events
Definition vr_events.h:92
bool check_new_state(void *kit_handle, const vr::vr_kit_state &new_state, double time)
in case the current vr state of a kit had been queried somewhere else, use this function to communica...
fvec< T, N > & col(unsigned j)
reference a column of the matrix as a vector
Definition fmat.h:209
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.
static bool enable_global_array(const context &ctx, int loc)
enable attribute array of given location
static bool set_global_attribute_array(const context &ctx, int loc, const vertex_buffer &vbo, type_descriptor td, size_t size, size_t offset, unsigned stride=0)
point array of vertex attribute at location loc to vertex buffer array array stored in CPU memory; in...
static bool disable_global_array(const context &ctx, int loc)
disable attribute array of given location
base class for all drawables, which is independent of the used rendering API.
Definition context.h:621
virtual void announce_external_viewport_change(ivec4 &cgv_viewport_storage)=0
announce an external viewport change performed with rendering API to the cgv framework providing spac...
virtual void mul_modelview_matrix(const dmat4 &MV)
multiply given matrix from right to current modelview matrix
Definition context.cxx:1808
virtual void render_pass(RenderPass render_pass=RP_MAIN, RenderPassFlags render_pass_flags=RPF_ALL, void *user_data=0)
perform the given render task
Definition context.cxx:791
virtual void set_color(const rgba &clr)
set the current color
Definition context.cxx:1617
virtual void recover_from_external_viewport_change(const ivec4 &cgv_viewport_storage)=0
restore cgv viewport to the state before the external change
virtual void announce_external_frame_buffer_change(void *&cgv_fbo_storage)=0
announce an external frame buffer change performed with rendering API to the cgv framework providing ...
virtual unsigned int get_width() const =0
return the width of the window
virtual shader_program & ref_default_shader_program(bool texture_support=false)=0
return a reference to a shader program used to render without illumination
virtual RenderPass get_render_pass() const
return the current render pass
Definition context.cxx:751
virtual RenderPassFlags get_render_pass_flags() const
return the current render pass flags
Definition context.cxx:758
virtual unsigned int get_height() const =0
return the height of the window
virtual void recover_from_external_frame_buffer_change(void *cgv_fbo_storage)=0
restore cgv frame buffer to the state before the external change
virtual void set_projection_matrix(const dmat4 &P)
set the current projection matrix, which transforms from eye to clip space
Definition context.cxx:1853
void pop_modelview_matrix()
see push_V for an explanation
Definition context.cxx:1814
void push_modelview_matrix()
push the current viewing matrix onto a matrix stack for viewing matrices.
Definition context.cxx:1802
virtual void set_modelview_matrix(const dmat4 &MV)
set the current modelview matrix, which transforms from world to eye space
Definition context.cxx:1836
the mesh_render_info structure manages vertex buffer objects for attribute and element buffers as wel...
void draw_all(context &ctx, bool skip_opaque=false, bool skip_blended=false, bool use_materials=true)
execute all draw calls
void set_render_style(const render_style &rs)
reference given render style
Definition renderer.cxx:140
void set_color_array(const context &ctx, const std::vector< T > &colors)
template method to set the color attribute from a vector of colors of type T
Definition renderer.h:192
virtual bool render(context &ctx, size_t start, size_t count, bool use_strips=false, bool use_adjacency=false, uint32_t strip_restart_index=-1)
Convenience function that draws vertex or indexed element with this renderer.
Definition renderer.cxx:342
renderer that supports splatting of spheres
void set_sphere_array(const context &ctx, const std::vector< cgv::math::fvec< T, 4 > > &spheres)
use this function if you store spheres in vec4 with the 4th component the radius
virtual bool blit_fbo(int eye, int x, int y, int w, int h)
initialize render targets and framebuffer objects in current opengl context
virtual void disable_fbo(int eye)
disable the framebuffer object of given eye
int get_width() const
return width in pixel of view
virtual void enable_fbo(int eye)
enable the framebuffer object of given eye (0..left, 1..right)
int get_height() const
return height in pixel of view
virtual void destruct_fbos(EyeSelection es=ES_BOTH)
destruct render targets and framebuffer objects in current opengl context
virtual bool init_fbos(EyeSelection es=ES_BOTH)
initialize render targets and framebuffer objects in current opengl context
virtual bool fbos_initialized(EyeSelection es=ES_BOTH) const
check whether fbos have been initialized
void set_driver_calibration_matrix(vr_driver *driver, const float calibration_matrix[12]) const
single point of write access to calibration transformation of vr drivers
Definition vr_driver.cxx:6
interface class for vr drivers.
Definition vr_driver.h:57
virtual float get_action_zone_height() const =0
return height of action zone in meters
virtual void put_action_zone_bounary(std::vector< float > &boundary) const =0
return a vector of floor points defining the action zone boundary as a closed polygon
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
bool query_state(vr_kit_state &state, int pose_query=2)
query current state of vr kit and return whether this was successful
Definition vr_kit.cxx:103
const vr_kit_info & get_device_info() const
return information on the currently attached devices
Definition vr_kit.cxx:117
const vr_driver * get_driver() const
return driver
Definition vr_kit.cxx:48
const std::string & get_name() const
return name of vr_kit
Definition vr_kit.cxx:54
virtual void put_eye_to_head_matrix(int eye, float *pose_matrix) const =0
access to 3x4 matrix in column major format for transformation from eye (0..left, 1....
virtual void submit_frame()=0
submit the rendered stereo frame to the hmd
cgv::dvec3 get_view_dir_of_kit(int vr_kit_idx=-1) const
query view direction of a vr kit
void set_blit_vr_view_width(int width)
set the width with which vr views are blit
void after_finish(cgv::render::context &ctx)
this method is called in one pass over all drawables after finish frame
void add_trackable_spheres(const float *pose, int i, std::vector< cgv::vec4 > &spheres, std::vector< cgv::rgb > &sphere_colors)
helper to visualize pose with colored spheres
bool self_reflect(cgv::reflect::reflection_handler &srh)
you must overload this for gui creation
void draw_vr_kits(bool do_draw)
set whether to draw vr kits
void draw_separate_view(bool do_draw)
set whether to draw separate view
vr::vr_kit * get_current_vr_kit() const
return a pointer to the current vr kit
cgv::vec3 head_tracker_position
head position from tracker location
float tracking_rotation
rotation angle around the y-axis
void enable_vr_event_debugging(bool enable=true)
set whether vr events should be printed to the console window
cgv::dvec3 get_view_up_dir_of_kit(int vr_kit_idx=-1) const
query view up direction of a vr kit
void create_gui()
you must overload this for gui creation
vr::vr_kit * get_rendered_vr_kit() const
return pointer to rendered vr kit or nullptr if birds eye view is rendered
std::string get_type_name() const
return the type name
bool separate_view
whether the window shows a separate view onto the scene or the one of the current vr kit
cgv::gui::VREventTypeFlags get_event_type_flags() const
query the currently set event type flags
void stream_stats(std::ostream &)
overload to show the content of this object
int pose_query
type of pose query according to vr::vr_kit::query_state function's 2nd parameter
void draw_vr_controllers(bool do_draw)
set whether to draw controllers
float blit_aspect_scale
scale of aspect ratio used for blitting
bool handle_vr_events(cgv::gui::event &e)
overload and implement this method to handle events
cgv::dvec3 get_eye_of_kit(int eye=0, int vr_kit_idx=-1) const
query the eye position of a vr kit.
cgv::vec3 tracking_rotation_origin
location in tracking coordinate system around which rotation is defined
void enable_blit_vr_views(bool enable)
enable vr view blitting
std::string calibration_file_path
path to calibration file
cgv::mat3 head_tracker_orientation
head orientation from tracker orientation
void draw_action_zone(bool do_draw)
whether to draw action zone
cgv::vec3 tracking_origin
origin of tracking coordinate system given in world coordinates
bool blit_vr_views
whether to blit in the views of the vr kits
void draw(cgv::render::context &)
draw all
int none_separate_view
selection of view of current hmd used in case of no separate view (1 ... left, 2 ....
void calibrate_driver()
perform driver calibration
void set_event_type_flags(cgv::gui::VREventTypeFlags flags)
set the event type flags of to be emitted events
const vr::vr_kit_state * get_current_vr_state() const
return a pointer to the state of the current vr kit
bool handle(cgv::gui::event &e)
overload and implement this method to handle events
void finish_frame(cgv::render::context &)
this method is called in one pass over all drawables after drawing
int rendered_eye
rendered_eye: 0...monitor,1...left eye,2...right eye
bool dont_render_kits
whether to not render for kits
void stream_help(std::ostream &os)
overload to stream help information to the given output stream
void init_frame(cgv::render::context &)
this method is called in one pass over all drawables before the draw method
bool attach(base_ptr slot_object, base_ptr attachment_object, void *user_data)
function to attach an object to an object of type attach_slot.
vr_calibration & ref_vr_calibration()
access to singleton object of vr_calibration class
Definition vr_calib.cxx:11
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_CTRL
ctrl modifier
Definition event.h:44
@ KEY_Space
space key
Definition shortcut.h:25
@ EID_POSE
id for a 6D pose change events
Definition event.h:21
@ EID_KEY
id for key event
Definition event.h:17
VREventTypeFlags
flags to define which events should be generated by server
Definition vr_server.h:27
@ VRE_ALL
all event types
Definition vr_server.h:37
@ EF_VR
whether event is from VR kit
Definition event.h:35
@ RP_USER_DEFINED
user defined renderpass
Definition context.h:86
@ RP_MAIN
the main rendering pass triggered by the redraw event
Definition context.h:79
sphere_renderer & ref_sphere_renderer(context &ctx, int ref_count_change)
reference to a singleton sphere renderer that can be shared among drawables
RenderPassFlags
available flags that can be queried from the context and set for a new render pass
Definition context.h:93
@ RPF_HANDLE_SCREEN_SHOT
whether to perform a screen shot if this was scheduled
Definition context.h:121
DummyEnum
some enum to mark an integral parameter to be of enum type
cgv::math::fvec< float, 3 > vec3
declare type of 3d single precision floating point vectors
Definition fvec.h:669
void set_vrmesh_file_name(VRMeshId id, const std::string &file_name)
set the file name for the given vrmesh type
cgv::mat4 get_eye_projection_transform(const vr_kit *vr_kit_ptr, const vr_kit_state &state, float z_near, float z_far, int eye)
query projection matrix for a given eye (0 ... left, 1 ... right)
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...
bool unregister_vr_kit(void *handle, vr_kit *vr_kit_ptr)
unregister a previously registered vr kit by handle and pointer
std::string get_status_string(VRStatus status)
convert flags to string
Definition vr_state.cxx:166
cgv::render::mesh_render_info * get_vrmesh_render_info(cgv::render::context &ctx, VRMeshId id)
return a pointer to a mesh info structure for the given mesh type (read and construct if necessary); ...
cgv::mat4 get_world_to_eye_transform(const vr_kit *vr_kit_ptr, const vr_kit_state &state, int eye)
compute lookat matrix for a given eye (0 ... left, 1 ... right)
VRStatus
different status values for a trackable
Definition vr_state.h:85
@ 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
const unsigned max_nr_controllers
maximum number of attachable controller and tracker devices
Definition vr_state.h:19
const std::string & get_vrmesh_file_name(VRMeshId id)
return the file name for the given vrmesh type
@ VR_INPUT0
input 0
Definition vr_state.h:47
helper functions to work with poses that can be represented with 3x4 matrix or quaternion plus vector
this type specific reflection traits class is used by the reflect_enum function to reflect enum types
VRControllerType type
controller type
Definition vr_info.h:122
unsigned time_stamp
a unique time stamp for fast test whether state changed
Definition vr_state.h:120
vr_controller_info controller[max_nr_controllers]
information for attached controllers and trackers
Definition vr_info.h:152
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
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
defines the class vr::vr_driver class and gives access to the driver registry with the functions vr::...