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>
15#include <cg_vr/vr_events.h>
16#include <cg_vr/vr_calib.h>
24vr_view_interactor::vr_view_interactor(
const char* name) : stereo_view_interactor(name),
25 fence_color1(0,0,1), fence_color2(1,1,0)
28 blit_aspect_scale = 1;
29 none_separate_view = 3;
30 head_tracker_orientation.identity();
33 tracking_rotation_origin =
cgv::vec3(0.0f);
34 tracking_rotation = 0;
36 debug_vr_events =
false;
38 dont_render_kits =
false;
42 rendered_display_ptr = 0;
44 rendered_display_index = -1;
48 vis_type = hmd_vis_type = controller_vis_type = tracker_vis_type = base_vis_type = VVT_MESH;
50 mesh_scales[0] = mesh_scales[1] = mesh_scales[2] = mesh_scales[3] = 1;
52 show_action_zone =
false;
53 current_vr_handle = 0;
54 current_vr_handle_index = -1;
55 kit_enum_definition =
"enums='none=-1'";
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;
68 if (debug_vr_events != enable) {
69 debug_vr_events = enable;
70 on_set(&debug_vr_events);
86 if ((vis_type != VVT_NONE) != do_draw) {
87 vis_type = do_draw ? VVT_MESH : VVT_NONE;
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);
104 if (show_action_zone != do_draw) {
105 show_action_zone = do_draw;
106 on_set(&show_action_zone);
120 if (blit_width != width) {
129 if (current_vr_handle_index >= 0 && current_vr_handle_index <
int(kit_states.size()))
130 return &kit_states[current_vr_handle_index];
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);
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]);
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()) {
157 return cross(get_view_dir(), cross(get_view_up_dir(), get_view_dir()));
159 return reinterpret_cast<const cgv::vec3&
>(kit_states[vr_kit_idx].hmd.pose[3]);
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())
168 return reinterpret_cast<const cgv::vec3&
>(kit_states[vr_kit_idx].hmd.pose[9]);
180 on_set(&event_flags);
184void vr_view_interactor::on_status_change(
void* handle,
int controller_index,
vr::VRStatus old_status,
vr::VRStatus new_status)
188 std::cout <<
"on status change(" <<
handle <<
","
194void vr_view_interactor::on_device_change(
void* handle,
bool attach)
197 new_kits.push_back(
handle);
199 old_kits.push_back(
handle);
202 std::cout <<
"on device change(" <<
handle <<
","
203 << (
attach?
"attach":
"detach") <<
")" << std::endl;
213 float calibration_matrix[12];
218 const_cast<vr::vr_driver*
>(driver_ptr)->enable_calibration_transformation();
224 return "vr_view_interactor";
227void vr_view_interactor::on_set(
void* member_ptr)
237 if (member_ptr == &hmd_mesh_file_name)
239 if (member_ptr == &controller_mesh_file_name)
241 if (member_ptr == &tracker_mesh_file_name)
243 if (member_ptr == &base_mesh_file_name) {
245 update_member(&base_mesh_file_name);
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);
256 if (member_ptr == ¤t_vr_handle_index) {
257 if (current_vr_handle_index == -1) {
258 current_vr_handle = 0;
265 if (current_vr_handle_index <
int(kits.size()))
266 current_vr_handle = kits[current_vr_handle_index];
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];
284 put_coordinate_system(x, y, z);
290 stereo_view_interactor::on_set(member_ptr);
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);
304 stereo_view_interactor::stream_stats(os);
319 mesh_scales[vr::VRM_TRACKER] = 0.001f;
324 return stereo_view_interactor::init(ctx);
338 if (vrke.get_key() ==
vr::VR_INPUT0 && vrke.get_controller_index() == 1) {
340 start_pose =
reinterpret_cast<const cgv::mat3x4&
>(*vrke.get_state().controller[1].pose);
344 tracking_origin += pose_position(end_pose) - pose_position(start_pose);
355 if (debug_vr_events) {
357 std::cout << std::endl;
362 if (head_tracker != -1) {
369 set_view_up_dir(V.
col(1));
370 set_view_dir(-V.
col(2));
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(¤t_vr_handle_index);
402 if (current_vr_handle_index >= 0) {
416 for (
int i = 0; i < 3; ++i) {
427 return stereo_view_interactor::handle(e);
434 stereo_view_interactor::finish_frame(ctx);
439 stereo_view_interactor::after_finish(ctx);
441 if (rendered_display_ptr) {
447 int x0 = 0, width = ctx.
get_width(), eye = 0, eye_end = 2;
449 case 1: eye_end = 1;
break;
450 case 2: eye = 1;
break;
451 case 3: width /= 2;
break;
453 for (; eye < eye_end; ++eye) {
459 rendered_display_ptr = 0;
460 rendered_display_index = -1;
465 for (
size_t ki = 0; ki < kits.size(); ++ki) {
469 vr::vr_kit* kit_ptr = get_vr_kit_from_index((
int)ki);
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;
480 y0 += blit_height + 5;
485 if (current_vr_handle)
490vr::vr_kit* vr_view_interactor::get_vr_kit_from_index(
int i)
const
495void vr_view_interactor::configure_kits()
497 bool update_kits =
false;
498 void* last_current_vr_handle = current_vr_handle;
500 while (!old_kits.empty()) {
501 if (current_vr_handle == old_kits.back())
502 current_vr_handle = 0;
508 std::cerr <<
"unable to unregister removed kit <" << old_kits.back() <<
">" << std::endl;
512 auto iter = std::find(kits.begin(), kits.end(), old_kits.back());
513 if (iter != kits.end()) {
519 if (current_vr_handle == 0 && !kits.empty())
520 current_vr_handle = kits.front();
522 while (!new_kits.empty()) {
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();
531 kits.push_back(new_kits.back());
536 kit_states.resize(kits.size());
539 kit_enum_definition =
"enums='none=-1";
540 for (
auto handle : kits) {
542 std::string kit_name;
546 std::stringstream ss;
550 kit_enum_definition +=
";";
551 kit_enum_definition += kit_name;
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;
558 if (update_kits || current_vr_handle != last_current_vr_handle) {
559 if (current_vr_handle == 0)
560 current_vr_handle_index = -1;
562 for (
unsigned i = 0; i < kits.size(); ++i)
563 if (kits[i] == current_vr_handle) {
564 current_vr_handle_index = i;
570 update_member(¤t_vr_handle_index);
575void vr_view_interactor::query_vr_states()
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) {
587 for (
unsigned i = 0; i < kits.size(); ++i) {
588 vr::vr_kit* kit_ptr = get_vr_kit_from_index(i);
591 if (kit_ptr == current_kit_ptr)
605 for (rendered_display_index = 0; rendered_display_index<int(kits.size()); ++rendered_display_index) {
606 if (rendered_display_index == current_vr_handle_index)
608 rendered_display_ptr = get_vr_kit_from_index(rendered_display_index);
609 if (!rendered_display_ptr)
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) {
638 this->fbo_handle = fbo_handle;
639 this->cgv_viewport = cgv_viewport;
649 rendered_display_ptr = 0;
650 rendered_display_index = -1;
653 rendered_display_ptr = 0;
654 rendered_display_index = -1;
665 if (kits.size() > 0) {
674 if (rendered_display_ptr) {
676 compute_clipping_planes(z_near_derived, z_far_derived, clip_relative_to_extent);
683 stereo_view_interactor::init_frame(ctx);
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));
709 std::vector<cgv::vec4> spheres;
710 std::vector<cgv::rgb> sphere_colors;
715 std::set<const vr::vr_driver*> driver_set;
716 for (
int i = 0; i < (int)kits.size(); ++i) {
718 vr::vr_kit* kit_ptr = get_vr_kit_from_index(i);
722 if (base_vis_type != VVT_NONE)
725 if (hmd_vis_type == VVT_NONE && controller_vis_type == VVT_NONE && tracker_vis_type == VVT_NONE)
730 if (i == current_vr_handle_index)
731 state_ptr = &kit_states[current_vr_handle_index];
736 if (kit_ptr != rendered_display_ptr) {
738 if ((hmd_vis_type & VVT_MESH) != 0) {
744 update_member(&hmd_mesh_file_name);
747 hmd_vis_type = VVT_SPHERE;
748 on_set(&hmd_vis_type);
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]))
763 if ((hmd_vis_type & VVT_SPHERE) != 0) {
764 float left_eye_to_head[12];
765 float right_eye_to_head[12];
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));
787 bool show_trackable_spheres;
789 float mesh_scale = 1;
791 show_trackable_spheres = (controller_vis_type & VVT_SPHERE) != 0;
792 if ((controller_vis_type & VVT_MESH) != 0) {
793 if (!MI_controller_ptr) {
795 if (MI_controller_ptr) {
797 update_member(&controller_mesh_file_name);
800 controller_vis_type = VVT_SPHERE;
801 on_set(&controller_vis_type);
804 if (MI_controller_ptr) {
805 M_info = MI_controller_ptr;
806 mesh_scale = mesh_scales[vr::VRM_CONTROLLER];
811 show_trackable_spheres = (tracker_vis_type & VVT_SPHERE) != 0;
812 if ((tracker_vis_type & VVT_MESH) != 0) {
813 if (!MI_tracker_ptr) {
815 if (MI_tracker_ptr) {
817 update_member(&tracker_mesh_file_name);
820 tracker_vis_type = VVT_SPHERE;
821 on_set(&tracker_vis_type);
824 if (MI_tracker_ptr) {
825 M_info = MI_tracker_ptr;
826 mesh_scale = mesh_scales[vr::VRM_TRACKER];
830 if (show_trackable_spheres)
841 for (
auto& dp : driver_set) {
842 auto ss = dp->get_tracking_reference_states();
843 for (
const auto& s : ss) {
845 if ((base_vis_type & VVT_SPHERE) != 0)
847 if ((base_vis_type & VVT_MESH) != 0) {
852 update_member(&base_mesh_file_name);
855 base_vis_type = VVT_SPHERE;
856 on_set(&base_vis_type);
870 if (!spheres.empty()) {
872 sr.set_y_view_angle(
float(get_y_view_angle()));
876 sr.
render(ctx, 0, spheres.size());
883 if (show_action_zone && current_vr_handle) {
885 vr::vr_kit* kit_ptr = get_vr_kit_from_index(current_vr_handle_index);
892 std::vector<float> boundary;
894 size_t n = boundary.size() / 3;
895 std::vector<cgv::vec3> G;
898 for (i = 0; i < 5; ++i) {
899 for (
size_t j = 0; j < n; ++j) {
901 p += 0.25f*i*h*up_dir;
905 glLineStipple(3, GLushort(0xF0F0));
906 glEnable(GL_LINE_STIPPLE);
907 glLineWidth(fence_line_width);
909 int pos_idx = prog.get_position_index();
913 float lambda = float(cos(fence_frequency*time));
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);
920 glDisable(GL_LINE_STIPPLE);
933 stereo_view_interactor::draw(ctx);
939 add_member_control(
this,
"current vr kit", (
cgv::type::DummyEnum&)current_vr_handle_index,
"dropdown", kit_enum_definition);
943 "open=true;open_title='open calibration file';filter='calib (cal):*.cal|all files:*.*';"
944 "save=true;save_title='save calibration file';w=140");
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")) {
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'");
959 if (begin_tree_node(
"VR rendering",
separate_view,
false,
"level=2")) {
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");
971 add_member_control(
this,
"head_tracker", head_tracker,
"value_slider",
"min=-1;max=3");
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")) {
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");
984 end_tree_node(fence_color1);
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'");
993 if (begin_tree_node(
"sphere styles", srs,
false,
"level=3")) {
995 add_gui(
"sphere style", srs);
1002 if (begin_tree_node(
"VR events", event_flags,
false,
"level=2")) {
1004 add_member_control(
this,
"pose_query",
pose_query,
"value_slider",
"min=0;max=2;ticks=true");
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=''");
1009 end_tree_node(event_flags);
1011 stereo_view_interactor::create_gui();
1017 return stereo_view_interactor::self_reflect(srh) &&
1021 srh.
reflect_member(
"controller_vis_type", controller_vis_type) &&
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) &&
1046#ifndef NO_VR_VIEW_INTERACTOR
1048#include <cgv/base/register.h>
1052 vr_interactor_reg(
"vr interactor",
"registration of vr interactor");
1055#ifdef REGISTER_SHADER_FILES
1056#include <crg_vr_view_shader_inc.h>
complete implementation of method actions that only call one method when entering a node
unsigned get_kind() const
return, what kind of event this is, typically a value from the EventId enum
virtual void stream_out(std::ostream &os) const
write to stream
unsigned get_flags() const
return the event flags
unsigned char get_modifiers() const
return the active modifiers as values from EventModifier combined with a logical or-operation
class to represent all possible keyboard events with the EID_KEY
unsigned short get_key() const
return the key being a capital letter, digit or a value from the Keys enum
KeyAction get_action() const
return the key event action
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
bool read_calibration(const std::string &file_path, bool update_drivers=true)
read calibration from calibration file
void update_calibration_info()
iterate vr drivers and copy calibration information into map
bool write_calibration(const std::string &file_path) const
write calibration to calibration file
vr key events use the key codes defined in vr::VRKeys
vr extension of pose events
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
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.
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
virtual void render_pass(RenderPass render_pass=RP_MAIN, RenderPassFlags render_pass_flags=RPF_ALL, void *user_data=0)
perform the given render task
virtual void set_color(const rgba &clr)
set the current color
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
virtual RenderPassFlags get_render_pass_flags() const
return the current render pass flags
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
void pop_modelview_matrix()
see push_V for an explanation
void push_modelview_matrix()
push the current viewing matrix onto a matrix stack for viewing matrices.
virtual void set_modelview_matrix(const dmat4 &MV)
set the current modelview matrix, which transforms from world to eye space
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
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
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.
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
interface class for vr drivers.
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...
bool query_state(vr_kit_state &state, int pose_query=2)
query current state of vr kit and return whether this was successful
const vr_kit_info & get_device_info() const
return information on the currently attached devices
const vr_driver * get_driver() const
return driver
const std::string & get_name() const
return name of vr_kit
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
vr_server & ref_vr_server()
return a reference to gamepad server singleton
@ KA_PRESS
key press action
@ KA_RELEASE
key release action
@ EID_POSE
id for a 6D pose change events
@ EID_KEY
id for key event
VREventTypeFlags
flags to define which events should be generated by server
@ EF_VR
whether event is from VR kit
@ RP_USER_DEFINED
user defined renderpass
@ RP_MAIN
the main rendering pass triggered by the redraw event
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
@ RPF_HANDLE_SCREEN_SHOT
whether to perform a screen shot if this was scheduled
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
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
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
@ VRS_TRACKED
trackable is connected and tracked
@ VRS_DETACHED
trackable is not reachable via wireless
const unsigned max_nr_controllers
maximum number of attachable controller and tracker devices
const std::string & get_vrmesh_file_name(VRMeshId id)
return the file name for the given vrmesh type
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
unsigned time_stamp
a unique time stamp for fast test whether state changed
vr_controller_info controller[max_nr_controllers]
information for attached controllers and trackers
structure that stores all information describing the state of a VR kit
vr_controller_state controller[max_nr_controllers]
status, pose, button, axes, and vibration information of up to vr::max_nr_controllers controller and ...
vr_trackable_state hmd
status and pose of hmd
VRStatus status
whether trackable is currently tracked, only in case of true, the pose member contains useful informa...
float pose[12]
pose as 3x4 matrix in column major format, where each column is a vector in world coordinates
defines the class vr::vr_driver class and gives access to the driver registry with the functions vr::...