ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ViewControlWithCustomAnimation.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 <Helper.h>
11 #include <IJsonConvertibleIO.h>
12 #include <Logging.h>
13 
14 namespace cloudViewer {
15 namespace visualization {
16 
18  if (animation_mode_ == AnimationMode::FreeMode) {
20  }
21 }
22 
24  if (animation_mode_ == AnimationMode::FreeMode) {
25  if (!view_trajectory_.view_status_.empty()) {
26  // Once editing starts, lock ProjectionType.
27  // This is because ProjectionType cannot be easily switched in a
28  // smooth trajectory.
30  double old_fov = field_of_view_;
32  if (GetProjectionType() == ProjectionType::Orthogonal) {
33  field_of_view_ = old_fov;
34  }
35  } else {
36  // do nothing, lock as ProjectionType::Orthogonal
37  }
39  } else {
41  }
42  }
43 }
44 
46  if (animation_mode_ == AnimationMode::FreeMode) {
47  ViewControl::Scale(scale);
48  }
49 }
50 
52  double y,
53  double xo,
54  double yo) {
55  if (animation_mode_ == AnimationMode::FreeMode) {
56  ViewControl::Rotate(x, y, xo, yo);
57  }
58 }
59 
61  double y,
62  double xo,
63  double yo) {
64  if (animation_mode_ == AnimationMode::FreeMode) {
65  ViewControl::Translate(x, y, xo, yo);
66  }
67 }
68 
70  if (mode != AnimationMode::FreeMode &&
72  return;
73  }
74  animation_mode_ = mode;
75  switch (mode) {
76  case AnimationMode::PreviewMode:
77  case AnimationMode::PlayMode:
79  GoToFirst();
80  break;
81  case AnimationMode::FreeMode:
82  default:
83  break;
84  }
85 }
86 
88  if (animation_mode_ == AnimationMode::FreeMode) {
89  ViewParameters current_status;
90  ConvertToViewParameters(current_status);
91  if (view_trajectory_.view_status_.empty()) {
92  view_trajectory_.view_status_.push_back(current_status);
93  current_keyframe_ = 0.0;
94  } else {
95  size_t current_index = CurrentKeyframe();
97  view_trajectory_.view_status_.begin() + current_index + 1,
98  current_status);
99  current_keyframe_ = current_index + 1.0;
100  }
101  }
102 }
103 
105  if (animation_mode_ == AnimationMode::FreeMode &&
106  !view_trajectory_.view_status_.empty()) {
109  }
110 }
111 
113  if (animation_mode_ == AnimationMode::FreeMode &&
114  !view_trajectory_.view_status_.empty()) {
115  size_t current_index = CurrentKeyframe();
117  view_trajectory_.view_status_.begin() + current_index);
119  current_index - 1.0, view_trajectory_.view_status_.size(),
121  }
123 }
124 
126  /* = 20*/) {
127  if (animation_mode_ == AnimationMode::FreeMode) {
128  double radian_per_step = M_PI * 2.0 / double(num_of_key_frames);
129  for (int i = 0; i < num_of_key_frames; i++) {
130  ViewControl::Rotate(radian_per_step / ROTATION_RADIAN_PER_PIXEL, 0);
131  AddKeyFrame();
132  }
133  }
134 }
135 
137  std::string prefix;
138  switch (animation_mode_) {
139  case AnimationMode::FreeMode:
140  prefix = "Editing ";
141  break;
142  case AnimationMode::PreviewMode:
143  prefix = "Previewing ";
144  break;
145  case AnimationMode::PlayMode:
146  prefix = "Playing ";
147  break;
148  }
149  std::string buffer;
150  if (animation_mode_ == AnimationMode::FreeMode) {
151  if (view_trajectory_.view_status_.empty()) {
152  buffer = "empty trajectory";
153  } else {
154  buffer = fmt::format(
155  "#{} keyframe ({} in total{})",
156  (unsigned int)CurrentKeyframe() + 1,
157  (unsigned int)view_trajectory_.view_status_.size(),
158  view_trajectory_.is_loop_ ? ", looped" : "");
159  }
160  } else {
161  if (view_trajectory_.view_status_.empty()) {
162  buffer = "empty trajectory";
163  } else {
164  buffer = fmt::format(buffer, "#{} frame ({} in total{})",
165  (unsigned int)CurrentFrame() + 1,
166  (unsigned int)view_trajectory_.NumOfFrames(),
167  view_trajectory_.is_loop_ ? ", looped" : "");
168  }
169  }
170  return prefix + std::string(buffer);
171 }
172 
174  if (view_trajectory_.view_status_.empty()) {
175  return;
176  }
177  if (animation_mode_ == AnimationMode::FreeMode) {
178  current_keyframe_ += change;
182  } else {
183  current_frame_ += change;
187  }
189 }
190 
192  if (view_trajectory_.view_status_.empty()) {
193  return;
194  }
195  if (animation_mode_ == AnimationMode::FreeMode) {
196  current_keyframe_ = 0.0;
197  } else {
198  current_frame_ = 0.0;
199  }
201 }
202 
204  if (view_trajectory_.view_status_.empty()) {
205  return;
206  }
207  if (animation_mode_ == AnimationMode::FreeMode) {
209  } else {
211  }
213 }
214 
216  const std::string &filename /* = ""*/) {
217  if (view_trajectory_.view_status_.empty()) {
218  return false;
219  }
220  std::string json_filename = filename;
221  if (json_filename.empty()) {
222  json_filename =
223  "ViewTrajectory_" + utility::GetCurrentTimeStamp() + ".json";
224  }
225  utility::LogDebug("[Visualizer] Trejactory capture to {}",
226  json_filename.c_str());
227  return io::WriteIJsonConvertible(json_filename, view_trajectory_);
228 }
229 
231  const std::string &filename) {
233  if (!success) {
235  }
236  current_keyframe_ = 0.0;
237  current_frame_ = 0.0;
239  return success;
240 }
241 
243  const camera::PinholeCameraTrajectory &camera_trajectory) {
244  current_keyframe_ = 0.0;
245  current_frame_ = 0.0;
247  if (camera_trajectory.parameters_.empty()) {
248  return false;
249  }
251  view_trajectory_.is_loop_ = false;
252  view_trajectory_.view_status_.resize(camera_trajectory.parameters_.size());
253  for (size_t i = 0; i < camera_trajectory.parameters_.size(); i++) {
254  ViewControlWithCustomAnimation view_control = *this;
255  if (!view_control.ConvertFromPinholeCameraParameters(
256  camera_trajectory.parameters_[i])) {
258  return false;
259  }
260  if (!view_control.ConvertToViewParameters(
263  return false;
264  }
265  }
267  return true;
268 }
269 
271  if (view_trajectory_.view_status_.empty()) {
272  return false;
273  }
274  if (view_trajectory_.view_status_[0].field_of_view_ == FIELD_OF_VIEW_MIN) {
275  return false;
276  }
277  for (const auto &status : view_trajectory_.view_status_) {
278  if (status.field_of_view_ !=
279  view_trajectory_.view_status_[0].field_of_view_) {
280  return false;
281  }
282  }
283  return true;
284 }
285 
287  double current_frame, size_t num_of_frames, bool is_loop) {
288  if (num_of_frames == 0) {
289  return 0.0;
290  }
291  double frame_index = current_frame;
292  if (is_loop) {
293  while (int(round(frame_index)) < 0) {
294  frame_index += double(num_of_frames);
295  }
296  while (int(round(frame_index)) >= int(num_of_frames)) {
297  frame_index -= double(num_of_frames);
298  }
299  } else {
300  if (frame_index < 0.0) {
301  frame_index = 0.0;
302  }
303  if (frame_index > num_of_frames - 1.0) {
304  frame_index = num_of_frames - 1.0;
305  }
306  }
307  return frame_index;
308 }
309 
311  if (view_trajectory_.view_status_.empty()) {
312  return;
313  }
314  if (animation_mode_ == AnimationMode::FreeMode) {
317  } else {
318  bool success;
319  ViewParameters status;
320  std::tie(success, status) =
322  if (success) {
324  }
325  }
326 }
327 
328 } // namespace visualization
329 } // namespace cloudViewer
constexpr double M_PI
Pi.
Definition: CVConst.h:19
std::string filename
filament::Texture::InternalFormat format
std::vector< PinholeCameraParameters > parameters_
List of PinholeCameraParameters objects.
bool LoadTrajectoryFromCameraTrajectory(const camera::PinholeCameraTrajectory &camera_trajectory)
void Rotate(double x, double y, double xo, double yo) override
Function to process rotation.
double RegularizeFrameIndex(double current_frame, size_t num_of_frames, bool is_loop)
void Translate(double x, double y, double xo, double yo) override
Function to process translation.
bool ConvertFromViewParameters(const ViewParameters &status)
Definition: ViewControl.cpp:97
ProjectionType GetProjectionType() const
virtual void Translate(double x, double y, double xo=0.0, double yo=0.0)
Function to process translation.
virtual void Rotate(double x, double y, double xo=0.0, double yo=0.0)
Function to process rotation.
virtual void ChangeFieldOfView(double step)
bool ConvertFromPinholeCameraParameters(const camera::PinholeCameraParameters &parameters, bool allow_arbitrary=false)
virtual void Scale(double scale)
static const double ROTATION_RADIAN_PER_PIXEL
Definition: ViewControl.h:37
bool ConvertToViewParameters(ViewParameters &status) const
Function to get equivalent view parameters (support orthogonal)
Definition: ViewControl.cpp:86
std::tuple< bool, ViewParameters > GetInterpolatedFrame(size_t k)
std::vector< ViewParameters > view_status_
#define LogDebug(...)
Definition: Logging.h:90
Helper functions for the ml ops.
bool WriteIJsonConvertible(const std::string &filename, const cloudViewer::utility::IJsonConvertible &object)
bool ReadIJsonConvertible(const std::string &filename, cloudViewer::utility::IJsonConvertible &object)
std::string GetCurrentTimeStamp()
Returns current time stamp.
Definition: Helper.cpp:286
GLMatrix4f Perspective(double field_of_view_, double aspect, double z_near, double z_far)
Definition: GLHelper.cpp:50
Generic file read and write utility for python interface.