ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
RotationInteractorLogic.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 namespace cloudViewer {
11 namespace visualization {
12 namespace rendering {
13 
15  double min_far_plane)
16  : min_far_plane_(min_far_plane), camera_(camera) {}
17 
19 
21  const Eigen::Vector3f& center) {
22  center_of_rotation_ = center;
23 }
24 
25 void RotationInteractorLogic::Pan(int dx, int dy) {
26  Eigen::Vector3f world_move = CalcPanVectorWorld(dx, dy);
28 
29  auto matrix = matrix_at_mouse_down_; // copy
30  // matrix.translate(cameraLocalMove) would work if
31  // matrix == camara matrix. Since it isn't necessarily true,
32  // we need to translate the position of the matrix in the world
33  // coordinate system.
34  Eigen::Vector3f new_trans = matrix.translation() + world_move;
35  matrix.fromPositionOrientationScale(new_trans, matrix.rotation(),
36  Eigen::Vector3f(1, 1, 1));
37  SetMatrix(matrix);
38 }
39 
40 Eigen::Vector3f RotationInteractorLogic::CalcPanVectorWorld(int dx, int dy) {
41  // Calculate the depth to the pixel we clicked on, so that we
42  // can compensate for perspective and have the mouse stays on
43  // that location. Unfortunately, we don't really have access to
44  // the depth buffer with Filament, so we'll fake it by finding
45  // the depth of the center of rotation.
46  auto pos = camera_->GetPosition();
47  auto forward = camera_->GetForwardVector();
48  float near_v = float(camera_->GetNear());
49  float dist = forward.dot(center_of_rotation_at_mouse_down_ - pos);
50  dist = std::max(near_v, dist);
51 
52  // How far is one pixel?
53  float half_fov = float(camera_->GetFieldOfView() / 2.0);
54  float hal_fov_radians = half_fov * float(M_PI / 180.0);
55  float units_at_dist = 2.0f * std::tan(hal_fov_radians) * (near_v + dist);
56  float units_per_px = units_at_dist / float(view_height_);
57 
58  // Move camera and center of rotation. Adjust values from the
59  // original positions at mousedown to avoid hysteresis problems.
60  // Note that the interactor's matrix may not be the same as the
61  // camera's matrix.
62  Eigen::Vector3f camera_local_move(-dx * units_per_px, dy * units_per_px, 0);
63  Eigen::Vector3f world_move =
64  camera_->GetModelMatrix().rotation() * camera_local_move;
65 
66  return world_move;
67 }
68 
71 }
72 
74 
76 
78  // Remember that the camera matrix is not necessarily the
79  // interactor's matrix.
80  // Also, the far plane needs to be able to show the
81  // axis if it is visible, so we need the far plane to include
82  // the origin.
84  auto proj = camera_->GetProjection();
85  if (proj.is_intrinsic) {
86  Eigen::Matrix3d intrinsic;
87  intrinsic << proj.proj.intrinsics.fx, 0.0, proj.proj.intrinsics.cx, 0.0,
88  proj.proj.intrinsics.fy, proj.proj.intrinsics.cy, 0.0, 0.0, 1.0;
89  camera_->SetProjection(intrinsic, proj.proj.intrinsics.near_plane,
90  far_v, proj.proj.intrinsics.width,
91  proj.proj.intrinsics.height);
92  } else if (proj.is_ortho) {
93  camera_->SetProjection(proj.proj.ortho.projection, proj.proj.ortho.left,
94  proj.proj.ortho.right, proj.proj.ortho.bottom,
95  proj.proj.ortho.top, proj.proj.ortho.near_plane,
96  far_v);
97  } else {
98  camera_->SetProjection(proj.proj.perspective.fov,
99  proj.proj.perspective.aspect,
100  proj.proj.perspective.near_plane, far_v,
101  proj.proj.perspective.fov_type);
102  }
103 }
104 
105 } // namespace rendering
106 } // namespace visualization
107 } // namespace cloudViewer
constexpr double M_PI
Pi.
Definition: CVConst.h:19
virtual const ProjectionInfo & GetProjection() const =0
virtual Eigen::Vector3f GetForwardVector() const =0
virtual Eigen::Vector3f GetPosition() const =0
virtual Transform GetModelMatrix() const =0
virtual double GetFieldOfView() const =0
only valid if fov was passed to SetProjection()
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
void SetMouseDownInfo(const Camera::Transform &matrix, const Eigen::Vector3f &center_of_rotation)
int max(int a, int b)
Definition: cutil_math.h:48
static double dist(double x1, double y1, double x2, double y2)
Definition: lsd.c:207
Generic file read and write utility for python interface.
struct cloudViewer::visualization::rendering::Camera::ProjectionInfo::@23::@26 intrinsics
union cloudViewer::visualization::rendering::Camera::ProjectionInfo::@23 proj