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