ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ecvViewportParameters.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 // CV_CORE_LIB
11 #include <CVConst.h>
12 
13 // Qt
14 #include <QRect>
15 
17  : defaultPointSize(1),
18  defaultLineWidth(1),
19  pixelSize(1.0f),
20  zoom(1.0f),
21  perspectiveView(false),
22  objectCenteredView(true),
23  zNearCoef(0.005),
24  zNear(0),
25  zFar(0),
26  focal(0, 0, 0),
27  up(0, 0, 0),
28  fov_deg(50.0f),
29  cameraAspectRatio(1.0f),
30  focalDistance(1.0),
31  pivotPoint(0, 0, 0),
32  cameraCenter(0, 0, focalDistance) {
34 }
35 
37  const ecvViewportParameters& params)
38  : viewMat(params.viewMat),
39  defaultPointSize(params.defaultPointSize),
40  defaultLineWidth(params.defaultLineWidth),
41  pixelSize(params.pixelSize),
42  zoom(params.zoom),
43  perspectiveView(params.perspectiveView),
44  objectCenteredView(params.objectCenteredView),
45  zNearCoef(params.zNearCoef),
46  zNear(params.zNear),
47  zFar(params.zFar),
48  focal(params.focal),
49  up(params.up),
50  fov_deg(params.fov_deg),
51  cameraAspectRatio(params.cameraAspectRatio),
52  focalDistance(params.focalDistance),
53  pivotPoint(params.pivotPoint),
54  cameraCenter(params.cameraCenter) {}
55 
56 bool ecvViewportParameters::toFile(QFile& out, short dataVersion) const {
57  if (dataVersion < 20) {
58  assert(false);
59  return false;
60  }
61 
62  // base modelview matrix (dataVersion>=20)
63  if (!viewMat.toFile(out, dataVersion)) return false;
64 
65  // other parameters (dataVersion>=20)
66  QDataStream outStream(&out);
67  outStream << pixelSize;
68  outStream << zoom;
69  outStream << focalDistance;
70  outStream << defaultPointSize;
71  outStream << defaultLineWidth;
72  outStream << perspectiveView;
73  outStream << objectCenteredView;
74  outStream << pivotPoint.x;
75  outStream << pivotPoint.y;
76  outStream << pivotPoint.z;
77  outStream << cameraCenter.x;
78  outStream << cameraCenter.y;
79  outStream << cameraCenter.z;
80  outStream << focal.x;
81  outStream << focal.y;
82  outStream << focal.z;
83  outStream << up.x;
84  outStream << up.y;
85  outStream << up.z;
86  outStream << fov_deg;
87  outStream << cameraAspectRatio;
88 
89  return true;
90 }
91 
93  // Version 36 introduced double precision for camera matrix
94  return std::max(static_cast<short>(36), viewMat.minimumFileVersion());
95 }
96 
98  short dataVersion,
99  int flags,
100  LoadedIDMap& oldToNewIDMap) {
101  // base modelview matrix (dataVersion>=20)
102  if (dataVersion >= 36) // we now save the camera matrix in double precision
103  {
104  if (!viewMat.fromFile(in, dataVersion, flags, oldToNewIDMap))
105  return false;
106  } else {
107  // camera matrix was saved in standard (float) precision
108  ccGLMatrix _viewMat;
109  if (!_viewMat.fromFile(in, dataVersion, flags, oldToNewIDMap))
110  return false;
111  viewMat = ccGLMatrixd(_viewMat.data());
112  }
113 
114  // other parameters (dataVersion>=20)
115  QDataStream inStream(&in);
116  inStream >> pixelSize;
117  // before version 25, we were saving the inverse of 'pixelSize'
118  // ('globalZoom')
119  if (dataVersion < 25)
120  pixelSize = (pixelSize > ZERO_TOLERANCE_F ? 1.0f / pixelSize : 1.0f);
121 
122  inStream >> zoom;
123  inStream >> focalDistance;
124  inStream >> defaultPointSize;
125  inStream >> defaultLineWidth;
126  inStream >> perspectiveView;
127  inStream >> objectCenteredView;
128  if (dataVersion >= 36) // we now save the camera center and pivot point in
129  // double precision
130  {
131  inStream >> pivotPoint.x;
132  inStream >> pivotPoint.y;
133  inStream >> pivotPoint.z;
134  inStream >> cameraCenter.x;
135  inStream >> cameraCenter.y;
136  inStream >> cameraCenter.z;
137  inStream >> focal.x;
138  inStream >> focal.y;
139  inStream >> focal.z;
140  inStream >> up.x;
141  inStream >> up.y;
142  inStream >> up.z;
143  } else {
144  CCVector3 _pivotPoint;
146  _pivotPoint.u, 3);
147  pivotPoint = CCVector3d::fromArray(_pivotPoint.u);
148  if (dataVersion >= 25) // after version 25 the camera center is saved
149  // as a separate point!
150  {
151  CCVector3 _cameraCenter;
153  _cameraCenter.u, 3);
154  cameraCenter = CCVector3d::fromArray(_cameraCenter.u);
155  } else {
156  // FIXME: doesn't work in object-centered perspective!
158  }
159  }
160 
161  inStream >> fov_deg;
162  inStream >> cameraAspectRatio;
163  if (dataVersion < 25) // screenPan has been replaced by cameraCenter(x,y)
164  // in object centered mode!
165  {
166  float screenPan[2];
167  inStream >> screenPan[0];
168  inStream >> screenPan[1];
169 
170  if (objectCenteredView) {
171  cameraCenter.x += static_cast<double>(screenPan[0]);
172  cameraCenter.y += static_cast<double>(screenPan[1]);
173  }
174  }
175 
176  if (dataVersion >= 30 && dataVersion < 48) {
177  // ortho mode aspect ratio (30 >= dataVersion < 48)
178  float orthoAspectRatio = 0.0f;
179  inStream >> orthoAspectRatio;
180  }
181 
182  // for older version, deduce the focal distance from the old paramters
183  // (pixelSize and zoom)
184  if (dataVersion < 48 && zoom != 1.0f) {
185  if (perspectiveView) {
186  focalDistance = (cameraCenter - pivotPoint).normd();
187  } else {
188  focalDistance =
189  pixelSize * 2048 /
190  computeDistanceToWidthRatio(); // 2048 = average screen
191  // size? Sadly we don't have
192  // this information
193  }
196  "[ecvViewportParameters] Approximate focal distance (sorry, "
197  "the parameters of viewport objects have changed!)");
198  }
199 
200  return true;
201 }
202 
204  assert(i >= 0 && i <= iMax);
205  return pow(10, -static_cast<double>((iMax - i) * 3) /
206  iMax); // between 10^-3 and 1
207 }
208 
210  assert(coef >= 0 && coef <= 1.0);
211  double id = -(iMax / 3.0) * log10(coef);
212  int i = static_cast<int>(id);
213  // cope with numerical inaccuracies
214  if (std::abs(id - i) > std::abs(id - (i + 1))) {
215  ++i;
216  }
217  assert(i >= 0 && i <= iMax);
218  return iMax - i;
219 }
220 
223 }
224 
226  ccGLMatrixd viewMatd;
227  viewMatd.toIdentity();
228 
229  const CCVector3d& rotationCenter = getRotationCenter();
230 
231  // place origin on rotation center
232  viewMatd.setTranslation(
233  /*viewMatd.getTranslationAsVec3D()*/
234  -rotationCenter); // viewMatd.getTranslationAsVec3D()
235  // = (0, 0,
236  // 0)
237 
238  // rotation (viewMat is simply a rotation matrix)
239  viewMatd = viewMat * viewMatd;
240 
241  // go back to initial origin, then place origin on camera center
242  viewMatd.setTranslation(viewMatd.getTranslationAsVec3D() + rotationCenter -
243  cameraCenter);
244 
245  return viewMatd;
246 }
247 
249  const QRect& glViewport) const {
250  ccGLMatrixd scaleMatd;
251  scaleMatd.toIdentity();
252 
253  // for proper aspect ratio handling
254  if (glViewport.height() != 0) {
255  double ar = static_cast<double>(
256  glViewport.width() / (glViewport.height() * cameraAspectRatio));
257  if (ar < 1.0) {
258  // glScalef(ar, ar, 1.0);
259  scaleMatd.data()[0] = ar;
260  scaleMatd.data()[5] = ar;
261  }
262  }
263 
264  return scaleMatd;
265 }
266 
268  // view direction is (the opposite of) the 3rd line of the current view
269  // matrix
270  const double* M = viewMat.data();
271  CCVector3d axis(-M[2], -M[6], -M[10]);
272  axis.normalize();
273 
274  return axis;
275 }
276 
278  // up direction is the 2nd line of the current view matrix
279  const double* M = viewMat.data();
280  CCVector3d axis(M[1], M[5], M[9]);
281  axis.normalize();
282 
283  return axis;
284 }
285 
287  bool autoUpdateFocal) {
288  pivotPoint = P;
289  if (autoUpdateFocal && objectCenteredView) {
290  // update focal distance accordingly
292  }
293 }
294 
296  bool autoUpdateFocal) {
297  cameraCenter = C;
298  if (autoUpdateFocal && objectCenteredView) {
299  // update focal distance accordingly
301  }
302 }
303 
306 
307  if (objectCenteredView) {
309  }
310 }
311 
313  return std::tan(
314  static_cast<double>(cloudViewer::DegreesToRadians(fov_deg / 2.0f)));
315 }
316 
318  return 2.0 * computeDistanceToHalfWidthRatio();
319 }
320 
323 }
324 
325 double ecvViewportParameters::computePixelSize(int glWidth) const {
326  return (glWidth > 0 ? computeWidthAtFocalDist() / glWidth : 1.0);
327 }
constexpr float ZERO_TOLERANCE_F
Definition: CVConst.h:43
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Definition: CVLog.cpp:133
Type y
Definition: CVGeom.h:137
Type u[3]
Definition: CVGeom.h:139
Type x
Definition: CVGeom.h:137
Type z
Definition: CVGeom.h:137
void normalize()
Sets vector norm to unity.
Definition: CVGeom.h:428
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
Definition: CVGeom.h:268
Vector3Tpl< T > getTranslationAsVec3D() const
Returns a copy of the translation as a CCVector3.
bool fromFile(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads data from binary stream.
T * data()
Returns a pointer to internal data.
bool toFile(QFile &out, short dataVersion) const override
Saves data to binary stream.
void setTranslation(const Vector3Tpl< float > &Tr)
Sets translation (float version)
short minimumFileVersion() const override
Returns the minimum file version required to save this instance.
virtual void toIdentity()
Sets matrix to identity.
Float version of ccGLMatrixTpl.
Definition: ecvGLMatrix.h:19
Double version of ccGLMatrixTpl.
Definition: ecvGLMatrix.h:56
QMultiMap< unsigned, unsigned > LoadedIDMap
Map of loaded unique IDs (old ID --> new ID)
static void CoordsFromDataStream(QDataStream &stream, int flags, PointCoordinateType *out, unsigned count=1)
Standard parameters for GL displays/viewports.
static int ZNearCoefToIncrement(double coef, int iMax)
float defaultLineWidth
Line width.
const CCVector3d & getRotationCenter() const
Returns the view rotation 'center'.
bool perspectiveView
Perspective view state.
float fov_deg
Camera F.O.V. (field of view) in degrees.
CCVector3d getViewDir() const
Returns the viewing direction.
static double IncrementToZNearCoef(int i, int iMax)
float pixelSize
Current pixel size (in 'current unit'/pixel)
CCVector3d cameraCenter
Camera center.
double computeWidthAtFocalDist() const
Computes the object 'width' at the 'focal' distance.
double focalDistance
Focal distance.
double computePixelSize(int glWidth) const
Computes the pixel size at the 'focal' distance.
float cameraAspectRatio
Camera aspect ratio.
ecvViewportParameters()
Default constructor.
ccGLMatrixd computeViewMatrix() const
Computes the view matrix.
double getFocalDistance() const
Computes the 'focal' distance.
bool toFile(QFile &out, short dataVersion) const override
Saves data to binary stream.
short minimumFileVersion() const override
Returns the minimum file version required to save this instance.
float defaultPointSize
Point size.
void setPivotPoint(const CCVector3d &P, bool autoUpdateFocal=true)
Sets the pivot point (for object-centered view mode)
double computeDistanceToHalfWidthRatio() const
Computes the ratio 'distance to half width' (based on the current FOV)
ccGLMatrixd viewMat
Visualization matrix (rotation only)
void setCameraCenter(const CCVector3d &C, bool autoUpdateFocal=true)
Sets the camera center.
ccGLMatrixd computeScaleMatrix(const QRect &glViewport) const
Computes the scale matrix.
double computeDistanceToWidthRatio() const
Computes the ratio 'distance to width' (based on the current FOV)
bool fromFile(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads data from binary stream.
CCVector3d pivotPoint
Rotation pivot point (for object-centered view modes)
void setFocalDistance(double distance)
Sets the 'focal' distance.
CCVector3d getUpDir() const
Returns the up direction.
static double distance(T *pot1, T *pot2)
Definition: utils.h:111
float DegreesToRadians(int degrees)
Convert degrees to radians.
Definition: CVMath.h:98