MRPT  2.0.5
TRenderMatrices.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "opengl-precomp.h" // Precompiled header
11 
12 #include <mrpt/math/geometry.h> // crossProduct3D()
13 #include <mrpt/math/ops_containers.h> // dotProduct()
15 #include <Eigen/Dense>
16 
17 using namespace mrpt::opengl;
18 
20  float left, float right, float bottom, float top, float znear, float zfar)
21 {
22  ASSERT_ABOVE_(zfar, znear);
23 
25 
26  p_matrix(0, 0) = 2.0f / (right - left);
27  p_matrix(1, 1) = 2.0f / (top - bottom);
28  p_matrix(2, 2) = -2.0f / (zfar - znear);
29  p_matrix(0, 3) = -(right + left) / (right - left);
30  p_matrix(1, 3) = -(top + bottom) / (top - bottom);
31  p_matrix(2, 3) = -(zfar + znear) / (zfar - znear);
32 }
33 
34 // Replacement for obsolete: gluPerspective() and glOrtho()
35 void TRenderMatrices::computeProjectionMatrix(float znear, float zfar)
36 {
37  ASSERT_ABOVE_(FOV, .0f);
38  ASSERT_ABOVE_(zfar, znear);
39  ASSERT_ABOVE_(zfar, .0f);
40  ASSERT_ABOVEEQ_(znear, .0f);
41 
42  if (is_projective)
43  {
44  // Was: gluPerspective()
45  // Based on GLM's perspective (MIT license).
46 
47  const float aspect = viewport_width / (1.0f * viewport_height);
49  std::abs(aspect - std::numeric_limits<float>::epsilon()), .0f);
50 
51  const float f = 1.0f / std::tan(mrpt::DEG2RAD(FOV) / 2.0f);
52 
53  p_matrix.setZero();
54 
55  p_matrix(0, 0) = f / aspect;
56  p_matrix(1, 1) = f;
57  p_matrix(2, 2) = -(zfar + znear) / (zfar - znear);
58  p_matrix(3, 2) = -1.0f;
59  p_matrix(2, 3) = -(2.0f * zfar * znear) / (zfar - znear);
60  }
61  else
62  {
63  // Was:
64  // glOrtho(-Ax, Ax, -Ay, Ay, -0.5 * m_clip_max, 0.5 * m_clip_max);
65 
66  const float ratio = viewport_width / (1.0f * viewport_height);
67  float Ax = eyeDistance * 0.5f;
68  float Ay = eyeDistance * 0.5f;
69 
70  if (ratio > 1)
71  Ax *= ratio;
72  else
73  {
74  if (ratio != 0) Ay /= ratio;
75  }
76 
77  const auto left = -.5f * Ax, right = .5f * Ax;
78  const auto bottom = -.5f * Ay, top = .5f * Ay;
79  computeOrthoProjectionMatrix(left, right, bottom, top, znear, zfar);
80  }
81 }
82 
83 // Replacement for deprecated OpenGL gluLookAt():
85 {
87 
88  // Note: Use double instead of float to avoid numerical innacuracies that
89  // are really noticeable with the naked eye when elevation is close to 90
90  // deg (!)
91  TVector3D forward = TVector3D(pointing - eye);
92  const double fn = forward.norm();
93  ASSERT_(fn != 0);
94  forward *= 1.0 / fn;
95 
96  // Side = forward x up
97  TVector3D side = mrpt::math::crossProduct3D(forward, up);
98  const double sn = side.norm();
99  ASSERT_(sn != 0);
100  side *= 1.0 / sn;
101 
102  // Recompute up as: up = side x forward
103  const TVector3D up2 = mrpt::math::crossProduct3D(side, forward);
104 
105  // s.x s.y s.z -dot(s, eye)
106  // u.x u.y u.z -dot(u, eye)
107  // -f.x -f.y -f.z dot(up, eye)
108  // 0 0 0 1
109 
111  // Axis X:
112  m(0, 0) = d2f(side[0]);
113  m(0, 1) = d2f(side[1]);
114  m(0, 2) = d2f(side[2]);
115  // Axis Y:
116  m(1, 0) = d2f(up2[0]);
117  m(1, 1) = d2f(up2[1]);
118  m(1, 2) = d2f(up2[2]);
119  // Axis Z:
120  m(2, 0) = d2f(-forward[0]);
121  m(2, 1) = d2f(-forward[1]);
122  m(2, 2) = d2f(-forward[2]);
123  // Translation:
124  m(0, 3) = d2f(-mrpt::math::dotProduct<3, double>(side, eye));
125  m(1, 3) = d2f(-mrpt::math::dotProduct<3, double>(up2, eye));
126  m(2, 3) = d2f(mrpt::math::dotProduct<3, double>(forward, eye));
127  // Last row:
128  m(3, 0) = .0f;
129  m(3, 1) = .0f;
130  m(3, 2) = .0f;
131  m(3, 3) = 1.f;
132 
133  // Homogeneous matrices composition:
134  // Overwrite projection matrix:
136 }
137 
139  float x, float y, float z, float& proj_u, float& proj_v,
140  float& proj_z_depth) const
141 {
143  pmv_matrix.asEigen() *
145  proj_u = proj[3] ? proj[0] / proj[3] : 0;
146  proj_v = proj[3] ? proj[1] / proj[3] : 0;
147  proj_z_depth = proj[2];
148 }
149 
151  float x, float y, float z, float& proj_u_px, float& proj_v_px,
152  float& proj_depth) const
153 {
154  projectPoint(x, y, z, proj_u_px, proj_v_px, proj_depth);
155  proj_u_px = (proj_u_px + 1.0f) * (viewport_width * 0.5f);
156  proj_v_px = (proj_v_px + 1.0f) * (viewport_height * 0.5f);
157 }
mrpt::math::TPoint3D up
Up vector of the camera.
This file implements several operations that operate element-wise on individual or pairs of container...
void crossProduct3D(const T &v0, const U &v1, V &vOut)
Computes the cross product of two 3D vectors, returning a vector normal to both.
Definition: geometry.h:765
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:120
float d2f(const double d)
shortcut for static_cast<float>(double)
void computeProjectionMatrix(float zmin, float zmax)
Uses is_projective , vw,vh, etc.
mrpt::math::CMatrixFloat44 pmv_matrix
Result of p_matrix * mv_matrix.
void projectPointPixels(float x, float y, float z, float &proj_u_px, float &proj_v_px, float &proj_depth) const
Projects a point from global world coordinates into (u,v) pixel coordinates.
void applyLookAt()
Updates the current p_matrix such that it "looks at" pointing, with up vector "up".
constexpr double DEG2RAD(const double x)
Degrees to radians.
#define ASSERT_ABOVEEQ_(__A, __B)
Definition: exceptions.h:167
void computeOrthoProjectionMatrix(float left, float right, float bottom, float top, float znear, float zfar)
Especial case for custom parameters of Orthographic projection.
TPoint3D TVector3D
Useful type alias for 3-vectors.
Definition: TPoint3D.h:273
size_t viewport_width
In pixels.
mrpt::math::TPoint3D eye
The camera is here.
#define ASSERT_ABOVE_(__A, __B)
Definition: exceptions.h:155
void projectPoint(float x, float y, float z, float &proj_u, float &proj_v, float &proj_z_depth) const
Computes the normalized coordinates (range=[0,1]) on the current rendering viewport of a point with l...
mrpt::math::TPoint3D pointing
The camera points to here.
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:13
EIGEN_MAP asEigen()
Get as an Eigen-compatible Eigen::Map object.
Definition: CMatrixFixed.h:251
double FOV
Vertical FOV in degrees.
mrpt::math::CMatrixFloat44 p_matrix
Projection matrix, computed by renderNormalScene() from all the parameters above. ...
bool is_projective
true: projective, false: ortho



Page generated by Doxygen 1.8.14 for MRPT 2.0.5 Git: 40e60e732 Thu Jul 9 08:38:35 2020 +0200 at jue jul 9 08:45:11 CEST 2020