1
2 #include "QtVTKTouchscreenRenderWindows.h"
3 #include "ui_QtVTKTouchscreenRenderWindows.h"
4
5 // Available interactions:
6 // - Tap: Randomizes background color and moves the sphere actor to the location of the tap point
7 // = Touchscreen: 1 finger
8 // - Tap and hold: Switches camera between perspective and orthographic view and moves the cylinder
9 // to the location of the tap point
10 // = Touchscreen and MacOS trackpad: 1 finger
11 // - Swipe: Changes the color of the Square/Sphere/Cylinder based on the swipe angle. Angle -> Hue
12 // = Touchscreen: 3 fingers
13 // - Pinch : Zoom in and out the view, centered on the location of the pinch
14 // = Touchscreen and MacOS trackpad: 2 fingers
15 // - Rotate: Rotate the view, centered on the location of the pinch
16 // = Touchscreen and MacOS trackpad: 2 fingers
17 // - Pan: Translate the view
18 // = Touchscreen: 2+ fingers
19 // = MacOS trackpad: Long tap and move
20
21 #include <vtkActor.h>
22 #include <vtkCamera.h>
23 #include <vtkCollectionIterator.h>
24 #include <vtkCubeSource.h>
25 #include <vtkCylinderSource.h>
26 #include <vtkGenericOpenGLRenderWindow.h>
27 #include <vtkInteractorStyleMultiTouchCamera.h>
28 #include <vtkPlane.h>
29 #include <vtkPolyDataMapper.h>
30 #include <vtkProperty.h>
31 #include <vtkRenderer.h>
32 #include <vtkSphereSource.h>
33 #include <vtkTransform.h>
34
35 vtkNew<vtkActor> cubeActor;
36 vtkNew<vtkActor> sphereActor;
37 vtkNew<vtkActor> cylinderActor;
38
39 vtkNew<vtkSphereSource> sphereSource;
40 vtkNew<vtkCubeSource> cubeSource;
41 vtkNew<vtkCylinderSource> cylinderSource;
42
43 vtkNew<vtkTransform> sphereTransform;
44 vtkNew<vtkTransform> cubeTransform;
45 vtkNew<vtkTransform> cylinderTransform;
46
47 class vtkInteractorStyleMultiTouchCameraExample : public vtkInteractorStyleMultiTouchCamera
48 {
49 public:
50 static vtkInteractorStyleMultiTouchCameraExample* New();
51 vtkTypeMacro(vtkInteractorStyleMultiTouchCameraExample, vtkInteractorStyleMultiTouchCamera);
52
GetPickPosition(double pickPosition[4])53 void GetPickPosition(double pickPosition[4])
54 {
55 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
56 if (!camera)
57 {
58 return;
59 }
60
61 int pointer = this->Interactor->GetPointerIndex();
62
63 this->FindPokedRenderer(this->Interactor->GetEventPositions(pointer)[0],
64 this->Interactor->GetEventPositions(pointer)[1]);
65
66 double* focalPointWorld = camera->GetFocalPoint();
67 double focalPointDisplay[3] = { 0, 0, 0 };
68 vtkInteractorObserver::ComputeWorldToDisplay(this->CurrentRenderer, focalPointWorld[0],
69 focalPointWorld[1], focalPointWorld[2], focalPointDisplay);
70
71 // New position at the center of the pinch gesture
72 int* touchPositionDisplay = this->Interactor->GetEventPositions(pointer);
73 double pickPoint[4] = { 0, 0, 0, 0 };
74 vtkInteractorObserver::ComputeDisplayToWorld(this->CurrentRenderer, touchPositionDisplay[0],
75 touchPositionDisplay[1], focalPointDisplay[2], pickPosition);
76 }
77
OnLongTap()78 void OnLongTap() override
79 {
80 if (!this->CurrentRenderer)
81 {
82 return;
83 }
84
85 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
86 if (!camera)
87 {
88 return;
89 }
90
91 camera->SetParallelProjection(!camera->GetParallelProjection());
92
93 double pickPoint[4] = { 0, 0, 0, 0 };
94 this->GetPickPosition(pickPoint);
95 cylinderTransform->Identity();
96 cylinderTransform->Translate(pickPoint);
97
98 this->CurrentRenderer->Render();
99 }
100
OnTap()101 void OnTap() override
102 {
103 if (!this->CurrentRenderer)
104 {
105 return;
106 }
107
108 this->CurrentRenderer->SetBackground(
109 (double)rand() / RAND_MAX, (double)rand() / RAND_MAX, (double)rand() / RAND_MAX);
110
111 double pickPoint[4] = { 0, 0, 0, 0 };
112 this->GetPickPosition(pickPoint);
113 sphereTransform->Identity();
114 sphereTransform->Translate(pickPoint);
115
116 this->CurrentRenderer->Render();
117 }
118
119 bool IsSwiping = false;
OnStartSwipe()120 void OnStartSwipe() override
121 {
122 this->IsSwiping = true;
123 this->StartGesture();
124 }
125
OnEndSwipe()126 void OnEndSwipe() override
127 {
128 this->IsSwiping = false;
129 this->EndGesture();
130 }
131
OnSwipe()132 void OnSwipe() override
133 {
134 if (!this->CurrentRenderer)
135 {
136 return;
137 }
138
139 double hsv[3] = { this->Interactor->GetRotation() / 360.0, 1.0, 1.0 };
140 double rgb[3];
141 vtkMath::HSVToRGB(hsv, rgb);
142
143 cubeActor->GetProperty()->SetColor(rgb);
144 sphereActor->GetProperty()->SetColor(rgb);
145 cylinderActor->GetProperty()->SetColor(rgb);
146
147 this->CurrentRenderer->Render();
148 }
149
OnPinch()150 void OnPinch() override
151 {
152 if (this->IsSwiping)
153 {
154 return;
155 }
156 Superclass::OnPinch();
157 }
158
OnRotate()159 void OnRotate() override
160 {
161 if (this->IsSwiping)
162 {
163 return;
164 }
165 Superclass::OnRotate();
166 }
167
OnPan()168 void OnPan() override
169 {
170 if (this->IsSwiping)
171 {
172 return;
173 }
174 Superclass::OnPan();
175 }
176 };
177 vtkStandardNewMacro(vtkInteractorStyleMultiTouchCameraExample);
178
179 //------------------------------------------------------------------------------
QtVTKTouchscreenRenderWindows(int vtkNotUsed (argc),char * argv[])180 QtVTKTouchscreenRenderWindows::QtVTKTouchscreenRenderWindows(int vtkNotUsed(argc), char* argv[])
181 {
182 this->ui = new Ui_QtVTKTouchscreenRenderWindows;
183 this->ui->setupUi(this);
184
185 vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow =
186 vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
187 this->ui->view->setRenderWindow(renderWindow);
188
189 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
190 this->ui->view->renderWindow()->AddRenderer(renderer);
191
192 vtkRenderWindowInteractor* interactor = this->ui->view->interactor();
193 vtkSmartPointer<vtkInteractorStyleMultiTouchCameraExample> interactorStyle =
194 vtkSmartPointer<vtkInteractorStyleMultiTouchCameraExample>::New();
195 interactor->SetInteractorStyle(interactorStyle);
196 renderWindow->SetInteractor(interactor);
197
198 // Create a cube.
199 cubeSource->SetXLength(0.5);
200 cubeSource->SetYLength(0.5);
201 cubeSource->SetZLength(0.5);
202
203 // Create a mapper and actor.
204 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
205 mapper->SetInputConnection(cubeSource->GetOutputPort());
206 cubeActor->SetMapper(mapper);
207 renderer->AddActor(cubeActor);
208
209 // Create a sphere.
210 sphereSource->SetRadius(0.125);
211
212 // Create a mapper and actor.
213 vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
214 sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
215 sphereActor->SetMapper(sphereMapper);
216 sphereActor->SetUserTransform(sphereTransform);
217 renderer->AddActor(sphereActor);
218
219 // Create a cylinder.
220 cylinderSource->SetRadius(0.125);
221 cylinderSource->SetHeight(0.25);
222
223 // Create a mapper and actor.
224 vtkSmartPointer<vtkPolyDataMapper> cylinderMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
225 cylinderMapper->SetInputConnection(cylinderSource->GetOutputPort());
226 cylinderActor->SetMapper(cylinderMapper);
227 cylinderActor->SetUserTransform(cylinderTransform);
228 renderer->AddActor(cylinderActor);
229
230 renderer->SetBackground(0.1, 0.2, 0.4);
231 };
232