cgv
Loading...
Searching...
No Matches
vr_test.cxx
1#include "vr_test.h"
2
3#include <cgv/signal/rebind.h>
4#include <cgv/base/register.h>
5#include <cgv/math/ftransform.h>
6#include <cgv/utils/scan.h>
7#include <cgv/utils/options.h>
8#include <cgv/utils/file.h>
9#include <cgv/gui/dialog.h>
10#include <cgv/gui/file_dialog.h>
11#include <cgv/render/attribute_array_binding.h>
12#include <cgv_gl/sphere_renderer.h>
13#include <cgv/media/mesh/simple_mesh.h>
14#include <cg_vr/vr_events.h>
15
16#include <random>
17#include <sstream>
18
19#include "intersection.h"
20
21
22void vr_test::init_cameras(vr::vr_kit* kit_ptr)
23{
24 vr::vr_camera* camera_ptr = kit_ptr->get_camera();
25 if (!camera_ptr)
26 return;
27 nr_cameras = camera_ptr->get_nr_cameras();
28 frame_split = camera_ptr->get_frame_split();
29 for (int i = 0; i < nr_cameras; ++i) {
30 std::cout << "camera " << i << "(" << nr_cameras << "):" << std::endl;
31 camera_ptr->put_camera_intrinsics(i, false, &focal_lengths[i](0), &camera_centers[i](0));
32 camera_ptr->put_camera_intrinsics(i, true, &focal_lengths[2 + i](0), &camera_centers[2 + i](0));
33 std::cout << " fx=" << focal_lengths[i][0] << ", fy=" << focal_lengths[i][1] << ", center=[" << camera_centers[i] << "]" << std::endl;
34 std::cout << " fx=" << focal_lengths[2+i][0] << ", fy=" << focal_lengths[2+i][1] << ", center=[" << camera_centers[2+i] << "]" << std::endl;
35 float camera_to_head[12];
36 camera_ptr->put_camera_to_head_matrix(i, camera_to_head);
37 kit_ptr->put_eye_to_head_matrix(i, camera_to_head);
38 camera_to_head_matrix[i] = vr::get_mat4_from_pose(camera_to_head);
39 std::cout << " C2H=" << camera_to_head_matrix[i] << std::endl;
40 camera_ptr->put_projection_matrix(i, false, 0.001f, 10.0f, &camera_projection_matrix[i](0, 0));
41 camera_ptr->put_projection_matrix(i, true, 0.001f, 10.0f, &camera_projection_matrix[2+i](0, 0));
42 std::cout << " dP=" << camera_projection_matrix[i] << std::endl;
43 std::cout << " uP=" << camera_projection_matrix[2+i] << std::endl;
44 }
46}
47
48void vr_test::start_camera()
49{
50 if (!vr_view_ptr)
51 return;
52 vr::vr_kit* kit_ptr = vr_view_ptr->get_current_vr_kit();
53 if (!kit_ptr)
54 return;
55 vr::vr_camera* camera_ptr = kit_ptr->get_camera();
56 if (!camera_ptr)
57 return;
58 if (!camera_ptr->start())
59 cgv::gui::message(camera_ptr->get_last_error());
60}
61
62void vr_test::stop_camera()
63{
64 if (!vr_view_ptr)
65 return;
66 vr::vr_kit* kit_ptr = vr_view_ptr->get_current_vr_kit();
67 if (!kit_ptr)
68 return;
69 vr::vr_camera* camera_ptr = kit_ptr->get_camera();
70 if (!camera_ptr)
71 return;
72 if (!camera_ptr->stop())
73 cgv::gui::message(camera_ptr->get_last_error());
74}
75
77void vr_test::compute_intersections(const vec3& origin, const vec3& direction, int ci, const rgb& color)
78{
79 for (size_t i = 0; i < movable_boxes.size(); ++i) {
80 vec3 origin_box_i = origin - movable_box_translations[i];
81 movable_box_rotations[i].inverse_rotate(origin_box_i);
82 vec3 direction_box_i = direction;
83 movable_box_rotations[i].inverse_rotate(direction_box_i);
84 float t_result;
85 vec3 p_result;
86 vec3 n_result;
87 if (cgv::media::ray_axis_aligned_box_intersection(
88 origin_box_i, direction_box_i,
89 movable_boxes[i],
90 t_result, p_result, n_result, 0.000001f)) {
91
92 // transform result back to world coordinates
93 movable_box_rotations[i].rotate(p_result);
94 p_result += movable_box_translations[i];
95 movable_box_rotations[i].rotate(n_result);
96
97 // store intersection information
98 intersection_points.push_back(p_result);
99 intersection_colors.push_back(color);
100 intersection_box_indices.push_back((int)i);
101 intersection_controller_indices.push_back(ci);
102 }
103 }
104}
105
107void vr_test::on_status_change(void* kit_handle, int ci, vr::VRStatus old_status, vr::VRStatus new_status)
108{
109 // ignore all but left controller changes
110 if (ci != 0)
111 return;
112 vr::vr_kit* kit_ptr = vr::get_vr_kit(kit_handle);
113 // check for attaching of controller
114 if (old_status == vr::VRS_DETACHED) {
115 left_inp_cfg.resize(kit_ptr->get_device_info().controller[0].nr_inputs);
116 for (int ii = 0; ii < (int)left_inp_cfg.size(); ++ii)
117 left_inp_cfg[ii] = kit_ptr->get_controller_input_config(0, ii);
119 }
120 // check for attaching of controller
121 if (new_status == vr::VRS_DETACHED) {
122 left_inp_cfg.clear();
124 }
125}
126
128void vr_test::on_device_change(void* kit_handle, bool attach)
129{
130 if (attach) {
131 if (last_kit_handle == 0) {
132 vr::vr_kit* kit_ptr = vr::get_vr_kit(kit_handle);
133 init_cameras(kit_ptr);
134 if (kit_ptr) {
135 last_kit_handle = kit_handle;
136 // copy left controller input configurations from new device in order to make it adjustable
137 left_inp_cfg.resize(kit_ptr->get_device_info().controller[0].nr_inputs);
138 for (int ii = 0; ii < (int)left_inp_cfg.size(); ++ii)
139 left_inp_cfg[ii] = kit_ptr->get_controller_input_config(0, ii);
141 }
142 }
143 }
144 else {
145 if (kit_handle == last_kit_handle) {
146 last_kit_handle = 0;
148 }
149 }
150}
151
153void vr_test::construct_table(float tw, float td, float th, float tW) {
154 // construct table
155 rgb table_clr(0.3f, 0.2f, 0.0f);
156 boxes.push_back(box3(
157 vec3(-0.5f*tw, th - tW, -0.5f*td),
158 vec3(0.5f*tw, th, 0.5f*td)));
159 box_colors.push_back(table_clr);
160
161 boxes.push_back(box3(vec3(-0.5f*tw + 2*tW, 0, -0.5f*td+2*tW), vec3(-0.5f*tw+tW, th - tW, -0.5f*td + tW)));
162 boxes.push_back(box3(vec3(-0.5f*tw + 2*tW, 0, 0.5f*td-2*tW), vec3(-0.5f*tw + tW, th - tW, 0.5f*td - tW)));
163 boxes.push_back(box3(vec3(0.5f*tw-2*tW, 0, -0.5f*td+tW), vec3(0.5f*tw - tW, th - tW, -0.5f*td +2* tW)));
164 boxes.push_back(box3(vec3(0.5f*tw-2*tW, 0, 0.5f*td-2*tW), vec3(0.5f*tw - tW, th - tW, 0.5f*td - tW)));
165 box_colors.push_back(table_clr);
166 box_colors.push_back(table_clr);
167 box_colors.push_back(table_clr);
168 box_colors.push_back(table_clr);
169}
170
172void vr_test::construct_room(float w, float d, float h, float W, bool walls, bool ceiling) {
173 // construct floor
174 boxes.push_back(box3(vec3(-0.5f*w, -W, -0.5f*d), vec3(0.5f*w, 0, 0.5f*d)));
175 box_colors.push_back(rgb(0.2f, 0.2f, 0.2f));
176
177 if(walls) {
178 // construct walls
179 boxes.push_back(box3(vec3(-0.5f*w, -W, -0.5f*d - W), vec3(0.5f*w, h, -0.5f*d)));
180 box_colors.push_back(rgb(0.8f, 0.5f, 0.5f));
181 boxes.push_back(box3(vec3(-0.5f*w, -W, 0.5f*d), vec3(0.5f*w, h, 0.5f*d + W)));
182 box_colors.push_back(rgb(0.8f, 0.5f, 0.5f));
183
184 boxes.push_back(box3(vec3(0.5f*w, -W, -0.5f*d - W), vec3(0.5f*w + W, h, 0.5f*d + W)));
185 box_colors.push_back(rgb(0.5f, 0.8f, 0.5f));
186 }
187 if(ceiling) {
188 // construct ceiling
189 boxes.push_back(box3(vec3(-0.5f*w - W, h, -0.5f*d - W), vec3(0.5f*w + W, h + W, 0.5f*d + W)));
190 box_colors.push_back(rgb(0.5f, 0.5f, 0.8f));
191 }
192}
193
195void vr_test::construct_environment(float s, float ew, float ed, float w, float d, float h) {
196 std::default_random_engine generator;
197 std::uniform_real_distribution<float> distribution(0, 1);
198 unsigned n = unsigned(ew / s);
199 unsigned m = unsigned(ed / s);
200 float ox = 0.5f*float(n)*s;
201 float oz = 0.5f*float(m)*s;
202 for(unsigned i = 0; i < n; ++i) {
203 float x = i * s - ox;
204 for(unsigned j = 0; j < m; ++j) {
205 float z = j * s - oz;
206 if(fabsf(x) < 0.5f*w && fabsf(x + s) < 0.5f*w && fabsf(z) < 0.5f*d && fabsf(z + s) < 0.5f*d)
207 continue;
208 float h = 0.2f*(std::max(abs(x) - 0.5f*w, 0.0f) + std::max(abs(z) - 0.5f*d, 0.0f))*distribution(generator) + 0.1f;
209 boxes.push_back(box3(vec3(x, 0.0f, z), vec3(x + s, h, z + s)));
210 rgb color = cgv::media::color<float, cgv::media::HLS>(distribution(generator), 0.1f*distribution(generator) + 0.15f, 0.3f);
211 box_colors.push_back(color);
212 /*box_colors.push_back(
213 rgb(0.3f*distribution(generator) + 0.3f,
214 0.3f*distribution(generator) + 0.2f,
215 0.2f*distribution(generator) + 0.1f));*/
216 }
217 }
218}
219
221void vr_test::construct_movable_boxes(float tw, float td, float th, float tW, size_t nr) {
222 /*
223 vec3 extent(0.75f, 0.5f, 0.05f);
224 movable_boxes.push_back(box3(-0.5f * extent, 0.5f * extent));
225 movable_box_colors.push_back(rgb(0, 0, 0));
226 movable_box_translations.push_back(vec3(0, 1.2f, 0));
227 movable_box_rotations.push_back(quat(1, 0, 0, 0));
228 */
229 std::default_random_engine generator;
230 std::uniform_real_distribution<float> distribution(0, 1);
231 std::uniform_real_distribution<float> signed_distribution(-1, 1);
232 for(size_t i = 0; i < nr; ++i) {
233 float x = distribution(generator);
234 float y = distribution(generator);
235 vec3 extent(distribution(generator), distribution(generator), distribution(generator));
236 extent += 0.01f;
237 extent *= std::min(tw, td)*0.1f;
238
239 vec3 center(-0.5f*tw + x * tw, th + tW, -0.5f*td + y * td);
240 movable_boxes.push_back(box3(-0.5f*extent, 0.5f*extent));
241 movable_box_colors.push_back(rgb(distribution(generator), distribution(generator), distribution(generator)));
242 movable_box_translations.push_back(center);
243 quat rot(signed_distribution(generator), signed_distribution(generator), signed_distribution(generator), signed_distribution(generator));
244 rot.normalize();
245 movable_box_rotations.push_back(rot);
246 }
247}
248
250void vr_test::build_scene(float w, float d, float h, float W, float tw, float td, float th, float tW)
251{
252 construct_room(w, d, h, W, false, false);
253 construct_table(tw, td, th, tW);
254 construct_environment(0.3f, 3 * w, 3 * d, w, d, h);
255 //construct_environment(0.4f, 0.5f, 1u, w, d, h);
256 construct_movable_boxes(tw, td, th, tW, 50);
257}
258
259vr_test::vr_test()
260{
261 frame_split = 0;
262 extent_texcrd = vec2(0.5f, 0.5f);
263 center_left = vec2(0.5f,0.25f);
264 center_right = vec2(0.5f,0.25f);
265 seethrough_gamma = 0.33f;
266 frame_width = frame_height = 0;
267 background_distance = 2;
268 background_extent = 2;
269 undistorted = true;
270 shared_texture = true;
271 max_rectangle = false;
272 nr_cameras = 0;
273 camera_tex_id = -1;
274 camera_aspect = 1;
275 use_matrix = true;
276 show_seethrough = false;
277 set_name("vr_test");
278 build_scene(5, 7, 3, 0.2f, 0.8f, 0.8f, 0.72f, 0.03f);
279 vr_view_ptr = 0;
280 ray_length = 2;
281 last_kit_handle = 0;
284
285 mesh_scale = 0.0005f;
286 mesh_location = dvec3(0, 0.85f, 0);
287 mesh_orientation = dquat(1, 0, 0, 0);
288
289 srs.radius = 0.005f;
290
291 label_outofdate = true;
292 label_text = "Info Board";
293 label_font_idx = 0;
294 label_upright = true;
295 label_face_type = cgv::media::font::FFA_BOLD;
296 label_resolution = 256;
297 label_size = 20.0f;
298 label_color = rgb(1, 1, 1);
299
300 state[0] = state[1] = state[2] = state[3] = IS_NONE;
301}
302
303void vr_test::stream_help(std::ostream& os) {
304 os << "vr_test: no shortcuts defined" << std::endl;
305}
306
307void vr_test::on_set(void* member_ptr)
308{
309 if (member_ptr == &label_face_type || member_ptr == &label_font_idx) {
310 label_font_face = cgv::media::font::find_font(font_names[label_font_idx])->get_font_face(label_face_type);
311 label_outofdate = true;
312 }
313 if ((member_ptr >= &label_color && member_ptr < &label_color + 1) ||
314 member_ptr == &label_size || member_ptr == &label_text) {
315 label_outofdate = true;
316 }
317
318 vr::vr_kit* kit_ptr = vr::get_vr_kit(last_kit_handle);
319 if (kit_ptr) {
320 for (int ii = 0; ii < (int)left_inp_cfg.size(); ++ii)
321 if (member_ptr >= &left_inp_cfg[ii] && member_ptr < &left_inp_cfg[ii] + 1)
322 kit_ptr->set_controller_input_config(0, ii, left_inp_cfg[ii]);
323 }
324 update_member(member_ptr);
325 post_redraw();
326}
327
329{
330 // check if vr event flag is not set and don't process events in this case
331 if ((e.get_flags() & cgv::gui::EF_VR) == 0)
332 return false;
333 // check event id
334 switch (e.get_kind()) {
336 {
337 cgv::gui::vr_key_event& vrke = static_cast<cgv::gui::vr_key_event&>(e);
338 if (vrke.get_action() != cgv::gui::KA_RELEASE) {
339 switch (vrke.get_key()) {
340 case vr::VR_GRIP:
341 std::cout << "grip button " << (vrke.get_controller_index() == 0 ? "left":"right") << " controller pressed" << std::endl;
342 return true;
344 std::cout << "touch pad of " << (vrke.get_controller_index() == 0 ? "left" : "right") << " controller pressed at right direction" << std::endl;
345 return true;
346 }
347 }
348 break;
349 }
351 {
353 std::cout << "throttle " << vrte.get_throttle_index() << " of controller " << vrte.get_controller_index()
354 << " adjusted from " << vrte.get_last_value() << " to " << vrte.get_value() << std::endl;
355 return true;
356 }
358 {
359 cgv::gui::vr_stick_event& vrse = static_cast<cgv::gui::vr_stick_event&>(e);
360 switch (vrse.get_action()) {
362 if (state[vrse.get_controller_index()] == IS_OVER)
363 state[vrse.get_controller_index()] = IS_GRAB;
364 break;
366 if (state[vrse.get_controller_index()] == IS_GRAB)
367 state[vrse.get_controller_index()] = IS_OVER;
368 break;
371 std::cout << "stick " << vrse.get_stick_index()
372 << " of controller " << vrse.get_controller_index()
374 << " at " << vrse.get_x() << ", " << vrse.get_y() << std::endl;
375 return true;
378 return true;
379 std::cout << "stick " << vrse.get_stick_index()
380 << " of controller " << vrse.get_controller_index()
382 << " from " << vrse.get_last_x() << ", " << vrse.get_last_y()
383 << " to " << vrse.get_x() << ", " << vrse.get_y() << std::endl;
384 return true;
385 }
386 return true;
387 }
389 cgv::gui::vr_pose_event& vrpe = static_cast<cgv::gui::vr_pose_event&>(e);
390 // check for controller pose events
391 int ci = vrpe.get_trackable_index();
392 if (ci != -1) {
393 if (state[ci] == IS_GRAB) {
394 // in grab mode apply relative transformation to grabbed boxes
395
396 // get previous and current controller position
397 vec3 last_pos = vrpe.get_last_position();
398 vec3 pos = vrpe.get_position();
399 // get rotation from previous to current orientation
400 // this is the current orientation matrix times the
401 // inverse (or transpose) of last orientation matrix:
402 // vrpe.get_orientation()*transpose(vrpe.get_last_orientation())
403 mat3 rotation = vrpe.get_rotation_matrix();
404 // iterate intersection points of current controller
405 for (size_t i = 0; i < intersection_points.size(); ++i) {
406 if (intersection_controller_indices[i] != ci)
407 continue;
408 // extract box index
409 unsigned bi = intersection_box_indices[i];
410 // update translation with position change and rotation
411 movable_box_translations[bi] =
412 rotation * (movable_box_translations[bi] - last_pos) + pos;
413 // update orientation with rotation, note that quaternions
414 // need to be multiplied in oposite order. In case of matrices
415 // one would write box_orientation_matrix *= rotation
416 movable_box_rotations[bi] = quat(rotation) * movable_box_rotations[bi];
417 // update intersection points
418 intersection_points[i] = rotation * (intersection_points[i] - last_pos) + pos;
419 }
420 }
421 else {// not grab
422 // clear intersections of current controller
423 size_t i = 0;
424 while (i < intersection_points.size()) {
425 if (intersection_controller_indices[i] == ci) {
426 intersection_points.erase(intersection_points.begin() + i);
427 intersection_colors.erase(intersection_colors.begin() + i);
428 intersection_box_indices.erase(intersection_box_indices.begin() + i);
429 intersection_controller_indices.erase(intersection_controller_indices.begin() + i);
430 }
431 else
432 ++i;
433 }
434
435 // compute intersections
436 vec3 origin, direction;
437 vrpe.get_state().controller[ci].put_ray(&origin(0), &direction(0));
438 compute_intersections(origin, direction, ci, ci == 0 ? rgb(1, 0, 0) : rgb(0, 0, 1));
439 label_outofdate = true;
440
441
442 // update state based on whether we have found at least
443 // one intersection with controller ray
444 if (intersection_points.size() == i)
445 state[ci] = IS_NONE;
446 else
447 if (state[ci] == IS_NONE)
448 state[ci] = IS_OVER;
449 }
450 post_redraw();
451 }
452 return true;
453 }
454 return false;
455}
456
458{
460 font_enum_decl = "enums='";
461 for (unsigned i = 0; i < font_names.size(); ++i) {
462 if (i > 0)
463 font_enum_decl += ";";
464 std::string fn(font_names[i]);
465 if (cgv::utils::to_lower(fn) == "calibri") {
466 label_font_face = cgv::media::font::find_font(fn)->get_font_face(label_face_type);
467 label_font_idx = i;
468 }
469 font_enum_decl += std::string(fn);
470 }
471 font_enum_decl += "'";
472
473 if (!cgv::utils::has_option("NO_OPENVR"))
474 ctx.set_gamma(1.0f);
475
477//#ifdef 1
478 if (M.read("D:/data/surface/meshes/obj/Max-Planck_lowres.obj")) {
479//#else
480// if (M.read("D:/data/surface/meshes/obj/Max-Planck_highres.obj")) {
481//#endif
482 MI.construct(ctx, M);
483 MI.bind(ctx, ctx.ref_surface_shader_program(true), true);
484 }
485
487
488 auto view_ptr = find_view_as_node();
489 if (view_ptr) {
490 view_ptr->set_eye_keep_view_angle(dvec3(0, 4, -4));
491 // if the view points to a vr_view_interactor
492 vr_view_ptr = dynamic_cast<vr_view_interactor*>(view_ptr);
493 if (vr_view_ptr) {
494 // configure vr event processing
495 vr_view_ptr->set_event_type_flags(
505 ));
506 vr_view_ptr->enable_vr_event_debugging(false);
507 // configure vr rendering
508 vr_view_ptr->draw_action_zone(false);
509 vr_view_ptr->draw_vr_kits(true);
510 vr_view_ptr->enable_blit_vr_views(true);
511 vr_view_ptr->set_blit_vr_view_width(200);
512 }
513 }
514
518 return true;
519}
520
527
529{
530 if (!seethrough.is_linked()) {
531 if (!seethrough.build_program(ctx, "seethrough.glpr"))
532 cgv::gui::message("could not build seethrough program");
533 }
534 if (label_fbo.get_width() != label_resolution) {
535 label_tex.destruct(ctx);
536 label_fbo.destruct(ctx);
537 }
538 if (!label_fbo.is_created()) {
539 label_tex.create(ctx, cgv::render::TT_2D, label_resolution, label_resolution);
540 label_fbo.create(ctx, label_resolution, label_resolution);
541 label_tex.set_min_filter(cgv::render::TF_LINEAR_MIPMAP_LINEAR);
542 label_tex.set_mag_filter(cgv::render::TF_LINEAR);
543 label_fbo.attach(ctx, label_tex);
544 label_outofdate = true;
545 }
546 if (label_outofdate && label_fbo.is_complete(ctx)) {
547 glPushAttrib(GL_COLOR_BUFFER_BIT);
548 label_fbo.enable(ctx);
549 label_fbo.push_viewport(ctx);
550 ctx.push_pixel_coords();
551 glClearColor(0.5f,0.5f,0.5f,1.0f);
552 glClear(GL_COLOR_BUFFER_BIT);
553
554 glColor4f(label_color[0], label_color[1], label_color[2], 1);
555 ctx.set_cursor(20, (int)ceil(label_size) + 20);
556 ctx.enable_font_face(label_font_face, label_size);
557 ctx.output_stream() << label_text << "\n";
558 ctx.output_stream().flush(); // make sure to flush the stream before change of font size or font face
559
560 ctx.enable_font_face(label_font_face, 0.7f*label_size);
561 for (size_t i = 0; i < intersection_points.size(); ++i) {
562 ctx.output_stream()
563 << "box " << intersection_box_indices[i]
564 << " at (" << intersection_points[i]
565 << ") with controller " << intersection_controller_indices[i] << "\n";
566 }
567 ctx.output_stream().flush();
568
569 ctx.pop_pixel_coords();
570 label_fbo.pop_viewport(ctx);
571 label_fbo.disable(ctx);
572 glPopAttrib();
573 label_outofdate = false;
574
575 label_tex.generate_mipmaps(ctx);
576 }
577 if (vr_view_ptr && vr_view_ptr->get_rendered_vr_kit() != 0 && vr_view_ptr->get_rendered_eye() == 0 && vr_view_ptr->get_rendered_vr_kit() == vr_view_ptr->get_current_vr_kit()) {
578 vr::vr_kit* kit_ptr = vr_view_ptr->get_current_vr_kit();
579 if (kit_ptr) {
580 vr::vr_camera* camera_ptr = kit_ptr->get_camera();
581 if (camera_ptr && camera_ptr->get_state() == vr::CS_STARTED) {
582 uint32_t width = frame_width, height = frame_height, split = frame_split;
583 if (shared_texture) {
584 cgv::box2 tex_range;
585 if (camera_ptr->get_gl_texture_id(camera_tex_id, width, height, undistorted, &tex_range.ref_min_pnt()(0))) {
586 camera_aspect = (float)width / height;
587 split = camera_ptr->get_frame_split();
588 switch (split) {
589 case vr::CFS_VERTICAL:
590 camera_aspect *= 2;
591 break;
592 case vr::CFS_HORIZONTAL:
593 camera_aspect *= 0.5f;
594 break;
595 }
596 }
597 else
598 camera_tex_id = -1;
599 }
600 else {
601 std::vector<uint8_t> frame_data;
602 if (camera_ptr->get_frame(frame_data, width, height, undistorted, max_rectangle)) {
603 camera_aspect = (float)width / height;
604 split = camera_ptr->get_frame_split();
605 switch (split) {
606 case vr::CFS_VERTICAL:
607 camera_aspect *= 2;
608 break;
609 case vr::CFS_HORIZONTAL:
610 camera_aspect *= 0.5f;
611 break;
612 }
614 cgv::data::data_view dv(&df, frame_data.data());
615 if (camera_tex.is_created()) {
616 if (camera_tex.get_width() != width || camera_tex.get_height() != height)
617 camera_tex.destruct(ctx);
618 else
619 camera_tex.replace(ctx, 0, 0, dv);
620 }
621 if (!camera_tex.is_created())
622 camera_tex.create(ctx, dv);
623 }
624 else if (camera_ptr->has_error())
625 cgv::gui::message(camera_ptr->get_last_error());
626 }
627 if (frame_width != width || frame_height != height) {
628 frame_width = width;
629 frame_height = height;
630
631 center_left(0) = camera_centers[2](0) / frame_width;
632 center_left(1) = camera_centers[2](1) / frame_height;
633 center_right(0) = camera_centers[3](0) / frame_width;
634 center_right(1) = camera_centers[3](1) / frame_height;
635
636 update_member(&frame_width);
637 update_member(&frame_height);
638 update_member(&center_left(0));
639 update_member(&center_left(1));
640 update_member(&center_right(0));
641 update_member(&center_right(1));
642 }
643 if (split != frame_split) {
644 frame_split = split;
645 update_member(&frame_split);
646 }
647 }
648 }
649 }
650}
651
653{
654 if (MI.is_constructed()) {
655 cgv::dmat4 R;
656 mesh_orientation.put_homogeneous_matrix(R);
659 cgv::math::translate4<double>(mesh_location)*
660 cgv::math::scale4<double>(mesh_scale, mesh_scale, mesh_scale) *
661 R);
662 MI.draw_all(ctx);
664 }
665 if (vr_view_ptr) {
666 if ((!shared_texture && camera_tex.is_created()) || (shared_texture && camera_tex_id != -1)) {
667 if (vr_view_ptr->get_rendered_vr_kit() != 0 && vr_view_ptr->get_rendered_vr_kit() == vr_view_ptr->get_current_vr_kit()) {
668 int eye = vr_view_ptr->get_rendered_eye();
669
670 // compute billboard
671 dvec3 vd = vr_view_ptr->get_view_dir_of_kit();
672 dvec3 y = vr_view_ptr->get_view_up_dir_of_kit();
673 dvec3 x = normalize(cross(vd, y));
674 y = normalize(cross(x, vd));
675 x *= camera_aspect * background_extent * background_distance;
676 y *= background_extent * background_distance;
677 vd *= background_distance;
678 dvec3 eye_pos = vr_view_ptr->get_eye_of_kit(eye);
679 std::vector<vec3> P;
680 std::vector<vec2> T;
681 P.push_back(eye_pos + vd - x - y);
682 P.push_back(eye_pos + vd + x - y);
683 P.push_back(eye_pos + vd - x + y);
684 P.push_back(eye_pos + vd + x + y);
685 double v_offset = 0.5 * (1 - eye);
686 T.push_back(dvec2(0.0, 0.5 + v_offset));
687 T.push_back(dvec2(1.0, 0.5 + v_offset));
688 T.push_back(dvec2(0.0, v_offset));
689 T.push_back(dvec2(1.0, v_offset));
690
691 cgv::render::shader_program& prog = seethrough;
694 cgv::render::attribute_array_binding::enable_global_array(ctx, prog.get_position_index());
695 cgv::render::attribute_array_binding::enable_global_array(ctx, prog.get_texcoord_index());
696
697 GLint active_texture, texture_binding;
698 if (shared_texture) {
699 glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
700 glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture_binding);
701 glActiveTexture(GL_TEXTURE0);
702 glBindTexture(GL_TEXTURE_2D, camera_tex_id);
703 }
704 else
705 camera_tex.enable(ctx, 0);
706 prog.set_uniform(ctx, "texture", 0);
707 prog.set_uniform(ctx, "seethrough_gamma", seethrough_gamma);
708 prog.set_uniform(ctx, "use_matrix", use_matrix);
709
710 // use of convenience function
711 vr::configure_seethrough_shader_program(ctx, prog, frame_width, frame_height,
712 vr_view_ptr->get_current_vr_kit(), *vr_view_ptr->get_current_vr_state(),
713 0.01f, 2 * background_distance, eye, undistorted);
714
715 /* equivalent detailed code relies on more knowledge on program parameters
716 mat4 TM = vr::get_texture_transform(vr_view_ptr->get_current_vr_kit(), *vr_view_ptr->get_current_vr_state(), 0.01f, 2 * background_distance, eye, undistorted);
717 prog.set_uniform(ctx, "texture_matrix", TM);
718
719 prog.set_uniform(ctx, "extent_texcrd", extent_texcrd);
720 prog.set_uniform(ctx, "frame_split", frame_split);
721 prog.set_uniform(ctx, "center_left", center_left);
722 prog.set_uniform(ctx, "center_right", center_right);
723 prog.set_uniform(ctx, "eye", eye);
724 */
725 prog.enable(ctx);
726 ctx.set_color(rgba(1, 1, 1, 1));
727
728 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
729
730
731 prog.disable(ctx);
732
733 if (shared_texture) {
734 glActiveTexture(active_texture);
735 glBindTexture(GL_TEXTURE_2D, texture_binding);
736 }
737 else
738 camera_tex.disable(ctx);
739
742 }
743 }
744 if (vr_view_ptr) {
745 std::vector<vec3> P;
746 std::vector<float> R;
747 std::vector<rgb> C;
748 const vr::vr_kit_state* state_ptr = vr_view_ptr->get_current_vr_state();
749 if (state_ptr) {
750 for (int ci = 0; ci < 2; ++ci)
751 if (state_ptr->controller[ci].status == vr::VRS_TRACKED) {
752 vec3 ray_origin, ray_direction;
753 state_ptr->controller[ci].put_ray(&ray_origin(0), &ray_direction(0));
754 P.push_back(ray_origin);
755 R.push_back(0.002f);
756 P.push_back(ray_origin + ray_length * ray_direction);
757 R.push_back(0.003f);
758 rgb c(float(1 - ci), 0.5f * (int)state[ci], float(ci));
759 C.push_back(c);
760 C.push_back(c);
761 }
762 }
763 if (P.size() > 0) {
764 auto& cr = cgv::render::ref_cone_renderer(ctx);
765 cr.set_render_style(cone_style);
766 //cr.set_eye_position(vr_view_ptr->get_eye_of_kit());
767 cr.set_position_array(ctx, P);
768 cr.set_color_array(ctx, C);
769 cr.set_radius_array(ctx, R);
770 if (!cr.render(ctx, 0, P.size())) {
772 int pi = prog.get_position_index();
773 int ci = prog.get_color_index();
778 glLineWidth(3);
779 prog.enable(ctx);
780 glDrawArrays(GL_LINES, 0, (GLsizei)P.size());
781 prog.disable(ctx);
784 glLineWidth(1);
785 }
786 }
787 }
788 }
790 // draw wireframe boxes
791 //TODO draw wireframe boxes
792 if (!frame_boxes.empty()) {
793 renderer.set_render_style(wire_frame_style);
794 renderer.set_box_array(ctx, frame_boxes);
795 renderer.set_color_array(ctx, frame_box_colors);
796 renderer.set_translation_array(ctx, frame_box_translations);
797 renderer.set_rotation_array(ctx, frame_box_rotations);
798 if (renderer.validate_and_enable(ctx)) {
799 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
800 renderer.draw(ctx, 0, frame_boxes.size());
801 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
802 }
803 renderer.disable(ctx);
804 }
805
806 // draw dynamic boxes
807 if (!movable_boxes.empty()) {
808 renderer.set_render_style(movable_style);
809 renderer.set_box_array(ctx, movable_boxes);
810 renderer.set_color_array(ctx, movable_box_colors);
811 renderer.set_translation_array(ctx, movable_box_translations);
812 renderer.set_rotation_array(ctx, movable_box_rotations);
813 if (renderer.validate_and_enable(ctx)) {
814 if (show_seethrough) {
815 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
816 renderer.draw(ctx, 0, 3);
817 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
818 renderer.draw(ctx, 3, movable_boxes.size() - 3);
819 }
820 else
821 renderer.draw(ctx, 0, movable_boxes.size());
822 }
823 renderer.disable(ctx);
824 }
825 // draw static boxes
826 if (!boxes.empty()) {
827 renderer.set_render_style(style);
828 renderer.set_box_array(ctx, boxes);
829 renderer.set_color_array(ctx, box_colors);
830 renderer.render(ctx, 0, boxes.size());
831 }
832 // draw intersection points
833 if (!intersection_points.empty()) {
834 auto& sr = cgv::render::ref_sphere_renderer(ctx);
835 sr.set_position_array(ctx, intersection_points);
836 sr.set_color_array(ctx, intersection_colors);
837 sr.set_render_style(srs);
838 sr.render(ctx, 0, intersection_points.size());
839 }
840
841 // draw label
842 if (vr_view_ptr && label_tex.is_created()) {
844 int pi = prog.get_position_index();
845 int ti = prog.get_texcoord_index();
846 vec3 p(0, 1.5f, 0);
847 vec3 y = label_upright ? cgv::math::fvec<double, 3>(0, 1.0, 0) : normalize(vr_view_ptr->get_view_up_dir_of_kit());
848 vec3 x = normalize(cross(vec3(vr_view_ptr->get_view_dir_of_kit()), y));
849 float w = 0.5f, h = 0.5f;
850 std::vector<vec3> P;
851 std::vector<vec2> T;
852 P.push_back(p - 0.5f * w * x - 0.5f * h * y); T.push_back(vec2(0.0f, 0.0f));
853 P.push_back(p + 0.5f * w * x - 0.5f * h * y); T.push_back(vec2(1.0f, 0.0f));
854 P.push_back(p - 0.5f * w * x + 0.5f * h * y); T.push_back(vec2(0.0f, 1.0f));
855 P.push_back(p + 0.5f * w * x + 0.5f * h * y); T.push_back(vec2(1.0f, 1.0f));
860 prog.enable(ctx);
861 label_tex.enable(ctx);
862 ctx.set_color(rgb(1, 1, 1));
863 glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)P.size());
864 label_tex.disable(ctx);
865 prog.disable(ctx);
868 }
869}
870
872{
873 return;
874 if ((!shared_texture && camera_tex.is_created()) || (shared_texture && camera_tex_id != -1)) {
876 glEnable(GL_BLEND);
877 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
878 GLint active_texture, texture_binding;
879 if (shared_texture) {
880 glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
881 glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture_binding);
882 glActiveTexture(GL_TEXTURE0);
883 glBindTexture(GL_TEXTURE_2D, camera_tex_id);
884 }
885 else
886 camera_tex.enable(ctx, 0);
887
888 prog.set_uniform(ctx, "texture", 0);
890 ctx.mul_modelview_matrix(cgv::math::translate4<double>(0, 3, 0));
891 prog.enable(ctx);
892 ctx.set_color(rgba(1, 1, 1, 0.8f));
894 prog.disable(ctx);
895 if (shared_texture) {
896 glActiveTexture(active_texture);
897 glBindTexture(GL_TEXTURE_2D, texture_binding);
898 }
899 else
900 camera_tex.disable(ctx);
902 glDisable(GL_BLEND);
903 }
904}
905
906 //0.2f*distribution(generator)+0.1f));
908 add_decorator("vr_test", "heading", "level=2");
909 add_member_control(this, "mesh_scale", mesh_scale, "value_slider", "min=0.1;max=10;log=true;ticks=true");
910 add_gui("mesh_location", mesh_location, "vector", "options='min=-3;max=3;ticks=true");
911 add_gui("mesh_orientation", static_cast<cgv::dvec4&>(mesh_orientation), "direction", "options='min=-1;max=1;ticks=true");
912 add_member_control(this, "ray_length", ray_length, "value_slider", "min=0.1;max=10;log=true;ticks=true");
913 add_member_control(this, "show_seethrough", show_seethrough, "check");
914 if(last_kit_handle) {
915 add_decorator("cameras", "heading", "level=3");
916 add_view("nr", nr_cameras);
917 if(nr_cameras > 0) {
918 connect_copy(add_button("start")->click, cgv::signal::rebind(this, &vr_test::start_camera));
919 connect_copy(add_button("stop")->click, cgv::signal::rebind(this, &vr_test::stop_camera));
920 add_view("frame_width", frame_width, "", "w=20", " ");
921 add_view("height", frame_height, "", "w=20", " ");
922 add_view("split", frame_split, "", "w=50");
923 add_member_control(this, "undistorted", undistorted, "check");
924 add_member_control(this, "shared_texture", shared_texture, "check");
925 add_member_control(this, "max_rectangle", max_rectangle, "check");
926 add_member_control(this, "use_matrix", use_matrix, "check");
927 add_member_control(this, "gamma", seethrough_gamma, "value_slider", "min=0.1;max=10;log=true;ticks=true");
928 add_member_control(this, "extent_x", extent_texcrd[0], "value_slider", "min=0.2;max=2;ticks=true");
929 add_member_control(this, "extent_y", extent_texcrd[1], "value_slider", "min=0.2;max=2;ticks=true");
930 add_member_control(this, "center_left_x", center_left[0], "value_slider", "min=0.2;max=0.8;ticks=true");
931 add_member_control(this, "center_left_y", center_left[1], "value_slider", "min=0.2;max=0.8;ticks=true");
932 add_member_control(this, "center_right_x", center_right[0], "value_slider", "min=0.2;max=0.8;ticks=true");
933 add_member_control(this, "center_right_y", center_right[1], "value_slider", "min=0.2;max=0.8;ticks=true");
934 add_member_control(this, "background_distance", background_distance, "value_slider", "min=0.1;max=10;log=true;ticks=true");
935 add_member_control(this, "background_extent", background_extent, "value_slider", "min=0.01;max=10;log=true;ticks=true");
936 }
937 vr::vr_kit* kit_ptr = vr::get_vr_kit(last_kit_handle);
938 if (kit_ptr) {
939 add_decorator("controller input configs", "heading", "level=3");
940 int ti = 0, si = 0, pi = 0;
941 const auto& CI = kit_ptr->get_device_info().controller[0];
942 for (int ii = 0; ii < (int)left_inp_cfg.size(); ++ii) {
943 std::string prefix;
944 switch (CI.input_type[ii]) {
945 case vr::VRI_TRIGGER: prefix = std::string("trigger[") + cgv::utils::to_string(ti++) + "]"; break;
946 case vr::VRI_PAD: prefix = std::string("pad[") + cgv::utils::to_string(pi++) + "]"; break;
947 case vr::VRI_STICK: prefix = std::string("strick[") + cgv::utils::to_string(si++) + "]"; break;
948 default: prefix = std::string("unknown[") + cgv::utils::to_string(ii) + "]";
949 }
950 add_member_control(this, prefix + ".dead_zone", left_inp_cfg[ii].dead_zone, "value_slider", "min=0;max=1;ticks=true;log=true");
951 add_member_control(this, prefix + ".precision", left_inp_cfg[ii].precision, "value_slider", "min=0;max=1;ticks=true;log=true");
952 add_member_control(this, prefix + ".threshold", left_inp_cfg[ii].threshold, "value_slider", "min=0;max=1;ticks=true");
953 }
954 }
955 }
956 if (begin_tree_node("movable boxes", 1.f)) {
957 align("\a");
958 connect_copy(add_button("save boxes")->click, rebind(this, &vr_test::on_save_movable_boxes_cb));
959 connect_copy(add_button("load boxes")->click, rebind(this, &vr_test::on_load_movable_boxes_cb));
960 connect_copy(add_button("load target")->click, rebind(this, &vr_test::on_load_wireframe_boxes_cb));
961 align("\b");
962 }
963 if (begin_tree_node("box style", style)) {
964 align("\a");
965 add_gui("box style", style);
966 align("\b");
967 end_tree_node(style);
968 }
969 if (begin_tree_node("cone style", cone_style)) {
970 align("\a");
971 add_gui("cone style", cone_style);
972 align("\b");
973 end_tree_node(cone_style);
974 }
975 if(begin_tree_node("movable box style", movable_style)) {
976 align("\a");
977 add_gui("movable box style", movable_style);
978 align("\b");
979 end_tree_node(movable_style);
980 }
981 if(begin_tree_node("intersections", srs)) {
982 align("\a");
983 add_gui("sphere style", srs);
984 align("\b");
985 end_tree_node(srs);
986 }
987 if(begin_tree_node("mesh", mesh_scale)) {
988 align("\a");
989 add_member_control(this, "scale", mesh_scale, "value_slider", "min=0.0001;step=0.0000001;max=100;log=true;ticks=true");
990 add_gui("location", mesh_location, "", "main_label='';long_label=true;gui_type='value_slider';options='min=-2;max=2;step=0.001;ticks=true'");
991 add_gui("orientation", static_cast<cgv::dvec4&>(mesh_orientation), "direction", "main_label='';long_label=true;gui_type='value_slider';options='min=-1;max=1;step=0.001;ticks=true'");
992 align("\b");
993 end_tree_node(mesh_scale);
994 }
995
996 if(begin_tree_node("label", label_size)) {
997 align("\a");
998 add_member_control(this, "text", label_text);
999 add_member_control(this, "upright", label_upright);
1000 add_member_control(this, "font", (cgv::type::DummyEnum&)label_font_idx, "dropdown", font_enum_decl);
1001 add_member_control(this, "face", (cgv::type::DummyEnum&)label_face_type, "dropdown", "enums='regular,bold,italics,bold+italics'");
1002 add_member_control(this, "size", label_size, "value_slider", "min=8;max=64;ticks=true");
1003 add_member_control(this, "color", label_color);
1004 add_member_control(this, "resolution", (cgv::type::DummyEnum&)label_resolution, "dropdown", "enums='256=256,512=512,1024=1024,2048=2048'");
1005 align("\b");
1006 end_tree_node(label_size);
1007 }
1008}
1009
1010bool vr_test::save_boxes(const std::string fn, const std::vector<box3>& boxes, const std::vector<rgb>& box_colors, const std::vector<vec3>& box_translations, const std::vector<quat>& box_rotations)
1011{
1012 std::stringstream data;
1013
1014
1015 if (boxes.size() != box_colors.size() || boxes.size() != box_translations.size() || boxes.size() != box_rotations.size()) {
1016 std::cerr << "vr_test::save_boxes: passed vectors have different sizes!";
1017 return false;
1018 }
1019
1020 for (int i = 0; i < movable_boxes.size(); ++i) {
1021 //format: BOX <box.min_p> <box.max_p> <trans> <rot> <col>
1022 const vec3& box_translation = box_translations[i];
1023 const quat& box_rotation = box_rotations[i];
1024 const rgb& box_color = box_colors[i];
1025 data << "BOX "
1026 << boxes[i].get_min_pnt() << " "
1027 << boxes[i].get_max_pnt() << " "
1028 << box_translation << " "
1029 << box_rotation << " "
1030 << box_color << " "
1031 << '\n';
1032 }
1033 std::string s = data.str();
1034 if (!cgv::utils::file::write(fn, s.data(), s.size())) {
1035 std::cerr << "vr_test::save_boxes: failed writing data to file: " << fn;
1036 }
1037 return true;
1038}
1039
1040bool vr_test::load_boxes(const std::string fn, std::vector<box3>& boxes, std::vector<rgb>& box_colors, std::vector<vec3>& box_translations, std::vector<quat>& box_rotations)
1041{
1042 std::string data;
1043 if (!cgv::utils::file::read(fn, data)) {
1044 std::cerr << "vr_test::load_boxes: failed reading data from file: " << fn << '\n';
1045 return false;
1046 }
1047 std::istringstream f(data);
1048 std::string line;
1049
1050 while (!f.eof()) {
1051 std::getline(f, line); //read a line
1052 std::istringstream l(line);
1053 std::string sym;
1054
1055 int limit=1;
1056 bool valid = true;
1057 if (!l.eof()) {
1058 getline(l, sym, ' '); //get the first symbol determing the type
1059 if (sym == "BOX") { //in case of a box
1060 vec3 minp,maxp,trans;
1061 quat rot;
1062 rgb col;
1063 l >> minp;
1064 l >> maxp;
1065 l >> trans;
1066 l >> rot;
1067 l >> col;
1068
1069 boxes.emplace_back(minp, maxp);
1070 box_translations.emplace_back(trans);
1071 box_rotations.emplace_back(rot);
1072 box_colors.emplace_back(col);
1073 }
1074 }
1075 }
1076 return true;
1077}
1078
1079void vr_test::on_save_movable_boxes_cb()
1080{
1081 std::string fn = cgv::gui::file_save_dialog("base file name", "Box configurations(txt):*.txt");
1082 if (fn.empty())
1083 return;
1084
1085 save_boxes(fn, movable_boxes, movable_box_colors, movable_box_translations, movable_box_rotations);
1086}
1087
1088void vr_test::on_load_movable_boxes_cb()
1089{
1090 std::string fn = cgv::gui::file_open_dialog("base file name", "Box configurations(txt):*.txt");
1091 if (!cgv::utils::file::exists(fn)) {
1092 std::cerr << "vr_test::on_load_movable_boxes_cb: file does not exist!\n";
1093 return;
1094 }
1095 clear_movable_boxes();
1096 if (!load_boxes(fn, movable_boxes, movable_box_colors, movable_box_translations, movable_box_rotations)) {
1097 std::cerr << "vr_test::on_load_movable_boxes_cb: failed to parse file!\n";
1098 clear_movable_boxes(); //delete all boxes after a failure to reach a valid logical state
1099 }
1100}
1101
1102void vr_test::on_load_wireframe_boxes_cb()
1103{
1104 std::string fn = cgv::gui::file_open_dialog("base file name", "Box configurations(txt):*.txt");
1105 if (!cgv::utils::file::exists(fn)) {
1106 std::cerr << "vr_test::on_load_movable_boxes_cb: file does not exist!\n";
1107 return;
1108 }
1109 clear_frame_boxes();
1110 if (!load_boxes(fn, frame_boxes, frame_box_colors, frame_box_translations, frame_box_rotations)) {
1111 std::cerr << "vr_test::on_load_wireframe_boxes_cb: failed to parse file!\n";
1112 clear_frame_boxes(); //delete all boxes after a failure to reach a valid logical state
1113 }
1114}
1115
1116void vr_test::clear_movable_boxes()
1117{
1118 movable_boxes.clear();
1119 movable_box_translations.clear();
1120 movable_box_rotations.clear();
1121 movable_box_colors.clear();
1122}
1123
1124void vr_test::clear_frame_boxes()
1125{
1126 frame_boxes.clear();
1127 frame_box_translations.clear();
1128 frame_box_rotations.clear();
1129 frame_box_colors.clear();
1130}
1131
1132#include <cgv/base/register.h>
1133
1134cgv::base::object_registration<vr_test> vr_test_reg("vr_test");
1135
1136#ifdef CGV_FORCE_STATIC
1137cgv::base::registration_order_definition ro_def("vr_view_interactor;vr_emulator;vr_wall;vr_scene;vr_test");
1138#endif
void set_name(const std::string &_name)
set a new parent node
Definition named.cxx:13
complete implementation of method actions that only call one method when entering a node
Definition action.h:113
A data_format describes a multidimensional data block of data entries.
Definition data_format.h:17
size_t get_width() const
return the resolution in the first dimension, or 1 if not defined
size_t get_height() const
return the resolution in the second dimension, or 1 if not defined
the data view gives access to a data array of one, two, three or four dimensions.
Definition data_view.h:153
unsigned get_kind() const
return, what kind of event this is, typically a value from the EventId enum
Definition event.cxx:202
unsigned get_flags() const
return the event flags
Definition event.cxx:214
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 vec3 & get_last_position() const
return last position
const vec3 & get_position() const
return current position
mat3 get_rotation_matrix() const
return rotation matrix between from the last to current orientation
int get_trackable_index() const
return trackable index
bool add_gui(const std::string &label, T &value, const std::string &gui_type="", const std::string &options="")
Add a composed gui of the given gui_type for the given value.
Definition provider.h:247
cgv::base::base_ptr add_decorator(const std::string &label, const std::string &decorator_type, const std::string &options="", const std::string &align="\n")
add a newly created decorator to the group
Definition provider.cxx:168
void align(const std::string &_align)
send pure alignment information
Definition provider.cxx:36
bool begin_tree_node(const std::string &label, const T &value, bool initial_visibility=false, const std::string &options="", gui_group_ptr ggp=gui_group_ptr())
Begin a sub tree of a tree structured gui.
Definition provider.h:212
virtual void update_member(void *member_ptr)
call this to update all views and controls of a member
Definition provider.cxx:72
data::ref_ptr< control< T > > add_member_control(cgv::base::base *base_ptr, const std::string &label, T &value, const std::string &gui_type="", const std::string &options="", const std::string &align="\n")
add control with callback to cgv::base::on_set method on cgv::gui::control::value_change
Definition provider.h:137
void end_tree_node(const T &value)
template specialization that allows to specify value reference plus node_instance by using the result...
Definition provider.h:222
virtual void post_recreate_gui()
delayed recreation of gui
Definition provider.cxx:509
data::ref_ptr< view< T > > add_view(const std::string &label, const T &value, const std::string &gui_type="", const std::string &options="", const std::string &align="\n")
use this to add a new view to the gui with a given value type, gui type and init options
Definition provider.h:112
button_ptr add_button(const std::string &label, const std::string &options="", const std::string &align="\n")
use the current gui driver to append a new button with the given label
Definition provider.cxx:176
unsigned get_stick_index() const
return stick index
float get_last_x() const
return the last x value of the stick
float get_y() const
return the current y value of the stick
float get_last_y() const
return the last y value of the stick
unsigned get_controller_index() const
return controller index
StickAction get_action() const
return the stick action
float get_x() const
return the current x value of the stick
float get_last_value() const
return the last value of the throttle
float get_value() const
return the current value of the throttle
unsigned get_controller_index() const
return controller index
unsigned get_throttle_index() const
return throttle index
const vr::vr_kit_state & get_state() const
return the state of vr kit
Definition vr_events.h:36
vr key events use the key codes defined in vr::VRKeys
Definition vr_events.h:40
unsigned get_controller_index() const
return controller index (0 .. vr::max_nr_controllers-1), controllers with left and right hand role ar...
Definition vr_events.h:54
vr extension of pose events
Definition vr_events.h:92
vr extension of stick event
Definition vr_events.h:78
vr extension of throttle event
Definition vr_events.h:65
void put_homogeneous_matrix(hmat_type &M) const
compute equivalent homogeneous 4x4 rotation matrix
Definition quaternion.h:154
fpnt_type & ref_min_pnt()
return a reference to corner 0
the simple_mesh class is templated over the coordinate type that defaults to float
bool read(const std::string &file_name)
read simple mesh from file (currently only obj and stl are supported)
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
renderer that supports point splatting
bool disable(context &ctx)
disable renderer
void set_translation_array(const context &ctx, const std::vector< T > &translations)
template method to set the translations from a vector of vectors of type T, which should have 3 compo...
void set_rotation_array(const context &ctx, const std::vector< T > &rotations)
template method to set the rotation from a vector of quaternions of type T, which should have 4 compo...
void draw(context &ctx, size_t start, size_t count, bool use_strips=false, bool use_adjacency=false, uint32_t strip_restart_index=-1)
Draw a range of vertices or indexed elements.
void set_box_array(const context &ctx, const std::vector< cgv::media::axis_aligned_box< T, 3 > > &boxes)
specify box array directly. This sets position_is_center to false as well as position and extent arra...
base class for all drawables, which is independent of the used rendering API.
Definition context.h:621
virtual std::ostream & output_stream()
returns an output stream whose output is printed at the current cursor location, which is managed by ...
Definition context.cxx:901
virtual void mul_modelview_matrix(const dmat4 &MV)
multiply given matrix from right to current modelview matrix
Definition context.cxx:1808
virtual void set_color(const rgba &clr)
set the current color
Definition context.cxx:1617
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 void enable_font_face(media::font::font_face_ptr font_face, float font_size)
enable the given font face with the given size in pixels
Definition context.cxx:906
virtual void push_pixel_coords()=0
use this to push new modelview and new projection matrices onto the transformation stacks such that x...
virtual void set_cursor(int x, int y)
flush the output_stream and set a new cursor position given in opengl coordinates with (0,...
Definition context.cxx:1959
void set_gamma(float _gamma)
set the current per channel gamma values to single value
Definition context.cxx:1575
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 pop_pixel_coords()=0
pop previously pushed transformation matrices from modelview and projection stacks
void tesselate_unit_square(bool flip_normals=false, bool edges=false)
tesselate a unit square in the xy-plane with texture coordinates
Definition context.cxx:1423
virtual shader_program & ref_surface_shader_program(bool texture_support=false)=0
return a reference to the default shader program used to render surfaces
view * find_view_as_node(size_t view_idx=0) const
convenience function to find the view control in the current hierarchy
Definition drawable.cxx:49
void post_redraw()
posts a redraw event to the current context if one is available
Definition drawable.cxx:43
bool create(const context &ctx, int _width=-1, int _height=-1)
create framebuffer if extension is supported, otherwise return false.
void push_viewport(context &ctx, const dvec2 &depth_range=dvec2(0, 1))
push a new window transformation to cover the fbo onto the window transformation stack
bool is_complete(const context &ctx) const
check for completeness, if not complete, get the reason in last_error
int get_width() const
return the width
void pop_viewport(context &ctx)
recover the window transformation array active before the last call to push_viewport
void destruct(const context &ctx)
destruct the framebuffer objext
bool attach(const context &ctx, const render_buffer &rb, int i=0)
attach render buffer to depth buffer if it is a depth buffer, to stencil if it is a stencil buffer or...
bool enable(context &ctx, int i0=-1, int i1=-1, int i2=-1, int i3=-1, int i4=-1, int i5=-1, int i6=-1, int i7=-1, int i8=-1, int i9=-1, int i10=-1, int i11=-1, int i12=-1, int i13=-1, int i14=-1, int i15=-1)
enable the framebuffer either with all color attachments if no arguments are given or if arguments ar...
bool disable(context &ctx)
disable the framebuffer object
bool bind(context &ctx, shader_program &prog, bool force_success, int aa_index=-1)
override to restrict bind function to first aa as second is used for wireframe rendering
void construct(cgv::render::context &ctx, cgv::media::mesh::simple_mesh< T > &mesh, std::vector< idx_type > *tuple_pos_indices=nullptr, std::vector< idx_type > *tuple_normal_indices=nullptr, int *num_floats_in_vertex=nullptr)
Construct mesh render info from a given simple mesh and store all vertex attributes in interleaved in...
bool is_constructed() const
check whether vbos are constructed
virtual bool is_created() const
return whether component has been created
Definition context.cxx:2046
void draw_all(context &ctx, bool skip_opaque=false, bool skip_blended=false, bool use_materials=true)
execute all draw calls
bool validate_and_enable(context &ctx)
validate attributes and if successful, enable renderer
Definition renderer.cxx:196
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
a shader program combines several shader code fragments to a complete definition of the shading pipel...
bool enable(context &ctx)
enable the shader program
bool disable(context &ctx)
disable shader program and restore fixed functionality
bool set_uniform(const context &ctx, const std::string &name, const T &value, bool generate_error=false)
Set the value of a uniform by name, where the type can be any of int, unsigned, float,...
bool is_linked() const
return whether program is linked
bool build_program(const context &ctx, const std::string &file_name, bool show_error=false, const shader_define_map &defines=shader_define_map())
successively calls create, attach_program and link.
bool generate_mipmaps(const context &ctx)
generate mipmaps automatically, only supported if framebuffer objects are supported by the GPU
Definition texture.cxx:518
void set_mag_filter(TextureFilter _mag_filter)
set the magnification filter
Definition texture.cxx:138
bool create(const context &ctx, TextureType _tt=TT_UNDEF, unsigned width=-1, unsigned height=-1, unsigned depth=-1)
create the texture of dimension and resolution specified in the data format base class.
Definition texture.cxx:208
bool disable(const context &ctx)
disable texture and restore state from before last enable call
Definition texture.cxx:756
bool enable(const context &ctx, int tex_unit=-1)
enable this texture in the given texture unit, -1 corresponds to the current unit.
Definition texture.cxx:745
bool destruct(const context &ctx)
destruct the texture and free texture memory and handle
Definition texture.cxx:730
bool replace(const context &ctx, int x, const cgv::data::const_data_view &data, int level=-1, const std::vector< cgv::data::data_view > *palettes=0)
replace a block within a 1d texture with the given data.
Definition texture.cxx:621
void set_min_filter(TextureFilter _min_filter, float _anisotropy=2.0f)
set the minification filters, if minification is set to TF_ANISOTROP, the second floating point param...
Definition texture.cxx:120
interface for mono or stereo cameras in VR headsets
Definition vr_camera.h:39
bool start()
start streaming of frames
Definition vr_camera.cxx:31
const std::string & get_last_error() const
return last error, if no error has occured, the function returns an empty string
Definition vr_camera.cxx:13
CameraState get_state() const
return the camera state
Definition vr_camera.cxx:94
virtual bool put_projection_matrix(int camera_index, bool undistorted, float z_near, float z_far, float *projection_matrix) const =0
access to 4x4 matrix in column major format for perspective transformation of camera (0....
bool stop()
stop streaming of frames
Definition vr_camera.cxx:47
virtual bool put_camera_intrinsics(int camera_index, bool undistorted, float *focal_length_2d_ptr, float *center_2d_ptr) const =0
write the focal lengths in x- and y-direction to access to focal_length_2d_ptr[0|1] and the texture c...
bool has_error() const
check for error
Definition vr_camera.h:71
bool get_gl_texture_id(uint32_t &tex_id, uint32_t &width, uint32_t &height, bool undistorted, float max_valid_texcoord_range[4])
query id of shared opengl texture id
Definition vr_camera.cxx:72
CameraFrameSplit get_frame_split() const
query stereo frame layout
Definition vr_camera.cxx:89
virtual bool put_camera_to_head_matrix(int camera_index, float *pose_matrix) const =0
access to 3x4 matrix in column major format for transformation from camera (0 .. left,...
uint8_t get_nr_cameras() const
return number of cameras in the headset (1 for mono and 2 for stereo)
Definition vr_camera.cxx:99
bool get_frame(std::vector< uint8_t > &frame_data, uint32_t &width, uint32_t &height, bool undistorted, bool maximum_valid_rectangle)
check for a new frame, return false if not available. Otherwise copy frame to provided buffer that is...
Definition vr_camera.cxx:60
a vr kit is composed of headset, two controllers, and two trackers, where all devices can be attached...
Definition vr_kit.h:69
vr_camera * get_camera() const
return camera or nullptr if not available
Definition vr_kit.cxx:52
const controller_input_config & get_controller_input_config(int controller_index, int input_index) const
query the configuration of a controller input
Definition vr_kit.cxx:126
const vr_kit_info & get_device_info() const
return information on the currently attached devices
Definition vr_kit.cxx:117
virtual void set_controller_input_config(int controller_index, int input_index, const controller_input_config &cic)
set the configuration of a controller input
Definition vr_kit.cxx:121
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....
void build_scene(float w, float d, float h, float W, float tw, float td, float th, float tW)
construct a scene with a table
Definition vr_test.cxx:250
bool save_boxes(const std::string fn, const std::vector< box3 > &boxes, const std::vector< rgb > &box_colors, const std::vector< vec3 > &box_translations, const std::vector< quat > &box_rotations)
stores configuration of the movable boxes inside a file
Definition vr_test.cxx:1010
void on_set(void *member_ptr)
this callback is called when the set_void method has changed a member and can be overloaded in derive...
Definition vr_test.cxx:307
bool load_boxes(const std::string fn, std::vector< box3 > &boxes, std::vector< rgb > &box_colors, std::vector< vec3 > &box_translations, std::vector< quat > &box_rotations)
loads boxes stored by the save_boxes method from a file
Definition vr_test.cxx:1040
void clear(cgv::render::context &ctx)
clear all objects living in the context like textures or display lists
Definition vr_test.cxx:521
void init_frame(cgv::render::context &ctx)
this method is called in one pass over all drawables before the draw method
Definition vr_test.cxx:528
void construct_movable_boxes(float tw, float td, float th, float tW, size_t nr)
construct boxes that represent a table of dimensions tw,td,th and leg width tW
Definition vr_test.cxx:221
void construct_table(float tw, float td, float th, float tW)
construct boxes that represent a table of dimensions tw,td,th and leg width tW
Definition vr_test.cxx:153
void on_status_change(void *kit_handle, int ci, vr::VRStatus old_status, vr::VRStatus new_status)
keep track of status changes
Definition vr_test.cxx:107
void construct_environment(float s, float ew, float ed, float w, float d, float h)
construct boxes for environment
Definition vr_test.cxx:195
void stream_help(std::ostream &os)
overload to stream help information to the given output stream
Definition vr_test.cxx:303
void construct_room(float w, float d, float h, float W, bool walls, bool ceiling)
construct boxes that represent a room of dimensions w,d,h and wall width W
Definition vr_test.cxx:172
void on_device_change(void *kit_handle, bool attach)
register on device change events
Definition vr_test.cxx:128
void draw(cgv::render::context &ctx)
overload to draw the content of this drawable
Definition vr_test.cxx:652
bool handle(cgv::gui::event &e)
overload and implement this method to handle events
Definition vr_test.cxx:328
void finish_draw(cgv::render::context &ctx)
this method is called when the current drawable is left in a tree traversal that calls the draw metho...
Definition vr_test.cxx:871
void create_gui()
you must overload this for gui creation
Definition vr_test.cxx:907
bool init(cgv::render::context &ctx)
this method is called after creation or recreation of the context, return whether all necessary funct...
Definition vr_test.cxx:457
void compute_intersections(const vec3 &origin, const vec3 &direction, int ci, const rgb &color)
compute intersection points of controller ray with movable boxes
Definition vr_test.cxx:77
extends the stereo view interactor for vr support
int get_rendered_eye() const
return the currently rendered eye
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 draw_vr_kits(bool do_draw)
set whether to draw vr kits
vr::vr_kit * get_current_vr_kit() const
return a pointer to the current vr kit
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
vr::vr_kit * get_rendered_vr_kit() const
return pointer to rendered vr kit or nullptr if birds eye view is rendered
cgv::dvec3 get_eye_of_kit(int eye=0, int vr_kit_idx=-1) const
query the eye position of a vr kit.
void enable_blit_vr_views(bool enable)
enable vr view blitting
void draw_action_zone(bool do_draw)
whether to draw action zone
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
@ CF_RGBA
color format with components R, G and B
std::string get_stick_action_string(StickAction action)
convert a key action into a readable string
std::string file_open_dialog(const std::string &title, const std::string &filter, const std::string &path)
ask the user for a file name to open a file.
void message(const std::string &_message)
tell the user something with a message box
Definition dialog.cxx:14
vr_server & ref_vr_server()
return a reference to gamepad server singleton
@ KA_RELEASE
key release action
Definition key_event.h:13
@ SA_DRAG
stick moved in pressed state
Definition stick_event.h:21
@ SA_RELEASE
stick release action
Definition stick_event.h:19
@ SA_PRESS
stick press action
Definition stick_event.h:17
@ SA_TOUCH
stick touch action
Definition stick_event.h:16
@ SA_UNPRESS
stick unpress repeated press action
Definition stick_event.h:18
@ SA_MOVE
stick moved with respect to last event
Definition stick_event.h:20
@ EID_POSE
id for a 6D pose change events
Definition event.h:21
@ EID_STICK
id of a stick event describing a two axis controller that optionally can be touched and pressed
Definition event.h:20
@ EID_KEY
id for key event
Definition event.h:17
@ EID_THROTTLE
id of throttle event describing a one axis controller
Definition event.h:19
std::string file_save_dialog(const std::string &title, const std::string &filter, const std::string &path)
ask the user for a file name to save a file.
VREventTypeFlags
flags to define which events should be generated by server
Definition vr_server.h:27
@ VRE_POSE
pose events
Definition vr_server.h:36
@ VRE_ONE_AXIS_GENERATES_KEY
whether one axis events should generate a key event when passing inputs threshold value
Definition vr_server.h:34
@ VRE_TWO_AXES
pad / stick events
Definition vr_server.h:33
@ VRE_ONE_AXIS
trigger / throttle / pedal events
Definition vr_server.h:32
@ VRE_KEY
key events
Definition vr_server.h:31
@ VRE_STATUS
status change events
Definition vr_server.h:30
@ VRE_TWO_AXES_GENERATES_DPAD
whether two axes input generates direction pad keys when presses
Definition vr_server.h:35
@ VRE_DEVICE
device change events
Definition vr_server.h:29
void connect_vr_server(bool connect_device_change_only_to_animation_trigger, cgv::gui::window_ptr w)
connect the gamepad server to the given window or the first window of the application,...
@ EF_VR
whether event is from VR kit
Definition event.h:35
font_ptr find_font(const std::string &font_name)
find an installed font by name
Definition font.cxx:32
void enumerate_font_names(std::vector< const char * > &font_names)
enumerate the names of all installed fonts
Definition font.cxx:65
cone_renderer & ref_cone_renderer(context &ctx, int ref_count_change)
reference to a singleton cone renderer that is shared among drawables
box_renderer & ref_box_renderer(context &ctx, int ref_count_change)
reference to a singleton box renderer that is shared among drawables
sphere_renderer & ref_sphere_renderer(context &ctx, int ref_count_change)
reference to a singleton sphere renderer that can be shared among drawables
@ TI_UINT8
signed integer stored in 64 bits
Definition type_id.h:23
DummyEnum
some enum to mark an integral parameter to be of enum type
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
char to_lower(char c)
convert char to lower case
Definition scan.cxx:39
bool has_option(const std::string &option)
check whether the system variable CGV_OPTIONS contains the given option (the comparison is case insen...
Definition options.cxx:8
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 configure_seethrough_shader_program(cgv::render::context &ctx, cgv::render::shader_program &prog, uint32_t frame_width, uint32_t frame_height, const vr_kit *vr_kit_ptr, const vr_kit_state &state, float z_near, float z_far, int eye, bool undistorted)
set all uniforms of seethrough shader program for a given camera (0 ... left or mono,...
cgv::mat4 get_mat4_from_pose(const float pose_matrix[12])
convert pose to mat4
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
@ VR_DPAD_RIGHT
direction pad right
Definition vr_state.h:41
@ VR_GRIP
grip button
Definition vr_state.h:36
Helper functions to access cgv options provided in the CGV_OPTIONS environment variable.
Helper functions to process strings.
helper class whose constructor calls the define_registration_order() function
Definition register.h:48
float radius
default value assigned to radius attribute in enable method of sphere renderer, set to 1 in construct...
int32_t nr_inputs
number of used inputs
Definition vr_info.h:126
void put_ray(float *ray_origin, float *ray_direction) const
place the 3d ray origin and the 3d ray direction into the given arrays which must provide space for 3...
Definition vr_state.cxx:21
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
VRStatus status
whether trackable is currently tracked, only in case of true, the pose member contains useful informa...
Definition vr_state.h:96
example plugin for vr usage