ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
vtkPVJoystickFly.cxx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ParaView
4  Module: vtkPVJoystickFly.cxx
5 
6  Copyright (c) Kitware, Inc.
7  All rights reserved.
8  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkPVJoystickFly.h"
16 
17 #include "vtkCamera.h"
19 #include "vtkMath.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkRenderWindow.h"
22 #include "vtkRenderWindowInteractor.h"
23 #include "vtkRenderer.h"
24 #include "vtkTimerLog.h"
25 
26 //-------------------------------------------------------------------------
28 {
29  this->In = -1;
30  this->FlyFlag = 0;
31  this->FlySpeed = 20.0;
32  this->LastRenderTime = 0.1;
33 
34  this->CameraXAxis[0] = 1.0;
35  this->CameraXAxis[1] = 0.0;
36  this->CameraXAxis[2] = 0.0;
37 
38  this->CameraYAxis[0] = 0.0;
39  this->CameraYAxis[1] = 1.0;
40  this->CameraYAxis[2] = 0.0;
41 
42  this->CameraZAxis[0] = 0.0;
43  this->CameraZAxis[1] = 0.0;
44  this->CameraZAxis[2] = 1.0;
45 }
46 
47 //-------------------------------------------------------------------------
49 {
50 }
51 
52 //-------------------------------------------------------------------------
53 void vtkPVJoystickFly::OnButtonDown(int, int, vtkRenderer* ren, vtkRenderWindowInteractor* rwi)
54 {
55  if (this->In < 0)
56  {
57  vtkErrorMacro(
58  "Joystick Fly manipulator has to be used from one of the two subclasses (In and Out)");
59  return;
60  }
61  if (!this->GetGUIHelper())
62  {
63  vtkErrorMacro("GUIHelper is not defined");
64  return;
65  }
66  if (!ren || !rwi)
67  {
68  vtkErrorMacro("Renderer or Render Window Interactor are not defined");
69  return;
70  }
71 
72  double* range = ren->GetActiveCamera()->GetClippingRange();
73  this->Fly(ren, rwi, range[1], (this->In ? 1 : -1) * this->FlySpeed * .01);
74 }
75 
76 //-------------------------------------------------------------------------
77 void vtkPVJoystickFly::OnButtonUp(int, int, vtkRenderer*, vtkRenderWindowInteractor* rwi)
78 {
79  this->FlyFlag = 0;
80  rwi->Render();
81 }
82 
83 //-------------------------------------------------------------------------
84 void vtkPVJoystickFly::OnMouseMove(int, int, vtkRenderer*, vtkRenderWindowInteractor*)
85 {
86 }
87 
88 //-------------------------------------------------------------------------
89 void vtkPVJoystickFly::Fly(vtkRenderer* ren, vtkRenderWindowInteractor* rwi, double, double ispeed)
90 {
91  if (this->FlyFlag || !this->GetGUIHelper())
92  {
93  return;
94  }
95 
96  // We'll need the size of the window
97  int* size = ren->GetSize();
98 
99  // Also we will need the camera.
100  vtkCamera* cam = ren->GetActiveCamera();
101 
102  // We need to time rendering so that we can adjust the speed
103  // accordingly
104  vtkTimerLog* timer = vtkTimerLog::New();
105 
106  // We are flying now!
107  this->FlyFlag = 1;
108 
109  double speed;
110 
111  // The first time through we don't want to move
112  int first = 1;
113 
114  // As long as the mouse is still pressed
115  while (this->FlyFlag)
116  {
117  double* range = cam->GetClippingRange();
118  double dist = 0.5 * (range[1] + range[0]);
119  double lastx = rwi->GetLastEventPosition()[0];
120  double lasty = size[1] - rwi->GetLastEventPosition()[1] - 1;
121 
122  // Compute a new render time if appropriate (delta time).
123  if (!first)
124  {
125  // We need at least one time to determine
126  // what our increments should be.
127  timer->StopTimer();
128  this->LastRenderTime = timer->GetElapsedTime();
129  // Limit length of render time because we do not want such large jumps
130  // when rendering takes more than 1 second.
131  if (this->LastRenderTime > 1.0)
132  {
133  this->LastRenderTime = 1.0;
134  }
135  }
136  first = 0;
137 
138  // Compute angle ralative to viewport.
139  // These values will be from -0.5 to 0.5
140  double vx = (size[0] / 2 - lastx) / (double)(size[0]);
141  double vy = (size[1] / 2 - lasty) / (double)(size[0]);
142 
143  // Convert to world angle by multiplying by view angle.
144  // (Speed up rotation for wide angle views).
145  double viewAngle;
146  if (cam->GetParallelProjection())
147  { // We need to compute a pseudo viewport angle.
148  double parallelScale = cam->GetParallelScale();
149  viewAngle = 360.0 * atan2(parallelScale * 0.5, dist) / vtkMath::Pi();
150  }
151  else
152  {
153  viewAngle = cam->GetViewAngle();
154  }
155  vx = vx * viewAngle;
156  vy = vy * viewAngle;
157 
158  // Compute speed.
159  speed = ispeed * range[1];
160 
161  // Scale speed and rotation by render time
162  // to get constant perceived velocities.
163  speed = speed * this->LastRenderTime;
164  vx = vx * this->LastRenderTime;
165  vy = vy * this->LastRenderTime;
166 
167  // Start the timer up again
168  timer->StartTimer();
169 
170  // Do the rotation
171  cam->Yaw(vx);
172  cam->Pitch(vy);
173  cam->OrthogonalizeViewUp();
174 
175  // Now figure out if we should slow down our speed because
176  // we are trying to make a sharp turn
177  vx = (double)(size[0] / 2 - lastx) / (double)(size[0]);
178  vy = (double)(size[1] / 2 - lasty) / (double)(size[1]);
179  vx = (vx < 0) ? (-vx) : (vx);
180  vy = (vy < 0) ? (-vy) : (vy);
181  vx = (vx > vy) ? (vx) : (vy);
182  speed *= (1.0 - 2.0 * vx);
183 
184  // Move the camera forward based on speed.
185  // Although this has no effect for parallel projection,
186  // it helps keep the pseudo view angle constant.
187  double fp[3], pos[3];
188  cam->GetPosition(pos);
189  cam->GetFocalPoint(fp);
190  double dir[3];
191  dir[0] = fp[0] - pos[0];
192  dir[1] = fp[1] - pos[1];
193  dir[2] = fp[2] - pos[2];
194  vtkMath::Normalize(dir);
195  dir[0] *= speed;
196  dir[1] *= speed;
197  dir[2] *= speed;
198  fp[0] += dir[0];
199  fp[1] += dir[1];
200  fp[2] += dir[2];
201  pos[0] += dir[0];
202  pos[1] += dir[1];
203  pos[2] += dir[2];
204  cam->SetPosition(pos);
205  cam->SetFocalPoint(fp);
206 
207  // In parallel we need to adjust the parallel scale
208  if (cam->GetParallelProjection())
209  {
210  double scale = cam->GetParallelScale();
211  if (dist > 0.0 && dist > speed)
212  {
213  scale = scale * (dist - speed) / dist;
214  cam->SetParallelScale(scale);
215  }
216  }
217 
218  rwi->Render();
219 
220  // Update to process mouse events to get the new position
221  // and to check for mouse up events
222  this->GetGUIHelper()->UpdateGUI();
223  }
224 
225  timer->Delete();
226 }
227 
228 //-------------------------------------------------------------------------
230 {
231  vtkCamera* camera = ren->GetActiveCamera();
232 
233  camera->OrthogonalizeViewUp();
234  camera->GetViewUp(this->CameraYAxis);
235  camera->GetDirectionOfProjection(this->CameraZAxis);
236 
237  // I do not know if this is actually used, but this was originally
238  // set to the ViewPlaneNormal.
239  this->CameraZAxis[0] = -this->CameraZAxis[0];
240  this->CameraZAxis[1] = -this->CameraZAxis[1];
241  this->CameraZAxis[2] = -this->CameraZAxis[2];
242 
243  vtkMath::Cross(this->CameraYAxis, this->CameraZAxis, this->CameraXAxis);
244 }
245 
246 //-------------------------------------------------------------------------
247 void vtkPVJoystickFly::PrintSelf(ostream& os, vtkIndent indent)
248 {
249  this->Superclass::PrintSelf(os, indent);
250  os << indent << "FlySpeed: " << this->FlySpeed << endl;
251 }
int size
void Fly(vtkRenderer *ren, vtkRenderWindowInteractor *rwi, double scale, double speed)
void OnMouseMove(int x, int y, vtkRenderer *ren, vtkRenderWindowInteractor *rwi) override
void PrintSelf(ostream &os, vtkIndent indent) override
~vtkPVJoystickFly() override
void OnButtonUp(int x, int y, vtkRenderer *ren, vtkRenderWindowInteractor *rwi) override
void OnButtonDown(int x, int y, vtkRenderer *ren, vtkRenderWindowInteractor *rwi) override
void ComputeCameraAxes(vtkRenderer *)
QTextStream & endl(QTextStream &stream)
Definition: QtCompat.h:718
CLOUDVIEWER_HOST_DEVICE float Cross(const Point &a, const Point &b)
Definition: IoUImpl.h:39
const float Pi
Definition: utils.cpp:15