ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Camera.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 #include <ecvBBox.h>
11 
12 namespace cloudViewer {
13 namespace visualization {
14 namespace rendering {
15 
16 static const double NEAR_PLANE = 0.1;
17 static const double MIN_FAR_PLANE = 1.0;
18 
19 void Camera::FromExtrinsics(const Eigen::Matrix4d& extrinsic) {
20  // The intrinsic * extrinsic matrix models projection from the world through
21  // a pinhole onto the projection plane. The instrinsic matrix is the
22  // projection matrix, and extrinsic.inverse() is the camera pose. But the
23  // OpenGL camera has the projection plane in front of the camera, which
24  // essentially inverts all the axes of the projection. (Pinhole camera
25  // images are flipped horizontally and vertically and the camera is the
26  // other direction.) But the extrinsic matrix is left-handed, so we also
27  // need to convert to OpenGL's right-handed matrices.
28  Eigen::Matrix4d toGLCamera;
29  toGLCamera << 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0,
30  0.0, 0.0, 0.0, 1.0;
31  Eigen::Matrix4f m = (extrinsic.inverse() * toGLCamera).cast<float>();
33 }
34 
36  const Eigen::Matrix3d& intrinsic,
37  const Eigen::Matrix4d& extrinsic,
38  int intrinsic_width_px,
39  int intrinsic_height_px,
40  const ccBBox& scene_bounds) {
41  camera.FromExtrinsics(extrinsic);
42  camera.SetProjection(intrinsic, NEAR_PLANE,
43  CalcFarPlane(camera, scene_bounds), intrinsic_width_px,
44  intrinsic_height_px);
45 }
46 
47 float Camera::CalcNearPlane() { return NEAR_PLANE; }
48 
50  const ccBBox& scene_bounds) {
51  // The far plane needs to be the max absolute distance, not just the
52  // max extent, so that axes are visible if requested.
53  // See also RotationInteractorLogic::UpdateCameraFarPlane().
54  auto far1 = scene_bounds.GetMinBound().norm();
55  auto far2 = scene_bounds.GetMaxBound().norm();
56  auto far3 = camera.GetModelMatrix().translation().cast<double>().norm();
57  auto model_size = 2.0 * scene_bounds.GetExtent().norm();
58  auto far_v = std::max(MIN_FAR_PLANE,
59  std::max(std::max(far1, far2), far3) + model_size);
60  return far_v;
61 }
62 
63 } // namespace rendering
64 } // namespace visualization
65 } // namespace cloudViewer
Bounding box structure.
Definition: ecvBBox.h:25
virtual Eigen::Vector3d GetMaxBound() const override
Returns max bounds for geometry coordinates.
Definition: ecvBBox.h:84
Eigen::Vector3d GetExtent() const
Get the extent/length of the bounding box in x, y, and z dimension.
Definition: ecvBBox.h:147
virtual Eigen::Vector3d GetMinBound() const override
Returns min bounds for geometry coordinates.
Definition: ecvBBox.h:81
Eigen::Transform< float, 3, Eigen::Affine > Transform
Definition: Camera.h:29
virtual void SetModelMatrix(const Transform &view)=0
virtual void FromExtrinsics(const Eigen::Matrix4d &extrinsics)
Definition: Camera.cpp:19
virtual Transform GetModelMatrix() const =0
static void SetupCameraAsPinholeCamera(rendering::Camera &camera, const Eigen::Matrix3d &intrinsic, const Eigen::Matrix4d &extrinsic, int intrinsic_width_px, int intrinsic_height_px, const ccBBox &scene_bounds)
Definition: Camera.cpp:35
static float CalcNearPlane()
Returns a good value for the near plane.
Definition: Camera.cpp:47
virtual void SetProjection(double fov, double aspect, double near, double far, FovType fov_type)=0
static float CalcFarPlane(const rendering::Camera &camera, const ccBBox &scene_bounds)
Definition: Camera.cpp:49
int max(int a, int b)
Definition: cutil_math.h:48
static const double MIN_FAR_PLANE
Definition: Camera.cpp:17
static const double NEAR_PLANE
Definition: Camera.cpp:16
Generic file read and write utility for python interface.