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>
14navigator::navigator() {
20 navigator_eye_pos =
vec3(0.0f, 0.0f, 2.5f);
32 show_wireframe =
true;
33 use_perspective =
true;
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);
40 box_data.style.illumination_mode = IM_TWO_SIDED;
41 box_data.style.culling_mode = CM_OFF;
42 box_data.style.material.diffuse_reflectance =
rgb(0.5f);
43 box_data.style.material.emission =
rgb(0.05f);
44 box_data.style.surface_opacity = 0.35f;
46 box_wire_data.style.default_color =
rgb(0.5f);
48 sphere_data.style.illumination_mode = IM_OFF;
49 sphere_data.style.radius = 0.04f;
50 sphere_data.style.surface_color =
rgb(0.5f);
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;
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);
69 blit_canvas.destruct(ctx);
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);
78 box_renderer.clear(ctx);
87 int last_hit_axis = hit_axis;
97 vec3 origin =
vec3(window_coord, navigator_eye_pos.
z());
98 vec3 direction =
vec3(0.0f, 0.0f, -1.0f);
100 if(use_perspective) {
101 mat4 MVP = get_projection_matrix() * get_view_matrix(ctx);
103 vec4 world_coord(window_coord.
x(), window_coord.
y(), 1.0f, 1.0f);
104 world_coord = inverse(MVP) * world_coord;
105 world_coord /= world_coord.
w();
107 vec3 origin = navigator_eye_pos;
108 vec3 direction = normalize(
vec3(world_coord) - origin);
111 mat4 IM = inverse(get_model_matrix(ctx));
113 origin =
vec3(IM *
vec4(origin, 1.0f));
114 direction =
vec3(IM *
vec4(direction, 0.0f));
116 float t = std::numeric_limits<float>::max();
117 if(intersect_box(origin, direction, t)) {
118 vec3 hit_pos = origin + t * direction;
120 unsigned mi = cgv::math::max_index(cgv::math::abs(hit_pos));
122 hit_axis =
static_cast<int>(mi) + 1;
123 if(hit_pos[mi] < 0.0f)
124 hit_axis = -hit_axis;
128 if(last_hit_axis != hit_axis)
132 switch(e.get_action()) {
135 check_for_click = e.get_time();
140 if(check_for_click != -1) {
141 double dt = e.get_time() - check_for_click;
144 int axis_idx = abs(hit_axis) - 1;
147 view_dir[axis_idx] = hit_axis < 0.0f ? -1.0f : 1.0f;
150 vec3 focus = view_ptr->get_focus();
151 float dist = (focus - view_ptr->get_eye()).length();
153 vec3 view_up_dir(0.0f, 1.0f, 0.0f);
155 view_up_dir =
vec3(0.0f, 0.0f, hit_axis < 0 ? 1.0f : -1.0f);
159 view_ptr->compute_axis_and_angle(-view_dir, view_up_dir, axis, angle);
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);
180 if(member_ptr == &layout_size) {
181 layout_size = cgv::math::clamp(layout_size, 10, 2000);
191 fbc.add_attachment(
"depth",
"[D]");
192 fbc.add_attachment(
"color",
"flt32[R,G,B,A]", TF_LINEAR);
197 success &= fbc.ensure(ctx);
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);
205 success &= box_renderer.init(ctx);
207 blit_canvas.register_shader(
"rectangle", cgv::g2d::shaders::rectangle);
208 success &= blit_canvas.init(ctx);
211 box_data.add_position(
vec3(0.0f));
212 box_wire_data.add_position(
vec3(0.0f));
214 sphere_data.add_position(
vec3(0.0f));
216 const float length = 0.5f;
219 arrow_data.add(
vec3(0.0f),
rgb(0.85f, 0.0f, 0.0f),
vec3(length, 0.0f, 0.0f));
221 arrow_data.add(
vec3(0.0f),
rgb(0.0f, 0.75f, 0.0f),
vec3(0.0f, length, 0.0f));
223 arrow_data.add(
vec3(0.0f),
rgb(0.0f, 0.05f, 0.95f),
vec3(0.0f, 0.0f, length));
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;
230 auto& blit_prog = blit_canvas.enable_shader(ctx,
"rectangle");
231 blit_style.apply(ctx, blit_prog);
232 blit_canvas.disable_current_shader(ctx);
243 if(ensure_layout(ctx)) {
256 ctx.set_bg_color({ 0.0f });
257 ctx.clear_background(
true,
true);
260 ctx.push_projection_matrix();
261 ctx.set_projection_matrix(get_projection_matrix());
263 ctx.push_modelview_matrix();
264 ctx.set_modelview_matrix(get_view_matrix(ctx) * get_model_matrix(ctx));
266 ctx.push_depth_test_state();
267 ctx.disable_depth_test();
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);
274 box_data.render(ctx, box_renderer);
277 box_wire_data.render(ctx);
279 sphere_data.render(ctx);
280 arrow_data.render(ctx);
283 int axis_idx = abs(hit_axis) - 1;
285 position[axis_idx] = hit_axis < 0.0f ? -0.5f : 0.5f;
287 const int mapping[3] = {1, 0, 2};
289 vec3 rotation_axis(0.0f);
290 rotation_axis[mapping[axis_idx]] = hit_axis < 0.0f ? -1.0f : 1.0f;
292 std::vector<quat> rotations;
293 quat rotation(rotation_axis, cgv::math::deg2rad(90.0f));
295 rectangle_data.clear();
296 rectangle_data.add_position(position);
297 rectangle_data.add_rotation(rotation);
299 rectangle_data.const_extent =
vec2(0.9f);
300 rectangle_data.render(ctx);
303 ctx.pop_modelview_matrix();
304 ctx.pop_projection_matrix();
308 ctx.set_blend_func(BF_SRC_ALPHA, BF_ONE_MINUS_SRC_ALPHA);
311 auto& blit_prog = blit_canvas.enable_shader(ctx,
"rectangle");
313 fbc.enable_attachment(ctx,
"color", 0);
315 fbc.disable_attachment(ctx,
"color");
317 blit_canvas.disable_current_shader(ctx);
319 ctx.pop_blend_state();
320 ctx.pop_depth_test_state();
323void navigator::set_size(
int size) {
331 add_member_control(
this,
"Size", layout_size,
"value_slider",
"min=50;max=300;step=1;ticks=true");
351 return cgv::math::look_at4(navigator_eye_pos,
vec3(0.0f),
vec3(0.0f, 1.0f, 0.0f));
354mat4 navigator::get_projection_matrix() {
357 float aspect = size.x() / size.y();
360 return cgv::math::perspective4(45.0f, aspect, 0.1f, 10.0f);
362 return cgv::math::ortho4(-1.0f, 1.0f, -1.0f, 1.0f, 0.01f, 5.0f);
365bool navigator::intersect_box(
const vec3 &origin,
const vec3& direction,
float& t)
const {
372 vec3 inv_dir =
vec3(1.0f) / direction;
374 float t1 = (min.x() - origin.
x())*inv_dir.
x();
375 float t2 = (max.x() - origin.
x())*inv_dir.
x();
377 t_min = std::min(t1, t2);
378 t_max = std::max(t1, t2);
380 t1 = (min.y() - origin.
y())*inv_dir.
y();
381 t2 = (max.y() - origin.
y())*inv_dir.
y();
383 t_min = std::max(t_min, std::min(t1, t2));
384 t_max = std::min(t_max, std::max(t1, t2));
386 t1 = (min.z() - origin.
z())*inv_dir.
z();
387 t2 = (max.z() - origin.
z())*inv_dir.
z();
389 t_min = std::max(t_min, std::min(t1, t2));
390 t_max = std::min(t_max, std::max(t1, t2));
393 return t_max > std::max(t_min, 0.0f);
void set_name(const std::string &_name)
set a new parent node
class to represent all possible mouse events with the EID_MOUSE
virtual void update_member(void *member_ptr)
call this to update all views and controls of a member
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
T & z()
return third component
T & y()
return second component
T & x()
return first component
T & w()
return fourth component
static cgv::type::uint32_type size()
return number of components
virtual void create_gui_impl()
virtual method to implement the derived class gui creation
void clear(cgv::render::context &ctx)
clear all objects living in the context like textures or display lists
void init_frame(cgv::render::context &ctx)
this method is called in one pass over all drawables before the draw method
bool self_reflect(cgv::reflect::reflection_handler &_rh)
overload to reflect members of derived classes
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...
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...
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...
void set_stretch_mode(StretchMode stretch, vec2 percentual_size=vec2(-1.0f))
set the stretch mode
void set_size(const ivec2 &size)
set the default size of the overlay before stretch gets applied
void set_alignment(Alignment horizontal, Alignment vertical, vec2 percentual_offset=vec2(-1.0f))
set the alignment
cgv::g2d::irect get_rectangle() const
return the current rectangle area (in screen coordinates) of the overlay taking layout into account
void set_margin(const ivec2 &margin)
set the overlay margin
gui_options_t gui_options
options for the GUI creation of this overlay (must be set before GUI creation)
ivec2 get_viewport_size() const
return the current viewport size
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.
base class for all drawables, which is independent of the used rendering API.
virtual dmat4 get_modelview_matrix() const =0
return homogeneous 4x4 viewing matrix, which transforms from world to eye space
context * get_context() const
access the current context. The context will be available latestly in the init method but not in the ...
view * find_view_as_node(size_t view_idx=0) const
convenience function to find the view control in the current hierarchy
void post_redraw()
posts a redraw event to the current context if one is available
@ MB_LEFT_BUTTON
left button
@ MA_PRESS
mouse button pressed
@ MA_LEAVE
mouse leave window action
@ MA_RELEASE
mouse button released
namespace for api independent GPU programming
this header is dependency free
cgv::math::fvec< float, 4 > vec4
declare type of 4d single precision floating point vectors (used for homogeneous coordinates)
cgv::media::color< float, cgv::media::RGB, cgv::media::OPACITY > rgba
declare rgba color type with 32 bit components
cgv::math::quaternion< float > quat
declare type of quaternion
cgv::math::fvec< double, 3 > dvec3
declare type of 3d double precision floating point vectors
cgv::media::color< float, cgv::media::RGB > rgb
declare rgb color type with 32 bit components
cgv::math::fvec< int32_t, 2 > ivec2
declare type of 2d 32 bit integer vectors
cgv::math::fvec< float, 2 > vec2
declare type of 2d single precision floating point vectors
cgv::math::fvec< float, 3 > vec3
declare type of 3d single precision floating point vectors
cgv::math::fmat< float, 4, 4 > mat4
declare type of 4x4 matrices