cgv
Loading...
Searching...
No Matches
navigator.cxx
1#include "navigator.h"
2
3#include <cgv/gui/animate.h>
4#include <cgv/gui/key_event.h>
5#include <cgv/gui/mouse_event.h>
6#include <cgv/math/ftransform.h>
7#include <cgv_gl/gl/gl.h>
8
9using namespace cgv::render;
10
11namespace cgv {
12namespace app {
13
14navigator::navigator() {
15
16 set_name("Navigator");
18
19 view_ptr = nullptr;
20 navigator_eye_pos = vec3(0.0f, 0.0f, 2.5f);
21
22 check_for_click = -1;
23
24 layout_size = 150;
25
26 set_alignment(AO_END, AO_END);
27 set_stretch(SO_NONE);
28 set_margin(ivec2(0));
29 overlay::set_size(ivec2(layout_size));
30
31 show_box = true;
32 show_wireframe = true;
33 use_perspective = true;
34 hit_axis = 0;
35
36 box_data.style.default_extent = vec3(1.0f);
37 box_data.style.map_color_to_material = CM_COLOR_AND_OPACITY;
38 box_data.style.surface_color = rgb(0.5f);
39
40 box_data.style.illumination_mode = IM_TWO_SIDED;
41 box_data.style.culling_mode = CM_OFF;
42 box_data.style.material.set_diffuse_reflectance(rgb(0.5f));
43 box_data.style.material.set_emission(rgb(0.05f));
44 box_data.style.surface_opacity = 0.35f;
45
46 box_wire_data.style.default_color = rgb(0.5f);
47
48 sphere_data.style.illumination_mode = IM_OFF;
49 sphere_data.style.radius = 0.04f;
50 sphere_data.style.surface_color = rgb(0.5f);
51
52 arrow_data.style.illumination_mode = IM_OFF;
53 arrow_data.style.radius_relative_to_length = 0.04f;
54 arrow_data.style.head_length_mode = AHLM_RELATIVE_TO_LENGTH;
55 arrow_data.style.head_length_relative_to_length = 0.3f;
56 arrow_data.style.head_radius_scale = 2.5f;
57
58 rectangle_data.style.illumination_mode = IM_OFF;
59 rectangle_data.style.map_color_to_material = CM_COLOR_AND_OPACITY;
60 rectangle_data.style.surface_color = rgb(0.05f, 0.25f, 1.0f);
61 rectangle_data.style.surface_opacity = 0.75f;
62 rectangle_data.style.pixel_blend = 0.0f;
63 rectangle_data.style.percentual_border_width = 0.111111f;
64 rectangle_data.style.default_border_color = rgba(0.05f, 0.15f, 0.8f, 0.75f);
65}
66
68
69 blit_canvas.destruct(ctx);
70 fbc.destruct(ctx);
71
72 arrow_data.destruct(ctx);
73 box_data.destruct(ctx);
74 box_wire_data.destruct(ctx);
75 rectangle_data.destruct(ctx);
76 sphere_data.destruct(ctx);
77
79}
80
82 return _rh.reflect_member("layout_size", layout_size);
83}
84
86
87 int last_hit_axis = hit_axis;
88 hit_axis = 0;
89
90 if(get_context()) {
91 context& ctx = *get_context();
92
94 hit_axis = 0;
95 } else {
96 vec2 window_coord = vec2(local_mouse_pos) * vec2(2.0f) / get_rectangle().size - vec2(1.0f);
97 vec3 origin = vec3(window_coord, navigator_eye_pos.z());
98 vec3 direction = vec3(0.0f, 0.0f, -1.0f);
99
100 if(use_perspective) {
101 mat4 MVP = get_projection_matrix() * get_view_matrix(ctx);
102
103 vec4 world_coord(window_coord.x(), window_coord.y(), 1.0f, 1.0f);
104 world_coord = inv(MVP) * world_coord;
105 world_coord /= world_coord.w();
106
107 vec3 origin = navigator_eye_pos;
108 vec3 direction = normalize(vec3(world_coord) - origin);
109 }
110
111 mat4 IM = inv(get_model_matrix(ctx));
112
113 origin = vec3(IM * vec4(origin, 1.0f));
114 direction = vec3(IM * vec4(direction, 0.0f));
115
116 float t = std::numeric_limits<float>::max();
117 if(intersect_box(origin, direction, t)) {
118 vec3 hit_pos = origin + t * direction;
119
120 unsigned mi = cgv::math::max_index(cgv::math::abs(hit_pos));
121
122 hit_axis = static_cast<int>(mi) + 1;
123 if(hit_pos[mi] < 0.0f)
124 hit_axis = -hit_axis;
125 }
126 }
127
128 if(last_hit_axis != hit_axis)
129 post_redraw();
130 }
131
132 switch(e.get_action()) {
135 check_for_click = e.get_time();
136 return true;
137 }
138 break;
140 if(check_for_click != -1) {
141 double dt = e.get_time() - check_for_click;
142 if(dt < 0.2) {
143 if(hit_axis != 0) {
144 int axis_idx = abs(hit_axis) - 1;
145
146 vec3 view_dir(0.0f);
147 view_dir[axis_idx] = hit_axis < 0.0f ? -1.0f : 1.0f;
148
149 if(view_ptr) {
150 vec3 focus = view_ptr->get_focus();
151 float dist = (focus - view_ptr->get_eye()).length();
152
153 vec3 view_up_dir(0.0f, 1.0f, 0.0f);
154 if(axis_idx == 1)
155 view_up_dir = vec3(0.0f, 0.0f, hit_axis < 0 ? 1.0f : -1.0f);
156
157 dvec3 axis;
158 double angle;
159 view_ptr->compute_axis_and_angle(-view_dir, view_up_dir, axis, angle);
160
161 cgv::gui::animate_with_axis_rotation(view_ptr->ref_view_dir(), axis, angle, 0.5)->set_base_ptr(this);
162 cgv::gui::animate_with_axis_rotation(view_ptr->ref_view_up_dir(), axis, angle, 0.5)->set_base_ptr(this);
163
164 post_redraw();
165 return true;
166 }
167 }
168 }
169 }
170 break;
171 default:
172 break;
173 }
174
175 return false;
176}
177
178void navigator::on_set(void* member_ptr) {
179
180 if(member_ptr == &layout_size) {
181 layout_size = cgv::math::clamp(layout_size, 10, 2000);
182 overlay::set_size(ivec2(layout_size));
183 }
184
185 update_member(member_ptr);
186 post_redraw();
187}
188
190
191 fbc.add_attachment("depth", "[D]");
192 fbc.add_attachment("color", "flt32[R,G,B,A]", TF_LINEAR);
193 fbc.set_size(get_rectangle().size);
194
195 bool success = true;
196
197 success &= fbc.ensure(ctx);
198
199 success &= arrow_data.init(ctx);
200 success &= box_data.init(ctx);
201 success &= box_wire_data.init(ctx);
202 success &= rectangle_data.init(ctx);
203 success &= sphere_data.init(ctx);
204
205 success &= box_renderer.init(ctx);
206
207 blit_canvas.register_shader("rectangle", cgv::g2d::shaders::rectangle);
208 success &= blit_canvas.init(ctx);
209
210 if(success) {
211 box_data.add_position(vec3(0.0f));
212 box_wire_data.add_position(vec3(0.0f));
213
214 sphere_data.add_position(vec3(0.0f));
215
216 const float length = 0.5f;
217
218 // x - red
219 arrow_data.add(vec3(0.0f), rgb(0.85f, 0.0f, 0.0f), vec3(length, 0.0f, 0.0f));
220 // y - green
221 arrow_data.add(vec3(0.0f), rgb(0.0f, 0.75f, 0.0f), vec3(0.0f, length, 0.0f));
222 // z - blue
223 arrow_data.add(vec3(0.0f), rgb(0.0f, 0.05f, 0.95f), vec3(0.0f, 0.0f, length));
224
225 blit_style.fill_color = rgba(1.0f);
226 blit_style.use_texture = true;
227 blit_style.use_blending = true;
228 blit_style.feather_width = 0.0f;
229
230 auto& blit_prog = blit_canvas.enable_shader(ctx, "rectangle");
231 blit_style.apply(ctx, blit_prog);
232 blit_canvas.disable_current_shader(ctx);
233 }
234
235 return success;
236}
237
239
240 if(!view_ptr)
241 view_ptr = find_view_as_node();
242
243 if(ensure_layout(ctx)) {
244 fbc.set_size(get_rectangle().size);
245 fbc.ensure(ctx);
246
247 blit_canvas.set_resolution(ctx, get_viewport_size());
248 }
249}
250
252
253 fbc.enable(ctx);
254
255 ctx.push_bg_color();
256 ctx.set_bg_color({ 0.0f });
257 ctx.clear_background(true, true);
258 ctx.pop_bg_color();
259
261 ctx.set_projection_matrix(get_projection_matrix());
262
264 ctx.set_modelview_matrix(get_view_matrix(ctx) * get_model_matrix(ctx));
265
267 ctx.disable_depth_test();
268
269 ctx.push_blend_state();
270 ctx.enable_blending();
271 ctx.set_blend_func_separate(BF_SRC_ALPHA, BF_ONE_MINUS_SRC_ALPHA, BF_ONE, BF_ONE_MINUS_SRC_ALPHA);
272
273 if(show_box)
274 box_data.render(ctx, box_renderer);
275
276 if(show_wireframe)
277 box_wire_data.render(ctx);
278
279 sphere_data.render(ctx);
280 arrow_data.render(ctx);
281
282 if(hit_axis != 0) {
283 int axis_idx = abs(hit_axis) - 1;
284 vec3 position(0.0f);
285 position[axis_idx] = hit_axis < 0.0f ? -0.5f : 0.5f;
286
287 const int mapping[3] = {1, 0, 2};
288
289 vec3 rotation_axis(0.0f);
290 rotation_axis[mapping[axis_idx]] = hit_axis < 0.0f ? -1.0f : 1.0f;
291
292 std::vector<quat> rotations;
293 quat rotation(rotation_axis, cgv::math::deg2rad(90.0f));
294
295 rectangle_data.clear();
296 rectangle_data.add_position(position);
297 rectangle_data.add_rotation(rotation);
298
299 rectangle_data.const_extent = vec2(0.9f);
300 rectangle_data.render(ctx);
301 }
302
305
306 fbc.disable(ctx);
307
308 ctx.set_blend_func(BF_SRC_ALPHA, BF_ONE_MINUS_SRC_ALPHA);
309
310 // draw frame buffer texture to screen
311 auto& blit_prog = blit_canvas.enable_shader(ctx, "rectangle");
312
313 fbc.enable_attachment(ctx, "color", 0);
314 blit_canvas.draw_shape(ctx, get_rectangle());
315 fbc.disable_attachment(ctx, "color");
316
317 blit_canvas.disable_current_shader(ctx);
318
319 ctx.pop_blend_state();
321}
322
323void navigator::set_size(int size) {
324
325 layout_size = size;
326 on_set(&layout_size);
327}
328
330
331 add_member_control(this, "Size", layout_size, "value_slider", "min=50;max=300;step=1;ticks=true");
332 add_member_control(this, "Show Box", show_box, "check");
333 add_member_control(this, "Show Wireframe", show_wireframe, "check");
334 add_member_control(this, "Use Perspective", use_perspective, "check");
335}
336
337mat4 navigator::get_model_matrix(context& ctx) {
338
339 mat4 MV = ctx.get_modelview_matrix();
340
341 // remove translation
342 MV(0, 3) = 0.0f;
343 MV(1, 3) = 0.0f;
344 MV(2, 3) = 0.0f;
345
346 return MV;
347}
348
349mat4 navigator::get_view_matrix(context& ctx) {
350
351 return cgv::math::look_at4(navigator_eye_pos, vec3(0.0f), vec3(0.0f, 1.0f, 0.0f));
352}
353
354mat4 navigator::get_projection_matrix() {
355
356 vec2 size = static_cast<vec2>(get_rectangle().size);
357 float aspect = size.x() / size.y();
358
359 if(use_perspective)
360 return cgv::math::perspective4(45.0f, aspect, 0.1f, 10.0f);
361 else
362 return cgv::math::ortho4(-1.0f, 1.0f, -1.0f, 1.0f, 0.01f, 5.0f);
363}
364
365bool navigator::intersect_box(const vec3 &origin, const vec3& direction, float& t) const {
366
367 vec3 min(-0.5f);
368 vec3 max(+0.5f);
369
370 float t_min, t_max;
371
372 vec3 inv_dir = vec3(1.0f) / direction;
373
374 float t1 = (min.x() - origin.x())*inv_dir.x();
375 float t2 = (max.x() - origin.x())*inv_dir.x();
376
377 t_min = std::min(t1, t2);
378 t_max = std::max(t1, t2);
379
380 t1 = (min.y() - origin.y())*inv_dir.y();
381 t2 = (max.y() - origin.y())*inv_dir.y();
382
383 t_min = std::max(t_min, std::min(t1, t2));
384 t_max = std::min(t_max, std::max(t1, t2));
385
386 t1 = (min.z() - origin.z())*inv_dir.z();
387 t2 = (max.z() - origin.z())*inv_dir.z();
388
389 t_min = std::max(t_min, std::min(t1, t2));
390 t_max = std::min(t_max, std::max(t1, t2));
391
392 t = t_min;
393 return t_max > std::max(t_min, 0.0f);
394}
395
396}
397}
bool handle_mouse_event(cgv::gui::mouse_event &e, cgv::ivec2 local_mouse_pos)
overload this method to handle mouse events; local_mouse_pos is the mouse position in the local coord...
Definition navigator.cxx:85
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...
virtual void create_gui_impl()
virtual method to implement the derived class gui creation
bool init(cgv::render::context &ctx)
this method is called after creation or recreation of the context, return whether all necessary funct...
void on_set(void *member_ptr)
default implementation of that calls handle_member_change and afterwards updates the member in the gu...
bool self_reflect(cgv::reflect::reflection_handler &_rh)
overload to reflect members of derived classes
Definition navigator.cxx:81
void init_frame(cgv::render::context &ctx)
this method is called in one pass over all drawables before the draw method
void clear(cgv::render::context &ctx)
clear all objects living in the context like textures or display lists
Definition navigator.cxx:67
cgv::g2d::irect get_rectangle() const
return the current rectangle area (in screen coordinates) of the overlay taking layout into account
Definition overlay.h:139
void set_stretch(StretchOption stretch, vec2 percentual_size=vec2(-1.0f))
set the stretch option
Definition overlay.cxx:92
void set_alignment(AlignmentOption horizontal, AlignmentOption vertical, vec2 percentual_offset=vec2(-1.0f))
set the alignment options
Definition overlay.cxx:80
void set_margin(const ivec2 &margin)
set the overlay margin
Definition overlay.cxx:103
ivec2 get_viewport_size() const
return the current viewport size
Definition overlay.h:133
gui_options_t gui_options
options for the GUI creation of this overlay (must be set before GUI creation)
Definition overlay.h:103
void set_size(const ivec2 &size)
set the default size of the overlay before stretch gets applied
Definition overlay.cxx:108
void set_name(const std::string &_name)
set a new parent node
Definition named.cxx:13
double get_time() const
return the time of the event in seconds
Definition event.cxx:247
class to represent all possible mouse events with the EID_MOUSE
Definition mouse_event.h:33
MouseAction get_action() const
return the mouse action
unsigned char get_button() const
return the pressed or released button for a button press or release action
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
T & z()
third element
Definition fvec.h:163
T & y()
second element
Definition fvec.h:159
T & x()
first element
Definition fvec.h:155
T & w()
fourth element
Definition fvec.h:167
static cgv::type::uint32_type size()
return number of elements
Definition fvec.h:179
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.
renderer that supports point splatting
base class for all drawables, which is independent of the used rendering API.
Definition context.h:621
virtual void set_blend_func(BlendFunction src_factor, BlendFunction dst_factor)
set the blend function
Definition context.cxx:1733
void pop_bg_color()
pop the top of the current background color from the stack
Definition context.cxx:288
virtual void set_blend_func_separate(BlendFunction src_color_factor, BlendFunction dst_color_factor, BlendFunction src_alpha_factor, BlendFunction dst_alpha_factor)
set the blend function separately for color and alpha
Definition context.cxx:1741
void push_depth_test_state()
push a copy of the current depth test state onto the stack saved attributes: depth test enablement,...
Definition context.cxx:1669
void push_blend_state()
push a copy of the current blend state onto the stack saved attributes: blend enablement,...
Definition context.cxx:1716
virtual void disable_depth_test()
disable the depth test
Definition context.cxx:1695
void pop_blend_state()
pop the top of the current culling state from the stack
Definition context.cxx:1720
virtual void clear_background(bool color_flag, bool depth_flag, bool stencil_flag=false, bool accum_flag=false)=0
clear the buffer contents of the flagged buffers to the set background colors
void pop_depth_test_state()
pop the top of the current depth test state from the stack
Definition context.cxx:1673
virtual void set_bg_color(vec4 rgba)
set a user defined background color
Definition context.cxx:293
void pop_projection_matrix()
see push_P for an explanation
Definition context.cxx:1825
void push_projection_matrix()
same as push_V but for the projection matrix - a different matrix stack is used.
Definition context.cxx:1820
virtual void set_projection_matrix(const dmat4 &P)
set the current projection matrix, which transforms from eye to clip space
Definition context.cxx:1853
virtual void enable_blending()
enable blending
Definition context.cxx:1756
virtual dmat4 get_modelview_matrix() const =0
return homogeneous 4x4 viewing matrix, which transforms from world to eye space
void pop_modelview_matrix()
see push_V for an explanation
Definition context.cxx:1814
void push_modelview_matrix()
push the current viewing matrix onto a matrix stack for viewing matrices.
Definition context.cxx:1802
virtual void set_modelview_matrix(const dmat4 &MV)
set the current modelview matrix, which transforms from world to eye space
Definition context.cxx:1836
void push_bg_color()
push a copy of the current background color onto the stack
Definition context.cxx:284
context * get_context() const
access the current context. The context will be available latestly in the init method but not in the ...
Definition drawable.cxx:37
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 set_size(const ivec2 &size)
Sets the size of the framebuffer renderbuffers.
cgv::data::optional< vec2 > const_extent
optional constant extent used for all elements
void render(context &ctx, unsigned offset=0, int count=-1)
Render the stored geometry.
bool init(context &ctx)
Initialize the attribute array manager.
void destruct(context &ctx)
Destruct the attribute array manager and decrease the reference count of the used renderer.
RenderStyleType style
the default render style
virtual bool init(context &ctx)
call init() once before using renderer
Definition renderer.cxx:173
virtual void clear(const context &ctx)
the clear function destructs the shader program
Definition renderer.cxx:349
const dvec3 & get_focus() const
query focus point
Definition view.cxx:48
dvec3 & ref_view_up_dir()
write access to view up direction
Definition view.cxx:18
const dvec3 get_eye() const
query the eye point, which is computed from focus, view dir, y extent at focus and y view angle
Definition view.cxx:123
dvec3 & ref_view_dir()
write access to view dir
Definition view.cxx:20
int compute_axis_and_angle(const dvec3 &target_view_dir, const dvec3 &target_view_up_dir, dvec3 &axis, double &angle)
compute axis and angle of a rotation that the current view_dir and view_up_dir to the given target_vi...
Definition view.cxx:27
@ MB_LEFT_BUTTON
left button
Definition mouse_event.h:26
@ MA_PRESS
mouse button pressed
Definition mouse_event.h:13
@ MA_LEAVE
mouse leave window action
Definition mouse_event.h:19
@ MA_RELEASE
mouse button released
Definition mouse_event.h:14
namespace for api independent GPU programming
the cgv namespace
Definition print.h:11
cgv::math::fvec< float, 4 > vec4
declare type of 4d single precision floating point vectors (used for homogeneous coordinates)
Definition fvec.h:671
cgv::media::color< float, cgv::media::RGB, cgv::media::OPACITY > rgba
declare rgba color type with 32 bit components
Definition color.h:855
cgv::media::color< float, cgv::media::RGB > rgb
declare rgb color type with 32 bit components
Definition color.h:853
cgv::math::fvec< int32_t, 2 > ivec2
declare type of 2d 32 bit integer vectors
Definition fvec.h:694
cgv::math::fvec< float, 2 > vec2
declare type of 2d single precision floating point vectors
Definition fvec.h:667
cgv::math::fvec< float, 3 > vec3
declare type of 3d single precision floating point vectors
Definition fvec.h:669
bool allow_stretch
whether to show the stretch options (show_layout_options must be enabled)
Definition overlay.h:98