fw4spl
InteractorStyle2DForNegato.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2017.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwRenderVTK/vtk/InteractorStyle2DForNegato.hpp"
8 
9 #include <fwCore/base.hpp>
10 
11 #include <vtkCallbackCommand.h>
12 #include <vtkCamera.h>
13 #include <vtkCommand.h>
14 #include <vtkObjectFactory.h>
15 #include <vtkRenderer.h>
16 #include <vtkRenderWindowInteractor.h>
17 
18 vtkStandardNewMacro(InteractorStyle2DForNegato);
19 
20 //------------------------------------------------------------------------------
21 
22 InteractorStyle2DForNegato::InteractorStyle2DForNegato() :
23  vtkInteractorStyleTrackballCamera()
24 {
25 }
26 
27 //------------------------------------------------------------------------------
28 
29 InteractorStyle2DForNegato::~InteractorStyle2DForNegato()
30 {
31 }
32 
33 //------------------------------------------------------------------------------
34 
35 void InteractorStyle2DForNegato::OnChar()
36 {
37  vtkRenderWindowInteractor* rwi = this->Interactor;
38 
39  switch (rwi->GetKeyCode())
40  {
41  case 'r':
42  this->FindPokedRenderer(rwi->GetEventPosition()[0],
43  rwi->GetEventPosition()[1]);
44  this->CurrentRenderer->ResetCamera();
45 
46  if (this->getAutoRender())
47  {
48  rwi->Render();
49  }
50  break;
51  }
52 }
53 
54 //------------------------------------------------------------------------------
55 
56 void InteractorStyle2DForNegato::OnLeftButtonDown()
57 {
58  this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
59  this->Interactor->GetEventPosition()[1]);
60  if (this->CurrentRenderer == NULL)
61  {
62  return;
63  }
64 
65  this->GrabFocus(this->EventCallbackCommand);
66  if (this->Interactor->GetShiftKey())
67  {
68  m_oldPickPoint[0] = this->Interactor->GetEventPosition()[0];
69  m_oldPickPoint[1] = this->Interactor->GetEventPosition()[1];
70  this->StartPan();
71  }
72 }
73 
74 //------------------------------------------------------------------------------
75 
76 void InteractorStyle2DForNegato::OnRightButtonDown()
77 {
78  this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
79  this->Interactor->GetEventPosition()[1]);
80  if (this->CurrentRenderer == NULL)
81  {
82  return;
83  }
84 
85  this->GrabFocus(this->EventCallbackCommand);
86 
87  m_oldPickPoint[0] = this->Interactor->GetEventPosition()[0];
88  m_oldPickPoint[1] = this->Interactor->GetEventPosition()[1];
89  this->StartDolly();
90 }
91 
92 //------------------------------------------------------------------------------
93 
94 void InteractorStyle2DForNegato::OnMiddleButtonDown()
95 {
96  this->FindPokedRenderer(this->Interactor->GetEventPosition()[0], this->Interactor->GetEventPosition()[1]);
97 
98  if (this->CurrentRenderer != NULL)
99  {
100  m_oldPickPoint[0] = this->Interactor->GetEventPosition()[0];
101  m_oldPickPoint[1] = this->Interactor->GetEventPosition()[1];
102  this->StartPan();
103  }
104 }
105 
106 //------------------------------------------------------------------------------
107 
108 void InteractorStyle2DForNegato::OnMouseMove()
109 {
110  int x = this->Interactor->GetEventPosition()[0];
111  int y = this->Interactor->GetEventPosition()[1];
112 
113  m_newPickPoint[0] = this->Interactor->GetEventPosition()[0];
114  m_newPickPoint[1] = this->Interactor->GetEventPosition()[1];
115 
116  switch (this->State)
117  {
118  case VTKIS_PAN:
119  this->FindPokedRenderer(x, y);
120  this->Pan();
121  this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
122  break;
123  case VTKIS_DOLLY:
124  this->FindPokedRenderer(x, y);
125  this->Dolly();
126  this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
127  break;
128  }
129  m_oldPickPoint[0] = m_newPickPoint[0];
130  m_oldPickPoint[1] = m_newPickPoint[1];
131 }
132 
133 //----------------------------------------------------------------------------
134 
135 void InteractorStyle2DForNegato::OnMouseWheelBackward()
136 {
137  if (!this->Interactor->GetShiftKey())
138  {
139  int x = this->Interactor->GetEventPosition()[0];
140  int y = this->Interactor->GetEventPosition()[1];
141  this->FindPokedRenderer(x, y);
142  this->GrabFocus(this->EventCallbackCommand);
143  this->StartDolly();
144  double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
145  this->Dolly(pow(1.1, factor));
146  this->EndDolly();
147  this->ReleaseFocus();
148  }
149 }
150 
151 //----------------------------------------------------------------------------
152 
153 void InteractorStyle2DForNegato::OnMouseWheelForward()
154 {
155  if (!this->Interactor->GetShiftKey())
156  {
157  int x = this->Interactor->GetEventPosition()[0];
158  int y = this->Interactor->GetEventPosition()[1];
159  this->FindPokedRenderer(x, y);
160  this->GrabFocus(this->EventCallbackCommand);
161  this->StartDolly();
162  double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
163  this->Dolly(pow(1.1, factor));
164  this->EndDolly();
165  this->ReleaseFocus();
166  }
167 }
168 
169 //----------------------------------------------------------------------------
170 
171 void InteractorStyle2DForNegato::Pan()
172 {
173  if (this->CurrentRenderer == NULL)
174  {
175  return;
176  }
177 
178  // do nothing if mouse is still on the same pos
179  if( (m_newPickPoint[0] == m_oldPickPoint[0]) &&
180  (m_newPickPoint[1] == m_oldPickPoint[1]) )
181  {
182  return;
183  }
184 
185  vtkRenderWindowInteractor* rwi = this->Interactor;
186  double viewFocus[4], focalDepth, viewPoint[3];
187  double newPickPoint[4], oldPickPoint[4];
188  double motionVector[3];
189 
190  // Calculate the focal depth since we'll be using it a lot
191  vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
192  camera->GetFocalPoint(viewFocus);
193  this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
194  viewFocus);
195  focalDepth = viewFocus[2];
196 
197  this->ComputeDisplayToWorld( m_newPickPoint[0],
198  m_newPickPoint[1],
199  focalDepth,
200  newPickPoint);
201 
202  // Has to recalc old mouse point since the viewport has moved,
203  // so can't move it outside the loop
204  this->ComputeDisplayToWorld(m_oldPickPoint[0],
205  m_oldPickPoint[1],
206  focalDepth,
207  oldPickPoint);
208 
209  // Camera motion is reversed
210  motionVector[0] = oldPickPoint[0] - newPickPoint[0];
211  motionVector[1] = oldPickPoint[1] - newPickPoint[1];
212  motionVector[2] = oldPickPoint[2] - newPickPoint[2];
213 
214  camera->GetFocalPoint(viewFocus);
215  camera->GetPosition(viewPoint);
216 
217  camera->SetFocalPoint(motionVector[0] + viewFocus[0],
218  motionVector[1] + viewFocus[1],
219  motionVector[2] + viewFocus[2]);
220 
221  camera->SetPosition(motionVector[0] + viewPoint[0],
222  motionVector[1] + viewPoint[1],
223  motionVector[2] + viewPoint[2]);
224 
225  if (rwi->GetLightFollowCamera())
226  {
227  this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
228  }
229 
230  if (this->getAutoRender())
231  {
232  rwi->Render();
233  }
234 }
235 
236 //----------------------------------------------------------------------------
237 
238 void InteractorStyle2DForNegato::Dolly()
239 {
240  if (this->CurrentRenderer == NULL)
241  {
242  return;
243  }
244  if( (m_newPickPoint[0] == m_oldPickPoint[0]) &&
245  (m_newPickPoint[1] == m_oldPickPoint[1]) )
246  {
247  return;
248  }
249  double* center = this->CurrentRenderer->GetCenter();
250  int dy = static_cast<int>(m_newPickPoint[1] - m_oldPickPoint[1]);
251  double dyf = this->MotionFactor * dy / center[1];
252  this->Dolly(pow(1.1, dyf));
253 }
254 
255 //----------------------------------------------------------------------------
256 
257 void InteractorStyle2DForNegato::Dolly(double factor)
258 {
259  if (this->CurrentRenderer == NULL)
260  {
261  return;
262  }
263 
264  vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
265  if (camera->GetParallelProjection())
266  {
267  camera->SetParallelScale(camera->GetParallelScale() / factor);
268  }
269  else
270  {
271  camera->Dolly(factor);
272  if (this->AutoAdjustCameraClippingRange)
273  {
274  this->CurrentRenderer->ResetCameraClippingRange();
275  }
276  }
277 
278  if (this->Interactor->GetLightFollowCamera())
279  {
280  this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
281  }
282 
283  if (this->getAutoRender())
284  {
285  this->Interactor->Render();
286  }
287 }