Horizon
canvas3d.hpp
1#pragma once
2#include "canvas_mesh.hpp"
3#include "canvas/appearance.hpp"
4#include "clipper/clipper.hpp"
5#include "common/common.hpp"
6#include "util/msd_animator.hpp"
7#include <epoxy/gl.h>
8#include <glm/glm.hpp>
9#include <gtkmm.h>
10#include <unordered_map>
11#include "canvas3d_base.hpp"
12#include "spacenav_prefs.hpp"
13#include <atomic>
14#include <thread>
15
16namespace horizon {
17class Canvas3D : public Gtk::GLArea, public Canvas3DBase {
18public:
19 friend class CoverRenderer;
20 friend class WallRenderer;
21 friend class FaceRenderer;
22 friend class BackgroundRenderer;
23 Canvas3D();
24
25 float far;
26 float near;
27
28 bool smooth_zoom = false;
29 bool touchpad_pan = false;
30 SpacenavPrefs spacenav_prefs;
31
32 void request_push();
33 void update(const class Board &brd);
34 void update_packages();
35 void set_highlights(const std::set<UUID> &pkgs);
36
37 void animate_to_azimuth_elevation_abs(float az, float el);
38 void animate_to_azimuth_elevation_rel(float az, float el);
39 void animate_zoom_step(int inc);
40 void animate_center_rel(const glm::vec2 &d);
41 void set_appearance(const Appearance &a);
42
43 void set_msaa(unsigned int samples);
44
45 void load_models_async(class IPool &pool);
46
47 void view_all();
48
49 void set_msd_params(const MSD::Params &params);
50
51 glm::vec2 get_center_shift(const glm::vec2 &shift) const;
52
53 typedef sigc::signal<void, unsigned int, unsigned int> type_signal_models_loading;
54 type_signal_models_loading signal_models_loading()
55 {
56 return s_signal_models_loading;
57 }
58 type_signal_models_loading signal_layers_loading()
59 {
60 return s_signal_layers_loading;
61 }
62
63 typedef sigc::signal<void, UUID> type_signal_package_select;
64 type_signal_package_select signal_package_select()
65 {
66 return s_signal_package_select;
67 }
68
69 typedef sigc::signal<void, glm::dvec3> type_signal_point_select;
70 type_signal_point_select signal_point_select()
71 {
72 return s_signal_point_select;
73 }
74
75 typedef sigc::signal<void, unsigned int> type_signal_spacenav_button_press;
76 type_signal_spacenav_button_press signal_spacenav_button_press()
77 {
78 return s_signal_spacenav_button_press;
79 }
80
81 bool get_spacenav_available() const
82 {
83 return have_spnav;
84 }
85
86 ~Canvas3D();
87
88private:
89 bool needs_push = false;
90 bool needs_view_all = false;
91 int a_get_scale_factor() const override;
92 void redraw() override;
93
94 void on_size_allocate(Gtk::Allocation &alloc) override;
95 void on_realize() override;
96 bool on_render(const Glib::RefPtr<Gdk::GLContext> &context) override;
97 bool on_button_press_event(GdkEventButton *button_event) override;
98 bool on_motion_notify_event(GdkEventMotion *motion_event) override;
99 bool on_button_release_event(GdkEventButton *button_event) override;
100 bool on_scroll_event(GdkEventScroll *scroll_event) override;
101
102 void pan_zoom(GdkEventScroll *scroll_event);
103 void pan_drag_move(GdkEventScroll *scroll_event);
104 void pan_rotate(GdkEventScroll *scroll_event);
105
106 Glib::RefPtr<Gtk::GestureDrag> gesture_drag;
107 glm::vec2 gesture_drag_center_orig;
108 void drag_gesture_begin_cb(GdkEventSequence *seq);
109 void drag_gesture_update_cb(GdkEventSequence *seq);
110
111 Glib::RefPtr<Gtk::GestureZoom> gesture_zoom;
112 float gesture_zoom_cam_dist_orig = 1;
113 void zoom_gesture_begin_cb(GdkEventSequence *seq);
114 void zoom_gesture_update_cb(GdkEventSequence *seq);
115
116 Glib::RefPtr<Gtk::GestureRotate> gesture_rotate;
117 float gesture_rotate_cam_azimuth_orig = 0;
118 float gesture_rotate_cam_elevation_orig = 0;
119 glm::vec2 gesture_rotate_pos_orig;
120 void rotate_gesture_begin_cb(GdkEventSequence *seq);
121 void rotate_gesture_update_cb(GdkEventSequence *seq);
122
123 glm::vec2 pointer_pos_orig;
124 float cam_azimuth_orig;
125 float cam_elevation_orig;
126
127 glm::vec2 center_orig;
128
129 enum class PanMode { NONE, MOVE, ROTATE };
130 PanMode pan_mode = PanMode::NONE;
131
132
133 bool needs_resize = false;
134
135 MSDAnimator azimuth_animator;
136 MSDAnimator elevation_animator;
137 MSDAnimator zoom_animator;
138 MSDAnimator cx_animator;
139 MSDAnimator cy_animator;
140
141 std::vector<MSDAnimator *> animators;
142 int animate_step(GdkFrameClock *frame_clock);
143 static int anim_tick_cb(GtkWidget *cwidget, GdkFrameClock *frame_clock, gpointer user_data);
144 void start_anim();
145
146 void prepare();
147
148 void load_models_thread(std::map<std::string, std::string> model_filenames);
149
150
151 Glib::Dispatcher models_loading_dispatcher;
152
153 type_signal_models_loading s_signal_models_loading;
154 type_signal_models_loading s_signal_layers_loading;
155 unsigned int n_models_loading = 0;
156 std::atomic<unsigned int> i_model_loading;
157
158 std::thread model_load_thread;
159 std::atomic<bool> stop_model_load_thread;
160
161 type_signal_package_select s_signal_package_select;
162 type_signal_point_select s_signal_point_select;
163 int pick_x, pick_y;
164
165 std::map<int, CanvasMesh::Layer3D> layers_local;
166 std::set<int> layers_to_be_moved;
167 const std::map<int, CanvasMesh::Layer3D> &get_layers() const override;
168
169 Glib::Dispatcher prepare_dispatcher;
170 std::thread prepare_thread;
171 void prepare_thread_worker();
172
173 bool have_spnav = false;
174 void handle_spnav();
175 sigc::connection spnav_connection;
176
177 type_signal_spacenav_button_press s_signal_spacenav_button_press;
178};
179} // namespace horizon
Definition: appearance.hpp:7
Definition: background_renderer.hpp:5
Definition: board.hpp:47
Definition: canvas3d_base.hpp:20
Definition: canvas3d.hpp:17
Definition: cover_renderer.hpp:7
Definition: face_renderer.hpp:6
Definition: ipool.hpp:14
Definition: msd_animator.hpp:5
Definition: wall_renderer.hpp:7
Definition: msd.hpp:13
Definition: spacenav_prefs.hpp:4