ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
CameraInteractorLogic.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  : RotationInteractorLogic(c, min_far_plane), fov_at_mouse_down_(60.0) {}
16 
18  Super::SetBoundingBox(bounds);
19  // Initialize parent's matrix_ (in case we do a mouse wheel, which
20  // doesn't involve a mouse down) and the center of rotation.
22  bounds.GetCenter().cast<float>());
23 }
24 
25 void CameraInteractorLogic::Rotate(int dx, int dy) {
26  Super::Rotate(dx, dy);
28 }
29 
30 void CameraInteractorLogic::RotateZ(int dx, int dy) {
31  Super::RotateZ(dx, dy);
33 }
34 
35 void CameraInteractorLogic::RotateFly(int dx, int dy) {
36  // Fly/first-person shooter rotation is always about the current camera
37  // matrix, and the camera's position, so we need to update Super's
38  // matrix information.
40  Super::Rotate(-dx, -dy);
42 }
43 
45  // Parent's matrix_ may not have been set yet
46  if (type != DragType::MOUSE) {
48  }
49  Super::Dolly(dy, type);
50 }
51 
52 void CameraInteractorLogic::Dolly(float z_dist, Camera::Transform matrix_in) {
53  Super::Dolly(z_dist, matrix_in);
54  auto matrix = GetMatrix();
55  camera_->SetModelMatrix(matrix);
56 
58 }
59 
60 void CameraInteractorLogic::Pan(int dx, int dy) {
61  Super::Pan(dx, dy);
63 }
64 
66  const Eigen::Vector3f& axis) {
67  auto model_matrix = camera_->GetModelMatrix(); // copy
68  model_matrix.rotate(Eigen::AngleAxis<float>(angle_rad, axis));
69  camera_->SetModelMatrix(model_matrix);
70 }
71 
72 void CameraInteractorLogic::MoveLocal(const Eigen::Vector3f& v) {
73  auto model_matrix = camera_->GetModelMatrix(); // copy
74  model_matrix.translate(v);
75  camera_->SetModelMatrix(model_matrix);
76 }
77 
78 void CameraInteractorLogic::Zoom(int dy, DragType drag_type) {
79  float d_fov = 0.0f; // initialize to make GCC happy
80  switch (drag_type) {
81  case DragType::MOUSE:
82  d_fov = float(-dy) * 0.1f; // deg
83  break;
85  d_fov = float(dy) * 0.2f; // deg
86  break;
87  case DragType::WHEEL: // actual mouse wheel, same as two-fingers
88  d_fov = float(dy) * 2.0f; // deg
89  break;
90  }
91  float old_fov = 0.0f;
92  if (drag_type == DragType::MOUSE) {
93  old_fov = float(fov_at_mouse_down_);
94  } else {
95  old_fov = float(camera_->GetFieldOfView());
96  }
97  float new_fov = old_fov + d_fov;
98  new_fov = std::max(5.0f, new_fov);
99  new_fov = std::min(90.0f, new_fov);
100 
101  float to_radians = float(M_PI / 180.0);
102  float near_v = float(camera_->GetNear());
103  Eigen::Vector3f camera_pos, cor;
104  if (drag_type == DragType::MOUSE) {
105  camera_pos = matrix_at_mouse_down_.translation();
107  } else {
108  camera_pos = camera_->GetPosition();
109  cor = center_of_rotation_;
110  }
111  Eigen::Vector3f to_cor = cor - camera_pos;
112  float old_dist_from_plane_to_cor = to_cor.norm() - near_v;
113  float new_dist_from_plane_to_cor =
114  (near_v + old_dist_from_plane_to_cor) *
115  std::tan(old_fov / 2.0f * to_radians) /
116  std::tan(new_fov / 2.0f * to_radians) -
117  near_v;
118  if (drag_type == DragType::MOUSE) {
119  Dolly(-(new_dist_from_plane_to_cor - old_dist_from_plane_to_cor),
121  } else {
122  Dolly(-(new_dist_from_plane_to_cor - old_dist_from_plane_to_cor),
124  }
125 
126  float aspect = 1.0f;
127  if (view_height_ > 0) {
128  aspect = float(view_width_) / float(view_height_);
129  }
130  camera_->SetProjection(new_fov, aspect, camera_->GetNear(),
132 }
133 
136  fov_at_mouse_down_ = camera_->GetFieldOfView();
137 }
138 
140 
142 
144 
145 } // namespace rendering
146 } // namespace visualization
147 } // namespace cloudViewer
constexpr double M_PI
Pi.
Definition: CVConst.h:19
char type
Bounding box structure.
Definition: ecvBBox.h:25
virtual Eigen::Vector3d GetCenter() const override
Returns the center of the geometry coordinates.
Definition: ecvBBox.h:87
void RotateLocal(float angle_rad, const Eigen::Vector3f &axis)
void Zoom(int dy, DragType drag_type)
Sets camera field of view.
void RotateZ(int dx, int dy) override
Rotates about the forward axis of the matrix.
Eigen::Transform< float, 3, Eigen::Affine > Transform
Definition: Camera.h:29
virtual void SetModelMatrix(const Transform &view)=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 FovType GetFieldOfViewType() 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
void SetMouseDownInfo(const Camera::Transform &matrix, const Eigen::Vector3f &center_of_rotation)
virtual void RotateZ(int dx, int dy)
Rotates about the forward axis of the matrix.
int min(int a, int b)
Definition: cutil_math.h:53
int max(int a, int b)
Definition: cutil_math.h:48
Generic file read and write utility for python interface.