Visual Computing Library
Loading...
Searching...
No Matches
abstract_viewer_drawer.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_RENDER_DRAWERS_ABSTRACT_VIEWER_DRAWER_H
24#define VCL_RENDER_DRAWERS_ABSTRACT_VIEWER_DRAWER_H
25
26#include "event_drawer.h"
27
28#include <vclib/render/drawable/drawable_object_vector.h>
29#include <vclib/render/drawers/event_drawer.h>
30#include <vclib/render/read_buffer_types.h>
31#include <vclib/render/viewer/desktop_trackball.h>
32
33#include <memory>
34
35namespace vcl {
36
45template<typename DerivedRenderApp>
47 public DesktopTrackBall<float>,
48 public EventDrawer<DerivedRenderApp>
49{
50 bool mReadRequested = false;
51
52protected:
53 // the list of drawable objects
54 // it could be owned by the viewer, or it could be shared with other
55 // objects (e.g. the window that contains the viewer along with other
56 // widgets)
57 std::shared_ptr<DrawableObjectVector> mDrawList =
58 std::make_shared<DrawableObjectVector>();
59
61
62public:
63 AbstractViewerDrawer(uint width = 1024, uint height = 768) :
64 DTB(width, height)
65 {
66 }
67
68 ~AbstractViewerDrawer() = default;
69
70 const DrawableObjectVector& drawableObjectVector() const
71 {
72 return *mDrawList;
73 }
74
75 void setDrawableObjectVector(const std::shared_ptr<DrawableObjectVector>& v)
76 {
77 mDrawList = v;
78
79 for (auto obj : *mDrawList) {
80 obj->init();
81 }
82 fitScene();
83 }
84
85 uint pushDrawableObject(const DrawableObject& obj)
86 {
87 mDrawList->pushBack(obj);
88 mDrawList->back()->init();
89 return mDrawList->size() - 1;
90 }
91
92 uint pushDrawableObject(DrawableObject&& obj)
93 {
94 mDrawList->pushBack(std::move(obj));
95 mDrawList->back()->init();
96 return mDrawList->size() - 1;
97 }
98
99 void fitScene()
100 {
102 float sceneRadius = 1;
103
104 Box3d bb = mDrawList->boundingBox();
105
106 if (!bb.isNull()) {
107 sceneCenter = bb.center().cast<float>();
108 sceneRadius = bb.diagonal();
109 }
110
111 DTB::setTrackBall(sceneCenter, sceneRadius);
112 }
113
114 virtual void toggleAxisVisibility() = 0;
115
116 virtual void toggleTrackBallVisibility() = 0;
117
118 // events
119 void onInit(uint) override
120 {
121 DerivedRenderApp::DRW::setCanvasDefaultClearColor(
122 derived(), Color::White);
123 }
124
125 void onResize(unsigned int width, unsigned int height) override
126 {
127 DTB::resizeViewer(width, height);
128 }
129
130 void onKeyPress(Key::Enum key, const KeyModifiers& modifiers) override
131 {
132 DTB::setKeyModifiers(modifiers);
133
134 switch (key) {
135 case Key::C:
136 std::cout << "(" << DTB::camera().eye() << ") "
137 << "(" << DTB::camera().center() << ") "
138 << "(" << DTB::camera().up() << ")\n";
139 std::cout << std::flush;
140 break;
141
142 case Key::A: toggleAxisVisibility(); break;
143
144 case Key::S:
145 if (modifiers[KeyModifier::CONTROL])
146 DerivedRenderApp::DRW::screenshot(
147 derived(), "viewer_screenshot.png");
148 break;
149
150 case Key::T: toggleTrackBallVisibility(); break;
151
152 default: break;
153 }
154
155 DTB::keyPress(key);
156 }
157
158 void onKeyRelease(Key::Enum key, const KeyModifiers& modifiers) override
159 {
160 DTB::setKeyModifiers(modifiers);
161 DTB::keyRelease(key);
162 }
163
164 void onMouseMove(double x, double y, const KeyModifiers& modifiers) override
165 {
166 DTB::setKeyModifiers(modifiers);
167 DTB::moveMouse(x, y);
168 }
169
170 void onMousePress(
171 MouseButton::Enum button,
172 double x,
173 double y,
174 const KeyModifiers& modifiers) override
175 {
176 DTB::setKeyModifiers(modifiers);
177 DTB::moveMouse(x, y);
178 DTB::pressMouse(button);
179 }
180
181 void onMouseRelease(
182 MouseButton::Enum button,
183 double x,
184 double y,
185 const KeyModifiers& modifiers) override
186 {
187 DTB::setKeyModifiers(modifiers);
188 DTB::moveMouse(x, y);
189 DTB::releaseMouse(button);
190 }
191
192 void onMouseScroll(double dx, double dy, const KeyModifiers& modifiers)
193 override
194 {
195 DTB::setKeyModifiers(modifiers);
196 DTB::scroll(dx, dy);
197 }
198
199protected:
200 void readRequest(
201 MouseButton::Enum button,
202 double x,
203 double y,
204 const KeyModifiers& modifiers,
205 bool homogeneousNDC = true)
206 {
207 using ReadData = ReadBufferTypes::ReadData;
208 using FloatData = ReadBufferTypes::FloatData;
209
210 if (mReadRequested)
211 return;
212
213 // get point
214 const Point2d p(x, y);
215
216 // create the callback
217 const auto proj = DTB::projectionMatrix();
218 const auto view = DTB::viewMatrix();
219 // viewport
220 auto size = DerivedRenderApp::DRW::canvasSize(derived());
221
222 const Point4f vp = {.0f, .0f, float(size.x()), float(size.y())};
223
224 auto callback = [=, this](const ReadData& dt) {
225 mReadRequested = false;
226
227 const auto& data = std::get<FloatData>(dt);
228 assert(data.size() == 1);
229 const float depth = data[0];
230 // if the depth is 1.0, the point is not in the scene
231 if (depth == 1.0f) {
232 return;
233 }
234
235 // unproject the point
236 const Point3f p2d(p.x(), vp[3] - p.y(), depth);
237 auto unproj = unproject(
239
240 this->focus(unproj);
241 derived()->update();
242 };
243
244 mReadRequested = DerivedRenderApp::DRW::readDepth(
245 derived(), Point2i(p.x(), p.y()), callback);
246 if (mReadRequested)
247 derived()->update();
248 }
249
250private:
251 auto* derived() { return static_cast<DerivedRenderApp*>(this); }
252
253 const auto* derived() const
254 {
255 return static_cast<const DerivedRenderApp*>(this);
256 }
257};
258
259} // namespace vcl
260
261#endif // VCL_RENDER_DRAWERS_ABSTRACT_VIEWER_DRAWER_H
The AbstractViewerDrawer class is a base class for all viewer drawers implementations.
Definition abstract_viewer_drawer.h:49
Definition desktop_trackball.h:37
Definition drawable_object_vector.h:36
The DrawableObject class is the base class for all the objects that can be drawn in a 3D viewer.
Definition drawable_object.h:55
The EventDrawer class is a base class for drawers that can handle events.
Definition event_drawer.h:44
The Point class represents an N-dimensional point containing N scalar values.
Definition point.h:58
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
Point2< int > Point2i
A convenience alias for a 2-dimensional Point with integer components.
Definition point.h:731