Developer documentation
Version 3.0.3-105-gd3941f44
transformation.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_opengl_transformation_h__
18#define __gui_opengl_transformation_h__
19
20#include <iostream>
21
22#include "math/least_squares.h"
23#include "gui/opengl/gl.h"
24
25namespace MR
26{
27 namespace GUI
28 {
29 namespace GL
30 {
31
32
33
34
35 class vec4 { MEMALIGN(vec4)
36 public:
37 vec4 () { }
38 vec4 (float x, float y, float z, float w) { v[0] = x; v[1] = y; v[2] = z; v[3] = w; }
39 vec4 (const Eigen::Quaternionf& V) { v[0] = V.x(); v[1] = V.y(); v[2] = V.z(); v[3] = V.w(); }
40 template <class Cont>
41 vec4 (const Cont& p, float w) { v[0] = p[0]; v[1] = p[1]; v[2] = p[2]; v[3] = w; }
42 vec4 (const float* p) { memcpy (v, p, sizeof(v)); }
43
44 void zero () {
45 memset (v, 0, sizeof (v));
46 }
47
48 operator const GLfloat* () const { return v; }
49 operator GLfloat* () { return v; }
50
51 friend std::ostream& operator<< (std::ostream& stream, const vec4& v) {
52 for (size_t i = 0; i < 4; ++i)
53 stream << v[i] << " ";
54 return stream;
55 }
56
57 protected:
58 GLfloat v[4];
59 };
60
61
62
63
64
65 class mat4 { MEMALIGN(mat4)
66 public:
67 mat4 () { }
68 mat4 (const mat4& a) { memcpy (m, a.m, sizeof(m)); }
69 mat4 (const float* p) { memcpy (m, p, sizeof(m)); }
70 mat4 (const Eigen::Quaternionf& v)
71 {
72 const auto R = v.matrix();
73 zero();
74 for (size_t i = 0; i != 3; ++i) {
75 for (size_t j = 0; j != 3; ++j)
76 (*this)(i,j) = R(i,j);
77 }
78 (*this)(3,3) = 1.0f;
79 }
80 template <class M>
81 mat4 (const M& a)
82 {
83 for (size_t i = 0; i != size_t(a.rows()); ++i) {
84 for (size_t j = 0; j != 4; ++j)
85 (*this)(i,j) = a(i,j);
86 }
87 if (a.rows() == 3) {
88 (*this)(3,0) = (*this)(3,1) = (*this)(3,2) = 0.0f;
89 (*this)(3,3) = 1.0f;
90 }
91 }
92
93 mat4& operator= (const mat4& a) { memcpy (m, a.m, sizeof(m)); return *this; }
94
95 void zero () {
96 memset (m, 0, sizeof (m));
97 }
98
99 operator const GLfloat* () const { return m; }
100 operator GLfloat* () { return m; }
101
102 GLfloat& operator() (size_t i, size_t j) { return m[i+4*j]; }
103 const GLfloat& operator() (size_t i, size_t j) const { return m[i+4*j]; }
104
105 mat4 operator* (const mat4& a) const {
106 mat4 t;
107 for (size_t j = 0; j < 4; ++j) {
108 for (size_t i = 0; i < 4; ++i) {
109 t(i,j) = 0.0f;
110 for (size_t k = 0; k < 4; ++k)
111 t(i,j) += (*this)(i,k) * a(k,j);
112
113 }
114 }
115 return t;
116 }
117
118 vec4 operator* (const vec4& v) const {
119 vec4 r;
120 r.zero();
121 for (size_t j = 0; j < 4; ++j)
122 for (size_t i = 0; i < 4; ++i)
123 r[i] += (*this)(i,j) * v[j];
124 return r;
125 }
126
127 mat4& operator*= (const mat4& a) {
128 *this = (*this) * a;
129 return *this;
130 }
131
132 friend std::ostream& operator<< (std::ostream& stream, const mat4& m) {
133 for (size_t i = 0; i < 4; ++i) {
134 for (size_t j = 0; j < 4; ++j)
135 stream << m(i,j) << " ";
136 stream << "\n";
137 }
138 return stream;
139 }
140
141
142 protected:
143 GLfloat m[16];
144 };
145
146
147
148
149 inline mat4 identity () {
150 mat4 m;
151 m.zero();
152 m(0,0) = m(1,1) = m(2,2) = m(3,3) = 1.0f;
153 return m;
154 }
155
156
157
158 inline mat4 transpose (const mat4& a)
159 {
160 mat4 b;
161 for (size_t j = 0; j < 4; ++j)
162 for (size_t i = 0; i < 4; ++i)
163 b(i,j) = a(j,i);
164 return b;
165 }
166
167
168
169
170
171 inline mat4 inv (const mat4& a)
172 {
173 Eigen::Matrix<float, 4, 4> A;
174 for (size_t i = 0; i != 4; ++i) {
175 for (size_t j = 0; j != 4; ++j)
176 A(i,j) = a(i,j);
177 }
178 return A.inverse().eval();
179 }
180
181
182
183 inline mat4 ortho (float L, float R, float B, float T, float N, float F)
184 {
185 mat4 m;
186 m.zero();
187 m(0,0) = 2.0f/(R-L);
188 m(1,1) = 2.0f/(T-B);
189 m(2,2) = 2.0f/(N-F);
190 m(3,3) = 1.0f;
191
192 m(0,3) = (R+L)/(R-L);
193 m(1,3) = (T+B)/(T-B);
194 m(2,3) = (F+N)/(F-N);
195
196 return m;
197 }
198
199
200
201 inline mat4 frustum (float L, float R, float B, float T, float N, float F)
202 {
203 mat4 m;
204 m.zero();
205
206 m(0,0) = 2.0f*N/(R-L);
207 m(1,1) = 2.0f*N/(T-B);
208 m(0,2) = (R+L)/(R-L);
209 m(1,2) = (T+B)/(T-B);
210 m(2,2) = (F+N)/(N-F);
211 m(3,2) = -1.0f;
212 m(2,3) = 2.0f*F*N/(N-F);
213
214 return m;
215 }
216
217
218 inline mat4 translate (float x, float y, float z)
219 {
220 mat4 m = identity();
221 m(0,3) = x;
222 m(1,3) = y;
223 m(2,3) = z;
224 m(3,3) = 1.0f;
225 return m;
226 }
227
228 template <class Cont>
229 inline mat4 translate (const Cont& x)
230 {
231 return translate (x[0], x[1], x[2]);
232 }
233
234
235 inline mat4 scale (float x, float y, float z)
236 {
237 mat4 m;
238 m.zero();
239 m(0,0) = x;
240 m(1,1) = y;
241 m(2,2) = z;
242 m(3,3) = 1.0f;
243 return m;
244 }
245
246 inline mat4 scale (float s) { return scale (s,s,s); }
247
248 }
249 }
250}
251
252#endif
253
friend std::ostream & operator<<(std::ostream &stream, const mat4 &m)
friend std::ostream & operator<<(std::ostream &stream, const vec4 &v)
mat4 ortho(float L, float R, float B, float T, float N, float F)
mat4 inv(const mat4 &a)
mat4 frustum(float L, float R, float B, float T, float N, float F)
mat4 scale(float x, float y, float z)
mat4 transpose(const mat4 &a)
mat4 translate(float x, float y, float z)
Definition: base.h:24
Eigen::MatrixXd R