1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkTDxInteractorStyleGeo.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 
16 #include "vtkTDxInteractorStyleGeo.h"
17 
18 #include "vtkTransform.h"
19 #include <cassert>
20 #include "vtkCamera.h"
21 #include "vtkRenderer.h"
22 #include "vtkRenderWindow.h"
23 #include "vtkRenderWindowInteractor.h"
24 #include "vtkTDxMotionEventInfo.h"
25 #include "vtkObjectFactory.h"
26 #include "vtkTDxInteractorStyleSettings.h"
27 
28 vtkStandardNewMacro(vtkTDxInteractorStyleGeo);
29 
30 // ----------------------------------------------------------------------------
vtkTDxInteractorStyleGeo()31 vtkTDxInteractorStyleGeo::vtkTDxInteractorStyleGeo()
32 {
33   this->Transform=vtkTransform::New();
34 //  this->DebugOn();
35 }
36 
37 // ----------------------------------------------------------------------------
~vtkTDxInteractorStyleGeo()38 vtkTDxInteractorStyleGeo::~vtkTDxInteractorStyleGeo()
39 {
40   this->Transform->Delete();
41 }
42 
43 // ----------------------------------------------------------------------------
OnMotionEvent(vtkTDxMotionEventInfo * motionInfo)44 void vtkTDxInteractorStyleGeo::OnMotionEvent(
45   vtkTDxMotionEventInfo *motionInfo)
46 {
47   assert("pre: motionInfo_exist" && motionInfo!=0);
48 
49   const double TyCalibration=0.1; // the value works well.
50   const double RxCalibration=0.1; // this value works well.
51 
52   vtkDebugMacro(<<"vtkTDxInteractorStyleGeo::OnMotionEvent()");
53 
54   if(this->Renderer==0 || this->Settings==0)
55     {
56     vtkDebugMacro(<<"vtkTDxInteractorStyleGeo::OnMotionEvent() no renderer or no settings");
57     return;
58     }
59 
60   vtkCamera *c=this->Renderer->GetActiveCamera();
61   vtkRenderWindow *w=this->Renderer->GetRenderWindow();
62   vtkRenderWindowInteractor *i=w->GetInteractor();
63 
64   vtkDebugMacro(<< "x=" << motionInfo->X << " y=" << motionInfo->Y << " z="
65                 << motionInfo->Z
66                 << " angle=" << motionInfo->Angle << " rx="
67                 << motionInfo->AxisX << " ry="
68                 << motionInfo->AxisY << " rz="<< motionInfo->AxisZ);
69 
70   vtkTransform *eyeToWorld=c->GetViewTransformObject();
71 
72   // Get the rotation axis in world coordinates.
73   this->Transform->Identity();
74   this->Transform->Concatenate(eyeToWorld);
75   this->Transform->Inverse();
76 
77   double xAxisEye[3];
78   double xAxisWorld[3];
79   xAxisEye[0]=1.0;
80   xAxisEye[1]=0.0;
81   xAxisEye[2]=0.0;
82   this->Transform->TransformVector(xAxisEye,xAxisWorld);
83 
84   double yAxisEye[3];
85   double yAxisWorld[3];
86   yAxisEye[0]=0.0;
87   yAxisEye[1]=1.0;
88   yAxisEye[2]=0.0;
89   this->Transform->TransformVector(yAxisEye,yAxisWorld);
90 
91   double zAxisEye[3];
92   double zAxisWorld[3];
93   zAxisEye[0]=0.0;
94   zAxisEye[1]=0.0;
95   zAxisEye[2]=1.0;
96 
97   this->Transform->TransformVector(zAxisEye,zAxisWorld);
98 
99   // Get the translation vector in world coordinates. Used at the end.
100   double translationEye[3];
101   double translationWorld[3];
102   translationEye[0]=0.0;
103   translationEye[1]=0.0;
104   translationEye[2]=TyCalibration*motionInfo->Y*
105     this->Settings->GetTranslationYSensitivity();
106 
107   this->Transform->TransformVector(translationEye,translationWorld);
108 
109   this->Transform->Identity();
110 
111   // default multiplication is "pre" which means applied to the "right" of
112   // the current matrix, which follows the OpenGL multiplication convention.
113 
114   double *p=c->GetFocalPoint();
115 
116   // 1. build the displacement (aka affine rotation) with the axes
117   // passing through the focal point.
118   this->Transform->Translate(p[0],p[1],p[2]);
119 
120   // Device X translation maps to camera Y rotation (west to east)
121   this->Transform->RotateWXYZ(
122     motionInfo->X*this->Settings->GetAngleSensitivity(),
123     yAxisWorld[0],yAxisWorld[1],yAxisWorld[2]);
124 
125   // Device Z translation maps to camera X rotation (south to north)
126   this->Transform->RotateWXYZ(
127     motionInfo->Z*this->Settings->GetAngleSensitivity(),
128     xAxisWorld[0],xAxisWorld[1],xAxisWorld[2]);
129 
130   // Device Y rotation maps to camera Z rotation (tilt)
131   this->Transform->RotateWXYZ(motionInfo->Angle*motionInfo->AxisY*
132                               this->Settings->GetAngleSensitivity(),
133                               zAxisWorld[0],zAxisWorld[1],zAxisWorld[2]);
134   this->Transform->Translate(-p[0],-p[1],-p[2]);
135 
136   //2. build the displacement (aka affine rotation) with the axes
137   // passing through the camera position.
138 
139   double *pos=c->GetPosition();
140   this->Transform->Translate(pos[0],pos[1],pos[2]);
141 
142   // Device X rotation maps to camera X rotation
143   this->Transform->RotateWXYZ(
144     RxCalibration*motionInfo->Angle*motionInfo->AxisX*
145     this->Settings->GetAngleSensitivity(),
146     xAxisWorld[0],xAxisWorld[1],xAxisWorld[2]);
147   this->Transform->Translate(-pos[0],-pos[1],-pos[2]);
148 
149 
150   // Apply the transform to the camera position
151   double newPosition[3];
152   this->Transform->TransformPoint(pos,newPosition);
153 
154   // 3. In addition position is translated (not the focal point)
155   newPosition[0]=newPosition[0]+translationWorld[0];
156   newPosition[1]=newPosition[1]+translationWorld[1];
157   newPosition[2]=newPosition[2]+translationWorld[2];
158 
159   // Apply the vector part of the transform to the camera view up vector
160   double *up=c->GetViewUp();
161   double newUp[3];
162   this->Transform->TransformVector(up,newUp);
163 
164   // Apply the transform to the camera focal point
165   double newFocalPoint[3];
166   this->Transform->TransformPoint(p,newFocalPoint);
167 
168   // Set the new view up vector and position of the camera.
169   c->SetViewUp(newUp);
170   c->SetPosition(newPosition);
171   c->SetFocalPoint(newFocalPoint);
172 
173   this->Renderer->ResetCameraClippingRange();
174 
175   // Display the result.
176   i->Render();
177 }
178 
179 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)180 void vtkTDxInteractorStyleGeo::PrintSelf(ostream& os, vtkIndent indent)
181 {
182   this->Superclass::PrintSelf(os,indent);
183 }
184