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}
109
111{
112 if (blit_vr_views != enable) {
113 blit_vr_views = enable;
114 on_set(&blit_vr_views);
115 }
116}
117
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
176
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}
226
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 cgv::gui::provider::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;
251 cgv::gui::provider::update_member(&controller_vis_type);
252 cgv::gui::provider::update_member(&tracker_vis_type);
253 cgv::gui::provider::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;
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 cgv::gui::provider::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) {
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 cgv::gui::provider::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}
706
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 cgv::gui::provider::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 cgv::gui::provider::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 cgv::gui::provider::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 cgv::gui::provider::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
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
virtual void update_member(void *member_ptr)
call this to update all views and controls of a member
Definition provider.cxx:72
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:670
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:1957
virtual void set_color(const rgba &clr)
set the current color
Definition context.cxx:1761
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:857
virtual RenderPassFlags get_render_pass_flags() const
return the current render pass flags
Definition context.cxx:864
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:2002
virtual void render_pass(RenderPass render_pass=RP_MAIN, RenderPassFlags render_pass_flags=RPF_ALL, void *user_data=0, int rp_idx=-1)
perform the given render task
Definition context.cxx:920
void pop_modelview_matrix()
see push_V for an explanation
Definition context.cxx:1963
void push_modelview_matrix()
push the current viewing matrix onto a matrix stack for viewing matrices.
Definition context.cxx:1951
virtual void set_modelview_matrix(const dmat4 &MV)
set the current modelview matrix, which transforms from world to eye space
Definition context.cxx:1985
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:142
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:247
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:344
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
int get_width() const
return width in pixel of view
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
VRkitVisType
different visualization types for vr kit components
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:142
@ RP_MAIN
the main rendering pass triggered by the redraw event
Definition context.h:135
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:149
@ RPF_HANDLE_SCREEN_SHOT
whether to perform a screen shot if this was scheduled
Definition context.h:177
DummyEnum
some enum to mark an integral parameter to be of enum type
cgv::math::fvec< float, 4 > vec4
declare type of 4d single precision floating point vectors (used for homogeneous coordinates)
Definition fvec.h:696
cgv::math::fvec< double, 3 > dvec3
declare type of 3d double precision floating point vectors
Definition fvec.h:701
cgv::math::fvec< int32_t, 4 > ivec4
declare type of 4d 32 bit integer vectors
Definition fvec.h:723
cgv::media::color< float, cgv::media::RGB > rgb
declare rgb color type with 32 bit components
Definition color.h:896
cgv::math::fmat< float, 3, 3 > mat3
declare type of 3x3 matrices
Definition fmat.h:460
cgv::math::fvec< float, 3 > vec3
declare type of 3d single precision floating point vectors
Definition fvec.h:694
cgv::math::fmat< float, 3, 4 > mat3x4
declare type of 3x4 matrices which are often used to store a pose
Definition fmat.h:474
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
convenience class to register an object of the given class type with one constructor argument
Definition register.h:172
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::...