Developer documentation
Version 3.0.3-105-gd3941f44
projection.h
Go to the documentation of this file.
1/* Copyright (c) 2008-2022 the MRtrix3 contributors.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 *
7 * Covered Software is provided under this License on an "as is"
8 * basis, without warranty of any kind, either expressed, implied, or
9 * statutory, including, without limitation, warranties that the
10 * Covered Software is free of defects, merchantable, fit for a
11 * particular purpose or non-infringing.
12 * See the Mozilla Public License v. 2.0 for more details.
13 *
14 * For more details, see http://www.mrtrix.org/.
15 */
16
17#ifndef __gui_projection_h__
18#define __gui_projection_h__
19
20#include "gui/gui.h"
21#include "gui/crosshair.h"
22#include "gui/opengl/gl.h"
23#include "gui/opengl/font.h"
25
26namespace MR
27{
28 namespace GUI
29 {
30
31 const int TopEdge = 0x00000001;
32 const int BottomEdge = 0x00000002;
33 const int LeftEdge = 0x00000004;
34 const int RightEdge = 0x00000008;
35
36
39 public:
40 void set_viewport (int x, int y, int w, int h) {
41 viewport[0] = x;
42 viewport[1] = y;
43 viewport[2] = w;
44 viewport[3] = h;
45 }
46
47 void set (const GL::mat4& modelview, const GL::mat4& projection) {
48 MV = modelview;
49 P = projection;
50 MVP = P * MV;
51
52 iMV = GL::inv (MV);
53 iP = GL::inv (P);
54 iMVP = iMV * iP;
55 }
56
57 GLint x_position () const {
58 return viewport[0];
59 }
60
61 GLint y_position () const {
62 return viewport[1];
63 }
64
65 GLint width () const {
66 return viewport[2];
67 }
68
69 GLint height () const {
70 return viewport[3];
71 }
72
73 float depth_of (const Eigen::Vector3f& x) const {
74 float d = MVP(2,0)*x[0] + MVP(2,1)*x[1] + MVP(2,2)*x[2] + MVP(2,3);
75 if (MVP(3,2)) d /= MVP(3,0)*x[0] + MVP(3,1)*x[1] + MVP(3,2)*x[2] + MVP(3,3);
76 return d;
77 }
78
79 Eigen::Vector3f model_to_screen (const Eigen::Vector3f& x) const {
80 Eigen::Vector3f S (
81 MVP(0,0)*x[0] + MVP(0,1)*x[1] + MVP(0,2)*x[2] + MVP(0,3),
82 MVP(1,0)*x[0] + MVP(1,1)*x[1] + MVP(1,2)*x[2] + MVP(1,3),
83 MVP(2,0)*x[0] + MVP(2,1)*x[1] + MVP(2,2)*x[2] + MVP(2,3));
84 if (MVP(3,2))
85 S /= MVP(3,0)*x[0] + MVP(3,1)*x[1] + MVP(3,2)*x[2] + MVP(3,3);
86 S[0] = viewport[0] + 0.5f*viewport[2]*(1.0f+S[0]);
87 S[1] = viewport[1] + 0.5f*viewport[3]*(1.0f+S[1]);
88 return S;
89 }
90
91 Eigen::Vector3f model_to_screen_direction (const Eigen::Vector3f& dir) const {
92 Eigen::Vector3f S (
93 MVP(0,0)*dir[0] + MVP(0,1)*dir[1] + MVP(0,2)*dir[2],
94 MVP(1,0)*dir[0] + MVP(1,1)*dir[1] + MVP(1,2)*dir[2],
95 MVP(2,0)*dir[0] + MVP(2,1)*dir[1] + MVP(2,2)*dir[2]);
96 S[0] *= 0.5f*viewport[2];
97 S[1] *= 0.5f*viewport[3];
98 return S;
99 }
100
101 Eigen::Vector3f screen_to_model (float x, float y, float depth) const {
102 x = 2.0f*(x-viewport[0])/viewport[2] - 1.0f;
103 y = 2.0f*(y-viewport[1])/viewport[3] - 1.0f;
104 Eigen::Vector3f S (
105 iMVP(0,0)*x + iMVP(0,1)*y + iMVP(0,2)*depth + iMVP(0,3),
106 iMVP(1,0)*x + iMVP(1,1)*y + iMVP(1,2)*depth + iMVP(1,3),
107 iMVP(2,0)*x + iMVP(2,1)*y + iMVP(2,2)*depth + iMVP(2,3));
108 if (MVP(3,2))
109 S /= iMVP(3,0)*x + iMVP(3,1)*y + iMVP(3,2)*depth + iMVP(3,3);
110 return S;
111 }
112
113 Eigen::Vector3f screen_to_model (const Eigen::Vector3f& x) const {
114 return screen_to_model (x[0], x[1], x[2]);
115 }
116
117 Eigen::Vector3f screen_to_model (const Eigen::Vector3f& x, float depth) const {
118 return screen_to_model (x[0], x[1], depth);
119 }
120
121 Eigen::Vector3f screen_to_model (const Eigen::Vector3f& x, const Eigen::Vector3f& depth) const {
122 return screen_to_model (x, depth_of (depth));
123 }
124
125 Eigen::Vector3f screen_to_model (const QPoint& x, float depth) const {
126 return screen_to_model (x.x(), x.y(), depth);
127 }
128
129 Eigen::Vector3f screen_to_model (const QPoint& x, const Eigen::Vector3f& depth) const {
130 return screen_to_model (x, depth_of (depth));
131 }
132
133 Eigen::Vector3f screen_normal () const {
134 return Eigen::Vector3f (iMVP(0,2), iMVP(1,2), iMVP(2,2)).normalized().eval();
135 }
136
137 Eigen::Vector3f screen_to_model_direction (float x, float y, float depth) const {
138 x *= 2.0f/viewport[2];
139 y *= 2.0f/viewport[3];
140 Eigen::Vector3f S (iMVP(0,0)*x + iMVP(0,1)*y, iMVP(1,0)*x + iMVP(1,1)*y, iMVP(2,0)*x + iMVP(2,1)*y);
141 if (MVP(3,2))
142 S /= iMVP(3,2)*depth + iMVP(3,3);
143 return S;
144 }
145
146 Eigen::Vector3f screen_to_model_direction (const Eigen::Vector3f& dx, float x) const {
147 return screen_to_model_direction (dx[0], dx[1], x);
148 }
149
150 Eigen::Vector3f screen_to_model_direction (const Eigen::Vector3f& dx, const Eigen::Vector3f& x) const {
151 return screen_to_model_direction (dx, depth_of (x));
152 }
153
154 Eigen::Vector3f screen_to_model_direction (const QPoint& dx, float x) const {
155 return screen_to_model_direction (dx.x(), dx.y(), x);
156 }
157
158 Eigen::Vector3f screen_to_model_direction (const QPoint& dx, const Eigen::Vector3f& x) const {
159 return screen_to_model_direction (dx, depth_of (x));
160 }
161
162 protected:
164 GLint viewport[4];
165 };
166
167
168
169
170
171
173 { NOMEMALIGN
174 public:
175 Projection (GL::Area* parent, const GL::Font& font) :
176 glarea (parent),
177 font (font),
178 crosshair (new Crosshair()) { }
179
180 void set_viewport (const QWidget& frame, int x, int y, int w, int h) {
182 set_viewport (frame);
183 }
184
185#if QT_VERSION >= 0x050100
186 void set_viewport (const QWidget& frame) const {
187 int m = frame.window()->devicePixelRatio();
188 gl::Viewport (m*viewport[0], m*viewport[1], m*viewport[2], m*viewport[3]);
189 }
190#else
191 void set_viewport (const QWidget&) const {
192 gl::Viewport (viewport[0], viewport[1], viewport[2], viewport[3]);
193 }
194#endif
195
196 void render_crosshairs (const Eigen::Vector3f& focus) const { crosshair->render (focus, *this); }
197
198 void setup_render_text (float red = 1.0, float green = 1.0, float blue = 0.0) const {
199 font.start (width(), height(), red, green, blue);
200 }
201 void done_render_text () const { font.stop(); }
202
203 void render_text (int x, int y, const std::string& text) const {
204 font.render (text, x, y);
205 }
206
207 void render_text_align (int x, int y, const std::string& text, int halign = 0, int valign = 0) const {
208 QString s (qstr(text));
209 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
210 int w = font.metric.width (s);
211 #else
212 int w = font.metric.horizontalAdvance (s);
213 #endif
214 int h = font.metric.height();
215 if (halign == 0) x -= w/2;
216 else if (halign > 0) x -= w;
217 if (valign == 0) y -= h/2;
218 else if (valign > 0) y -= h;
219 render_text (x, y, text);
220 }
221
222 void render_text_inset (int x, int y, const std::string& text, int inset = -1) const {
223 QString s (qstr(text));
224 if (inset < 0)
225 inset = font.metric.height() / 2;
226 if (x < inset)
227 x = inset;
228 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
229 if (x + font.metric.width (s) + inset > width())
230 x = width() - font.metric.width (s) - inset;
231 #else
232 if (x + font.metric.horizontalAdvance (s) + inset > width())
233 x = width() - font.metric.horizontalAdvance (s) - inset;
234 #endif
235
236 if (y < inset)
237 y = inset;
238 if (y + font.metric.height() + inset > height())
239 y = height() - font.metric.height() - inset;
240 render_text (x, y, text);
241 }
242
243 void render_text (const std::string& text, int position, int line = 0) const {
244 QString s (qstr(text));
245 int x, y;
246
247 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
248 if (position & RightEdge) x = width() - font.metric.height() / 2 - font.metric.width (s);
249 else if (position & LeftEdge) x = font.metric.height() / 2;
250 else x = (width() - font.metric.width (s)) / 2;
251 #else
252 if (position & RightEdge) x = width() - font.metric.height() / 2 - font.metric.horizontalAdvance (s);
253 else if (position & LeftEdge) x = font.metric.height() / 2;
254 else x = (width() - font.metric.horizontalAdvance (s)) / 2;
255 #endif
256
257 if (position & TopEdge) y = height() - 1.5 * font.metric.height() - line * font.metric.lineSpacing();
258 else if (position & BottomEdge) y = font.metric.height() / 2 + line * font.metric.lineSpacing();
259 else y = (height() - font.metric.height()) / 2 - line * font.metric.lineSpacing();
260
261 render_text (x, y, text);
262 }
263
265
266
267 const GL::mat4& modelview_projection () const { return MVP; }
268 const GL::mat4& modelview_projection_inverse () const { return iMVP; }
269 const GL::mat4& modelview () const { return MV; }
270 const GL::mat4& modelview_inverse () const { return iMV; }
271 const GL::mat4& projection () const { return P; }
272 const GL::mat4& projection_inverse () const { return iP; }
273
274
276
277 void set (GL::Shader::Program& shader_program) const {
278 assert (shader_program != 0);
279 gl::UniformMatrix4fv (gl::GetUniformLocation (shader_program, "MVP"), 1, gl::FALSE_, modelview_projection());
280 }
281
282 protected:
285 std::shared_ptr<Crosshair> crosshair;
286 };
287
288
289
290
291 }
292}
293
294#endif
void stop() const
Definition: font.h:54
void render(const std::string &text, int x, int y) const
void start(int width, int height, float red, float green, float blue) const
Definition: font.h:39
const QFontMetrics metric
Definition: font.h:37
Eigen::Vector3f screen_to_model(const QPoint &x, const Eigen::Vector3f &depth) const
Definition: projection.h:129
Eigen::Vector3f screen_normal() const
Definition: projection.h:133
float depth_of(const Eigen::Vector3f &x) const
Definition: projection.h:73
void set_viewport(int x, int y, int w, int h)
Definition: projection.h:40
Eigen::Vector3f screen_to_model(const Eigen::Vector3f &x, float depth) const
Definition: projection.h:117
Eigen::Vector3f screen_to_model_direction(const QPoint &dx, const Eigen::Vector3f &x) const
Definition: projection.h:158
Eigen::Vector3f screen_to_model(const Eigen::Vector3f &x, const Eigen::Vector3f &depth) const
Definition: projection.h:121
Eigen::Vector3f screen_to_model(const QPoint &x, float depth) const
Definition: projection.h:125
Eigen::Vector3f model_to_screen(const Eigen::Vector3f &x) const
Definition: projection.h:79
Eigen::Vector3f screen_to_model_direction(const Eigen::Vector3f &dx, float x) const
Definition: projection.h:146
Eigen::Vector3f screen_to_model_direction(const Eigen::Vector3f &dx, const Eigen::Vector3f &x) const
Definition: projection.h:150
Eigen::Vector3f model_to_screen_direction(const Eigen::Vector3f &dir) const
Definition: projection.h:91
Eigen::Vector3f screen_to_model(const Eigen::Vector3f &x) const
Definition: projection.h:113
Eigen::Vector3f screen_to_model_direction(const QPoint &dx, float x) const
Definition: projection.h:154
void set(const GL::mat4 &modelview, const GL::mat4 &projection)
Definition: projection.h:47
Eigen::Vector3f screen_to_model(float x, float y, float depth) const
Definition: projection.h:101
Eigen::Vector3f screen_to_model_direction(float x, float y, float depth) const
Definition: projection.h:137
GL::Area * glarea
Definition: projection.h:283
void render_text_align(int x, int y, const std::string &text, int halign=0, int valign=0) const
Definition: projection.h:207
std::shared_ptr< Crosshair > crosshair
Definition: projection.h:285
void render_text(const std::string &text, int position, int line=0) const
Definition: projection.h:243
void draw_orientation_labels() const
void render_text(int x, int y, const std::string &text) const
Definition: projection.h:203
const GL::mat4 & modelview_inverse() const
Definition: projection.h:270
void done_render_text() const
Definition: projection.h:201
void render_text_inset(int x, int y, const std::string &text, int inset=-1) const
Definition: projection.h:222
void set_viewport(const QWidget &) const
Definition: projection.h:191
void set(GL::Shader::Program &shader_program) const
Definition: projection.h:277
const GL::mat4 & modelview_projection() const
Definition: projection.h:267
const GL::Font & font
Definition: projection.h:284
const GL::mat4 & modelview() const
Definition: projection.h:269
void render_crosshairs(const Eigen::Vector3f &focus) const
Definition: projection.h:196
const GL::mat4 & modelview_projection_inverse() const
Definition: projection.h:268
const GL::mat4 & projection() const
Definition: projection.h:271
void setup_render_text(float red=1.0, float green=1.0, float blue=0.0) const
Definition: projection.h:198
const GL::mat4 & projection_inverse() const
Definition: projection.h:272
void set_viewport(const QWidget &frame, int x, int y, int w, int h)
Definition: projection.h:180
Projection(GL::Area *parent, const GL::Font &font)
Definition: projection.h:175
#define NOMEMALIGN
Definition: memory.h:22
mat4 inv(const mat4 &a)
const int BottomEdge
Definition: projection.h:32
const int LeftEdge
Definition: projection.h:33
QString qstr(const std::string &s)
Definition: gui.h:31
const int TopEdge
Definition: projection.h:31
const int RightEdge
Definition: projection.h:34
Definition: base.h:24
Eigen::MatrixXd S