1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkInteractorStyleFlight.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm 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 "vtkInteractorStyleFlight.h"
16
17 #include "vtkCamera.h"
18 #include "vtkPerspectiveTransform.h"
19 #include "vtkRenderer.h"
20 #include "vtkMath.h"
21 #include "vtkObjectFactory.h"
22 #include "vtkRenderWindowInteractor.h"
23 #include "vtkCallbackCommand.h"
24 #include "vtkWindows.h"
25
26 vtkStandardNewMacro(vtkInteractorStyleFlight);
27
28 class CPIDControl
29 {
30 public:
31 int m_iDeltaT;
32 int m_iDeltaTf;
33 double m_dPrevX;
34 double m_dKp;
35 double m_dKd;
36 double m_dKi;
37 double m_dXSum;
38 double m_dDelta;
39
40 double m_dVelSum;
41 int m_iVelCount;
42 double m_dVelAvg;
43 public:
44 CPIDControl(double dKp, double dKd, double dKi);
45 double PIDCalc(double dX,double dFinalX);
46 void SetCoefficients(double dKp, double dKd, double dKi);
47 };
48
CPIDControl(double dKp,double dKd,double dKi)49 CPIDControl::CPIDControl(double dKp, double dKd, double dKi)
50 {
51 m_dXSum = 0.0;
52 m_dPrevX = 0.0;
53 m_dDelta = 0.0;
54 m_iDeltaT = 0;
55 m_iDeltaTf = 0;
56 m_dVelSum = 0.0;
57 m_iVelCount = 0;
58 m_dVelAvg = 0.0;
59 this->SetCoefficients(dKp, dKd, dKi);
60 }
61
62 ///////////////////////////////////////////////////////////////////////////////
63 ///////////////////////////////////////////////////////////////////////////////
PIDCalc(double dX,double dFinalX)64 double CPIDControl::PIDCalc(double dX, double dFinalX)
65 {
66 double dVal = dX - dFinalX;
67 m_dXSum = m_dXSum + dVal;
68 // Calculate the velocity
69 dVal = m_dPrevX - dX;
70 // Average the velocity
71 m_dVelSum += dVal;
72 m_iVelCount++;
73 if(m_iVelCount >= 10)
74 {
75 m_dVelAvg = m_dVelSum/m_iVelCount;
76 m_iVelCount = 0;
77 m_dVelSum = 0.0;
78 }
79 m_dDelta = m_dKp*dX + m_dKd*m_dVelAvg + m_dKi*m_dXSum;
80 m_dPrevX = dX;
81
82 return m_dDelta;
83 }
84
85 ///////////////////////////////////////////////////////////////////////////////
86 ///////////////////////////////////////////////////////////////////////////////
SetCoefficients(double dKp,double dKd,double dKi)87 void CPIDControl::SetCoefficients(double dKp, double dKd, double dKi)
88 {
89 m_dKp = dKp;
90 m_dKd = dKd;
91 m_dKi = dKi;
92 // should reset internal params here, but no need for this simple usage
93 }
94
95
96 //---------------------------------------------------------------------------
vtkInteractorStyleFlight()97 vtkInteractorStyleFlight::vtkInteractorStyleFlight()
98 {
99 this->KeysDown = 0;
100 this->UseTimers = 1;
101
102 this->DiagonalLength = 1.0;
103 this->MotionStepSize = 1.0/250.0;
104 this->MotionUserScale = 1.0; // +/- key adjustment
105 this->MotionAccelerationFactor = 10.0;
106 this->AngleStepSize = 1.0;
107 this->AngleAccelerationFactor = 5.0;
108
109 this->DisableMotion = 0;
110 this->RestoreUpVector = 1;
111 this->DefaultUpVector[0] = 0;
112 this->DefaultUpVector[1] = 0;
113 this->DefaultUpVector[2] = 1;
114 //
115 PID_Yaw = new CPIDControl(-0.05, 0.0, -0.0008);
116 PID_Pitch = new CPIDControl(-0.05, 0.0, -0.0008);
117 Transform = vtkPerspectiveTransform::New();
118 }
119
120 //---------------------------------------------------------------------------
~vtkInteractorStyleFlight()121 vtkInteractorStyleFlight::~vtkInteractorStyleFlight()
122 {
123 Transform->Delete();
124 delete PID_Yaw;
125 delete PID_Pitch;
126 }
127 //---------------------------------------------------------------------------
ForwardFly()128 void vtkInteractorStyleFlight::ForwardFly()
129 {
130 if (this->CurrentRenderer == nullptr)
131 {
132 return;
133 }
134 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
135 //
136 if (this->KeysDown)
137 {
138 this->FlyByKey(camera);
139 }
140 else
141 {
142 this->UpdateSteering(camera);
143 this->FlyByMouse(camera);
144 }
145 //
146 this->FinishCamera(camera);
147 }
148 //---------------------------------------------------------------------------
ReverseFly()149 void vtkInteractorStyleFlight::ReverseFly()
150 {
151 // The code is the same, just the state variable that is tracked...
152 ForwardFly();
153 }
154
155 //----------------------------------------------------------------------------
StartForwardFly()156 void vtkInteractorStyleFlight::StartForwardFly()
157 {
158 if (this->State != VTKIS_NONE)
159 {
160 return;
161 }
162 this->StartState(VTKIS_FORWARDFLY);
163 }
164
165 //----------------------------------------------------------------------------
EndForwardFly()166 void vtkInteractorStyleFlight::EndForwardFly()
167 {
168 if (this->State != VTKIS_FORWARDFLY)
169 {
170 return;
171 }
172 this->StopState();
173 }
174
175 //----------------------------------------------------------------------------
StartReverseFly()176 void vtkInteractorStyleFlight::StartReverseFly()
177 {
178 if (this->State != VTKIS_NONE)
179 {
180 return;
181 }
182 this->StartState(VTKIS_REVERSEFLY);
183 }
184
185 //----------------------------------------------------------------------------
EndReverseFly()186 void vtkInteractorStyleFlight::EndReverseFly()
187 {
188 if (this->State != VTKIS_REVERSEFLY)
189 {
190 return;
191 }
192 this->StopState();
193 }
194
195 //---------------------------------------------------------------------------
196 // All actual motion is performed in the timer
197 //---------------------------------------------------------------------------
OnTimer()198 void vtkInteractorStyleFlight::OnTimer()
199 {
200 switch (this->State)
201 {
202 case VTKIS_FORWARDFLY:
203 this->ForwardFly();
204 break;
205
206 case VTKIS_REVERSEFLY:
207 this->ReverseFly();
208 break;
209
210 default:
211 break;
212 }
213 }
214
215 //---------------------------------------------------------------------------
216 // Mouse event handlers
217 //---------------------------------------------------------------------------
OnMouseMove()218 void vtkInteractorStyleFlight::OnMouseMove()
219 {
220 int x = this->Interactor->GetEventPosition()[0];
221 int y = this->Interactor->GetEventPosition()[1];
222 this->FindPokedRenderer(x, y);
223 vtkCamera* cam = this->CurrentRenderer->GetActiveCamera();
224 switch (this->State)
225 {
226 case VTKIS_FORWARDFLY:
227 case VTKIS_REVERSEFLY:
228 this->UpdateMouseSteering(cam);
229 this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
230 break;
231 }
232 }
233
234 //---------------------------------------------------------------------------
OnLeftButtonDown()235 void vtkInteractorStyleFlight::OnLeftButtonDown()
236 {
237 int x = this->Interactor->GetEventPosition()[0];
238 int y = this->Interactor->GetEventPosition()[1];
239 this->FindPokedRenderer(x, y);
240 if (this->CurrentRenderer == nullptr)
241 {
242 return;
243 }
244
245 //
246 this->GrabFocus(this->EventCallbackCommand);
247 vtkCamera* cam = this->CurrentRenderer->GetActiveCamera();
248 switch (this->State)
249 {
250 case VTKIS_REVERSEFLY:
251 this->State = VTKIS_FORWARDFLY;
252 break;
253 default :
254 this->SetupMotionVars(cam);
255 this->StartForwardFly();
256 break;
257 }
258 }
259
260 //---------------------------------------------------------------------------
OnLeftButtonUp()261 void vtkInteractorStyleFlight::OnLeftButtonUp()
262 {
263 switch (this->State)
264 {
265 case VTKIS_FORWARDFLY:
266 this->EndForwardFly();
267 break;
268 default :
269 break;
270 }
271 if ( this->Interactor )
272 {
273 this->ReleaseFocus();
274 }
275 }
276
277 //---------------------------------------------------------------------------
OnMiddleButtonDown()278 void vtkInteractorStyleFlight::OnMiddleButtonDown()
279 {
280 }
281
282 //---------------------------------------------------------------------------
OnMiddleButtonUp()283 void vtkInteractorStyleFlight::OnMiddleButtonUp()
284 {
285 }
286
287 //---------------------------------------------------------------------------
OnRightButtonDown()288 void vtkInteractorStyleFlight::OnRightButtonDown()
289 {
290 int x = this->Interactor->GetEventPosition()[0];
291 int y = this->Interactor->GetEventPosition()[1];
292 this->FindPokedRenderer(x, y);
293 if (this->CurrentRenderer == nullptr)
294 {
295 return;
296 }
297
298 //
299 this->GrabFocus(this->EventCallbackCommand);
300 vtkCamera* cam = this->CurrentRenderer->GetActiveCamera();
301 switch (this->State)
302 {
303 case VTKIS_FORWARDFLY:
304 this->State = VTKIS_REVERSEFLY;
305 break;
306 default :
307 this->SetupMotionVars(cam);
308 this->StartReverseFly();
309 break;
310 }
311 }
312
313 //---------------------------------------------------------------------------
OnRightButtonUp()314 void vtkInteractorStyleFlight::OnRightButtonUp()
315 {
316 switch (this->State)
317 {
318 case VTKIS_REVERSEFLY:
319 this->EndReverseFly();
320 break;
321 default :
322 break;
323 }
324 if ( this->Interactor )
325 {
326 this->ReleaseFocus();
327 }
328 }
329
330 //---------------------------------------------------------------------------
331 // Keyboard event handlers
332 // Note, OnChar is a key press down and then up event
333 // Note, OnKeyDown/OnKeyUp are more sensitive for controlling motion
334 //---------------------------------------------------------------------------
OnKeyDown()335 void vtkInteractorStyleFlight::OnKeyDown()
336 {
337 // New Flight mode behaviour
338 // Note that we'll need #defines for ARROW key defs under non win32 OS
339 #ifdef _WIN32
340 switch (this->Interactor->GetKeyCode())
341 {
342 case VK_LEFT : this->KeysDown |=1; break;
343 case VK_RIGHT : this->KeysDown |=2; break;
344 case VK_UP : this->KeysDown |=4; break;
345 case VK_DOWN : this->KeysDown |=8; break;
346 case 'a':
347 case 'A' : this->KeysDown |=16; break;
348 case 'z':
349 case 'Z' : this->KeysDown |=32; break;
350 }
351 if ((this->KeysDown & (32+16)) == (32+16))
352 {
353 if (this->State==VTKIS_FORWARDFLY)
354 {
355 this->EndForwardFly();
356 }
357 if (this->State==VTKIS_REVERSEFLY)
358 {
359 this->EndReverseFly();
360 }
361 }
362 else if ((this->KeysDown & 32) == 32)
363 {
364 if (this->State==VTKIS_FORWARDFLY)
365 {
366 this->EndForwardFly();
367 }
368 this->StartReverseFly();
369 }
370 else if ((this->KeysDown & 16) == 16)
371 {
372 if (this->State==VTKIS_REVERSEFLY)
373 {
374 this->EndReverseFly();
375 }
376 this->StartForwardFly();
377 }
378 #else
379 // the following if statement is a dummy one to prevent keycode not used
380 // warnings under unix, (until the correct keycodes are supplied)
381 if (this->Interactor->GetKeyCode() == 0x7F)
382 {
383 vtkWarningMacro(<<"Dummy test to prevent compiler warning");
384 }
385 #endif
386 }
387
388 //---------------------------------------------------------------------------
OnKeyUp()389 void vtkInteractorStyleFlight::OnKeyUp()
390 {
391 #ifdef _WIN32
392 switch (this->Interactor->GetKeyCode())
393 {
394 case VK_LEFT : this->KeysDown &= ~1; break;
395 case VK_RIGHT : this->KeysDown &= ~2; break;
396 case VK_UP : this->KeysDown &= ~4; break;
397 case VK_DOWN : this->KeysDown &= ~8; break;
398 case 'a':
399 case 'A' : this->KeysDown &= ~16; break;
400 case 'z':
401 case 'Z' : this->KeysDown &= ~32; break;
402 }
403 switch (this->State)
404 {
405 case VTKIS_FORWARDFLY:
406 if ((this->KeysDown & 16) == 0)
407 {
408 this->EndForwardFly();
409 }
410 break;
411 case VTKIS_REVERSEFLY:
412 if ((this->KeysDown & 32) == 0)
413 {
414 this->EndReverseFly();
415 }
416 break;
417 }
418 #else
419 // the following if statement is a dummy one to prevent keycode not used
420 // warnings under unix, (until the correct keycodes are supplied)
421 if (this->Interactor->GetKeyCode() == 0x7F)
422 {
423 vtkWarningMacro(<<"Dummy test to prevent compiler warning");
424 }
425 #endif
426 }
427
428 //---------------------------------------------------------------------------
OnChar()429 void vtkInteractorStyleFlight::OnChar()
430 {
431 switch (this->Interactor->GetKeyCode())
432 {
433 case '+' :
434 this->MotionUserScale *= 2.0;
435 break;
436 case '-' :
437 this->MotionUserScale *= 0.5;
438 break;
439 default:
440 this->Superclass::OnChar();
441 break;
442 }
443 }
444
445 //---------------------------------------------------------------------------
JumpTo(double campos[3],double focpos[3])446 void vtkInteractorStyleFlight::JumpTo(double campos[3], double focpos[3])
447 {
448 if (this->CurrentRenderer == nullptr)
449 {
450 return;
451 }
452 vtkCamera* cam = this->CurrentRenderer->GetActiveCamera();
453 cam->SetPosition(campos);
454 cam->SetFocalPoint(focpos);
455 FinishCamera(cam);
456 this->Interactor->Render();
457 }
458
FinishCamera(vtkCamera * cam)459 void vtkInteractorStyleFlight::FinishCamera(vtkCamera* cam)
460 {
461 cam->OrthogonalizeViewUp();
462 if (this->RestoreUpVector)
463 {
464 double delta[3];
465 cam->GetViewUp(delta);
466 double weight = vtkMath::Dot(this->DefaultUpVector,delta);
467 // only correct up if we're close to it already...
468 if (weight>0.3) {
469 weight = 0.25*fabs(weight);
470 delta[0] = delta[0] + (this->DefaultUpVector[0]-delta[0])*weight;
471 delta[1] = delta[1] + (this->DefaultUpVector[1]-delta[1])*weight;
472 delta[2] = delta[2] + (this->DefaultUpVector[2]-delta[2])*weight;
473 cam->SetViewUp(delta);
474 }
475 }
476 if (this->AutoAdjustCameraClippingRange)
477 {
478 this->CurrentRenderer->ResetCameraClippingRange();
479 }
480 if (this->Interactor->GetLightFollowCamera())
481 {
482 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
483 }
484 }
485
486 //---------------------------------------------------------------------------
487 // Use this mouse pos and last mouse pos to get the amount of motion
488 // Compute an "Ideal" focal point, The flight will sterr towards this ideal
489 // point, but will be damped in Yaw/Pitch by our PID Controllers.
490 // The damping and motion is done in the timer event.
491 //---------------------------------------------------------------------------
UpdateMouseSteering(vtkCamera * cam)492 void vtkInteractorStyleFlight::UpdateMouseSteering(vtkCamera *cam)
493 {
494 int *thispos = this->Interactor->GetEventPosition();
495 int *lastpos = this->Interactor->GetLastEventPosition();
496
497 double aspeed = this->AngleStepSize*(this->Interactor->GetShiftKey() ?
498 this->AngleAccelerationFactor : 1.0);
499 //
500 // we want to steer by an amount proportional to window viewangle and size
501 // compute dx and dy increments relative to last mouse click
502 int *size = this->Interactor->GetSize();
503 double scalefactor = 5*cam->GetViewAngle()/size[0];
504 double dx = - (thispos[0] - lastpos[0])*scalefactor*aspeed;
505 double dy = (thispos[1] - lastpos[1])*scalefactor*aspeed;
506
507 // Temporary until I get smooth flight working
508 this->DeltaPitch = dy;
509 this->DeltaYaw = dx;
510 /*
511 Not happy with smooth flight yet, please leave this code here
512 until I get around to experimenting : JB July 2002
513
514 // dx and dy need to be converted to a new 'ideal' camera focal point
515 // we maintain an actual FocalPoint and an IdealFocalPoint so that we can
516 // smooth the motion using our PID controllers (one for yaw, one for pitch).
517 cam->OrthogonalizeViewUp();
518 double LRaxis[3];
519 double *ViewUp = cam->GetViewUp();
520 double *Position = cam->GetPosition();
521 double *FocalPoint = cam->GetFocalPoint();
522 this->GetLRVector(LRaxis, cam);
523 //
524 this->Transform->Identity();
525 this->Transform->Translate(+Position[0],+Position[1],+Position[2]);
526 this->Transform->RotateWXYZ(dx, ViewUp);
527 this->Transform->RotateWXYZ(dy, LRaxis);
528 this->Transform->Translate(-Position[0],-Position[1],-Position[2]);
529 this->Transform->TransformPoint(this->IdealFocalPoint,this->IdealFocalPoint);
530 */
531 }
532
533 // We know the ideal and actual focal points. We now want to reduce these
534 // to a 2D Yaw+Pitch form so that we can smooth the motion on each
UpdateSteering(vtkCamera * vtkNotUsed (cam))535 void vtkInteractorStyleFlight::UpdateSteering(vtkCamera *vtkNotUsed(cam))
536 {
537 /*
538 #define D2R 0.01745329251994329576923690768 // degrees to radians
539 #define R2D 57.2957795130823208767981548141 // radians to degrees
540
541 Not happy with smooth flight yet, please leave this code here
542 until I get around to experimenting : JB July 2002
543
544 cam->OrthogonalizeViewUp();
545 double *Position = cam->GetPosition();
546 double *FocalPoint = cam->GetFocalPoint();
547 double vec1[3], vec2[3], norm1[3], norm2[3];
548 vec1[0] = FocalPoint[0]-Position[0];
549 vec1[1] = FocalPoint[1]-Position[1];
550 vec1[2] = FocalPoint[2]-Position[2];
551 vec2[0] = this->IdealFocalPoint[0]-Position[0];
552 vec2[1] = this->IdealFocalPoint[1]-Position[1];
553 vec2[2] = this->IdealFocalPoint[2]-Position[2];
554 // what's the azimuthal angle between the Ideal and actual focal points
555 // angle between planes given by Up/Focus and Up/IdealFocus
556 double *ViewUp = cam->GetViewUp();
557 vtkMath::Cross(vec1, ViewUp, norm1);
558 vtkMath::Cross(vec2, ViewUp, norm2);
559 vtkMath::Normalize(norm1);
560 vtkMath::Normalize(norm2);
561 //
562 double dot = vtkMath::Dot(norm1, norm2);
563 if (dot>1.0) {
564 dot = 1.0;
565 }
566 else if (dot<-1.0) {
567 dot =-1.0;
568 }
569 double yaw = R2D*acos(dot);
570 // we know the angle, but is it +ve or -ve (which side is new focal point)
571 double d1,d2;
572 d1 = vtkMath::Dot(norm1,this->IdealFocalPoint);
573 d2 = vtkMath::Dot(norm1,FocalPoint);
574 if (d1-d2>0) yaw = -yaw;
575 //
576 // what's the elevation angle between the Ideal and actual focal points
577 // angle between planes given by LR/Focus and LR/IdealFocus
578 double LRaxis[3];
579 this->GetLRVector(LRaxis, cam);
580 vtkMath::Cross(vec1, LRaxis, norm1);
581 vtkMath::Cross(vec2, LRaxis, norm2);
582 vtkMath::Normalize(norm1);
583 vtkMath::Normalize(norm2);
584 //
585 dot = vtkMath::Dot(norm1, norm2);
586 if (dot>1.0) {
587 dot = 1.0;
588 } else if (dot<-1.0) {
589 dot =-1.0;
590 }
591 double pitch = R2D*acos(dot);
592 d1 = vtkMath::Dot(norm1,this->IdealFocalPoint);
593 d2 = vtkMath::Dot(norm1,FocalPoint);
594 if (d1-d2>0) pitch = -pitch;
595
596 // use our motion dampers to reduce the yaw/pitch errors to zero gradually
597 // this->DeltaYaw = PID_Yaw->PIDCalc(yaw, 0);
598 // this->DeltaPitch = PID_Pitch->PIDCalc(pitch, 0);
599
600 this->DeltaPitch = 0.75*pitch + 0.25*lPitch;
601 lPitch = pitch;
602
603 this->DeltaYaw = 0.75*yaw + 0.25*lYaw;
604 lYaw = yaw;
605
606 */
607 }
608
609 //---------------------------------------------------------------------------
610 // useful utility functions
611 //---------------------------------------------------------------------------
SetupMotionVars(vtkCamera * cam)612 void vtkInteractorStyleFlight::SetupMotionVars(vtkCamera *cam)
613 {
614 lPitch = 0;
615 lYaw = 0;
616 cam->GetFocalPoint(IdealFocalPoint);
617
618 double bounds[6];
619 this->CurrentRenderer->ComputeVisiblePropBounds( bounds );
620 if ( !vtkMath::AreBoundsInitialized(bounds) )
621 {
622 this->DiagonalLength = 1.0;
623 }
624 else
625 {
626 this->DiagonalLength =
627 sqrt( (bounds[0] - bounds[1]) * (bounds[0] - bounds[1]) +
628 (bounds[2] - bounds[3]) * (bounds[2] - bounds[3]) +
629 (bounds[4] - bounds[5]) * (bounds[4] - bounds[5]) );
630 }
631 }
632
633 //---------------------------------------------------------------------------
MotionAlongVector(double vector[3],double amount,vtkCamera * cam)634 void vtkInteractorStyleFlight::MotionAlongVector(double vector[3],
635 double amount, vtkCamera* cam)
636 {
637 double oldcampos[3], oldcamfoc[3];
638 cam->GetPosition(oldcampos);
639 cam->GetFocalPoint(oldcamfoc);
640 // move camera and focus along DirectionOfProjection
641 cam->SetPosition(
642 oldcampos[0] - amount * vector[0],
643 oldcampos[1] - amount * vector[1],
644 oldcampos[2] - amount * vector[2]);
645 cam->SetFocalPoint(
646 oldcamfoc[0] - amount * vector[0],
647 oldcamfoc[1] - amount * vector[1],
648 oldcamfoc[2] - amount * vector[2]);
649 }
650
651 //---------------------------------------------------------------------------
GetLRVector(double vector[3],vtkCamera * cam)652 void vtkInteractorStyleFlight::GetLRVector(double vector[3], vtkCamera* cam)
653 {
654 vtkMatrix4x4 *vtm;
655 vtm = cam->GetViewTransformMatrix();
656 vector[0] = vtm->GetElement(0,0);
657 vector[1] = vtm->GetElement(0,1);
658 vector[2] = vtm->GetElement(0,2);
659 }
660
661 //---------------------------------------------------------------------------
662 // Perform the motion
663 //---------------------------------------------------------------------------
FlyByMouse(vtkCamera * cam)664 void vtkInteractorStyleFlight::FlyByMouse(vtkCamera* cam)
665 {
666 double a_vector[3];
667 double speed = this->DiagonalLength * this->MotionStepSize * this->MotionUserScale;
668 speed = speed * ( this->Interactor->GetShiftKey() ? this->MotionAccelerationFactor : 1.0);
669 if (this->DisableMotion)
670 {
671 speed = 0;
672 }
673 // Sidestep (convert steering angles to left right movement :
674 // only because I added this after doing the angles earlier
675 if (this->Interactor->GetControlKey())
676 {
677 if (this->DeltaYaw!=0.0)
678 {
679 this->GetLRVector(a_vector, cam);
680 this->MotionAlongVector(a_vector,-this->DeltaYaw*speed/2.0, cam);
681 }
682 if (this->DeltaPitch!=0.0)
683 {
684 cam->GetViewUp(a_vector);
685 this->MotionAlongVector(a_vector,-this->DeltaPitch*speed/2.0, cam);
686 }
687 }
688 else
689 {
690 cam->Yaw(this->DeltaYaw);
691 cam->Pitch(this->DeltaPitch);
692 this->DeltaYaw = 0;
693 this->DeltaPitch = 0;
694 // cam->SetFocalPoint(this->IdealFocalPoint);
695 }
696 //
697 if (!this->Interactor->GetControlKey())
698 {
699 cam->GetDirectionOfProjection(a_vector); // reversed (use -speed)
700 switch (this->State)
701 {
702 case VTKIS_FORWARDFLY:
703 this->MotionAlongVector(a_vector, -speed, cam);
704 break;
705 case VTKIS_REVERSEFLY:
706 this->MotionAlongVector(a_vector, speed, cam);
707 break;
708 }
709 }
710 }
711
712 //---------------------------------------------------------------------------
FlyByKey(vtkCamera * cam)713 void vtkInteractorStyleFlight::FlyByKey(vtkCamera* cam)
714 {
715 double speed = this->DiagonalLength * this->MotionStepSize * this->MotionUserScale;
716 speed = speed * ( this->Interactor->GetShiftKey() ? this->MotionAccelerationFactor : 1.0);
717 if (this->DisableMotion)
718 {
719 speed = 0;
720 }
721 //
722 double aspeed = this->AngleStepSize* (this->Interactor->GetShiftKey() ? this->AngleAccelerationFactor : 1.0);
723 double a_vector[3];
724 // Left and right
725 if (this->Interactor->GetControlKey())
726 { // Sidestep
727 this->GetLRVector(a_vector, cam);
728 if (this->KeysDown & 1)
729 {
730 this->MotionAlongVector(a_vector,-speed, cam);
731 }
732 if (this->KeysDown & 2)
733 {
734 this->MotionAlongVector(a_vector, speed, cam);
735 }
736 }
737 else
738 {
739 if (this->KeysDown & 1)
740 {
741 cam->Yaw( aspeed);
742 }
743 if (this->KeysDown & 2)
744 {
745 cam->Yaw(-aspeed);
746 }
747 }
748
749 // Up and Down
750 if (this->Interactor->GetControlKey())
751 { // Sidestep
752 cam->GetViewUp(a_vector);
753 if (this->KeysDown & 4)
754 {
755 this->MotionAlongVector(a_vector,-speed, cam);
756 }
757 if (this->KeysDown & 8)
758 {
759 this->MotionAlongVector(a_vector, speed, cam);
760 }
761 }
762 else
763 {
764 if (this->KeysDown & 4)
765 {
766 cam->Pitch(-aspeed);
767 }
768 if (this->KeysDown & 8)
769 {
770 cam->Pitch( aspeed);
771 }
772 }
773
774 // forward and backward
775 cam->GetDirectionOfProjection(a_vector);
776 if (this->KeysDown & 16)
777 {
778 this->MotionAlongVector(a_vector, speed, cam);
779 }
780 if (this->KeysDown & 32)
781 {
782 this->MotionAlongVector(a_vector,-speed, cam);
783 }
784 }
785
786 //---------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)787 void vtkInteractorStyleFlight::PrintSelf(ostream& os, vtkIndent indent)
788 {
789 this->Superclass::PrintSelf(os,indent);
790 os << indent << "MotionStepSize: "
791 << this->MotionStepSize << "\n";
792 os << indent << "MotionAccelerationFactor: "
793 << this->MotionAccelerationFactor << "\n";
794 os << indent << "AngleStepSize: "
795 << this->AngleStepSize << "\n";
796 os << indent << "AngleAccelerationFactor: "
797 << this->AngleAccelerationFactor << "\n";
798 os << indent << "MotionUserScale: "
799 << this->MotionUserScale << "\n";
800 os << indent << "DisableMotion: "
801 << this->DisableMotion << "\n";
802 os << indent << "RestoreUpVector: "
803 << this->RestoreUpVector << "\n";
804 os << indent << "DefaultUpVector: "
805 << this->DefaultUpVector[0] << " "
806 << this->DefaultUpVector[1] << " "
807 << this->DefaultUpVector[2] << "\n";
808 }
809
810
811