]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java
7eb4cfc93d7d0df69ea3a6adc181b0360b693256
[simantics/3d.git] / org.simantics.g3d.vtk / src / org / simantics / g3d / vtk / swt / vtkCameraAndSelectorAction.java
1 /*******************************************************************************
2  * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.g3d.vtk.swt;
13
14 import java.awt.event.InputEvent;
15 import java.awt.event.MouseEvent;
16 import java.awt.event.MouseWheelEvent;
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.List;
20
21 import org.eclipse.jface.viewers.ISelection;
22 import org.eclipse.jface.viewers.ISelectionChangedListener;
23 import org.eclipse.jface.viewers.ISelectionProvider;
24 import org.eclipse.jface.viewers.SelectionChangedEvent;
25 import org.eclipse.jface.viewers.StructuredSelection;
26 import org.eclipse.swt.widgets.Display;
27 import org.simantics.g3d.tools.AdaptationUtils;
28
29 import vtk.vtkCamera;
30 import vtk.vtkProp;
31 import vtk.vtkRenderWindow;
32 import vtk.vtkRenderer;
33
34 public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelectionProvider {
35
36         protected vtkRenderer ren;
37         protected int lastX;
38         protected int lastY;
39         protected vtkRenderWindow rw;
40         protected vtkCamera cam;
41         protected int InteractionMode = 1;
42
43         protected double activeRate = 5.0;
44         protected double passiveRate = 0.01;
45         protected boolean doNotRotate = true;
46
47         public vtkCameraAndSelectorAction(InteractiveVtkComposite panel) {
48                 super(panel);
49                 this.ren = panel.getRenderer();
50                 this.rw = panel.getRenderWindow();
51                 this.cam = ren.GetActiveCamera();
52         }
53
54         public void Lock() {
55                 panel.lock();
56         }
57
58         public void UnLock() {
59                 panel.unlock();
60         }
61
62         public void InteractionModeRotate() {
63                 this.InteractionMode = 1;
64         }
65
66         public void InteractionModeTranslate() {
67                 this.InteractionMode = 2;
68         }
69
70         public void InteractionModeZoom() {
71                 this.InteractionMode = 3;
72         }
73
74         public void resetCameraClippingRange() {
75                 Lock();
76                 ren.ResetCameraClippingRange();
77                 UnLock();
78         }
79
80         public void resetCamera() {
81                 Lock();
82                 ren.ResetCamera();
83                 UnLock();
84         }
85
86         public boolean mousePressed(MouseEvent e) {
87
88                 if (ren.VisibleActorCount() == 0)
89                         return false;
90                 rw.SetDesiredUpdateRate(activeRate);
91                 lastX = e.getX();
92                 lastY = e.getY();
93                 if ((e.getModifiers() == InputEvent.BUTTON2_MASK)
94                                 || (e.getModifiers() == (InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK))) {
95                         InteractionModeTranslate();
96                 } else if (e.getModifiers() == InputEvent.BUTTON3_MASK) {
97                         InteractionModeZoom();
98                 } else {
99                         InteractionModeRotate();
100                 }
101                 return true;
102         }
103
104         public boolean mouseReleased(MouseEvent e) {
105                 rw.SetDesiredUpdateRate(passiveRate);
106                 return true;
107         }
108
109         public boolean mouseDragged(MouseEvent e) {
110                 if (ren.VisibleActorCount() == 0)
111                         return false;
112                 int x = e.getX();
113                 int y = e.getY();
114                 // rotate
115                 if (this.InteractionMode == 1) {
116                         cam.Azimuth(lastX - x);
117                         cam.Elevation(y - lastY);
118                         if (doNotRotate)
119                                 cam.SetRoll(0);
120                         cam.OrthogonalizeViewUp();
121                         resetCameraClippingRange();
122                         // panel.UpdateLight();
123                 }
124                 // translate
125                 if (this.InteractionMode == 2) {
126                         double FPoint[];
127                         double PPoint[];
128                         double APoint[] = new double[3];
129                         double RPoint[];
130                         double focalDepth;
131
132                         // get the current focal point and position
133                         FPoint = cam.GetFocalPoint();
134                         PPoint = cam.GetPosition();
135
136                         // calculate the focal depth since we'll be using it a lot
137                         ren.SetWorldPoint(FPoint[0], FPoint[1], FPoint[2], 1.0);
138                         ren.WorldToDisplay();
139                         focalDepth = ren.GetDisplayPoint()[2];
140
141                         APoint[0] = rw.GetSize()[0] / 2.0 + (x - lastX);
142                         APoint[1] = rw.GetSize()[1] / 2.0 - (y - lastY);
143                         APoint[2] = focalDepth;
144                         ren.SetDisplayPoint(APoint);
145                         ren.DisplayToWorld();
146                         RPoint = ren.GetWorldPoint();
147                         if (RPoint[3] != 0.0) {
148                                 RPoint[0] = RPoint[0] / RPoint[3];
149                                 RPoint[1] = RPoint[1] / RPoint[3];
150                                 RPoint[2] = RPoint[2] / RPoint[3];
151                         }
152
153                         /*
154                          * Compute a translation vector, moving everything 1/2 the distance to the
155                          * cursor. (Arbitrary scale factor)
156                          */
157                         cam.SetFocalPoint((FPoint[0] - RPoint[0]) / 2.0 + FPoint[0], (FPoint[1] - RPoint[1]) / 2.0 + FPoint[1],
158                                         (FPoint[2] - RPoint[2]) / 2.0 + FPoint[2]);
159                         cam.SetPosition((FPoint[0] - RPoint[0]) / 2.0 + PPoint[0], (FPoint[1] - RPoint[1]) / 2.0 + PPoint[1],
160                                         (FPoint[2] - RPoint[2]) / 2.0 + PPoint[2]);
161                         resetCameraClippingRange();
162                 }
163                 // zoom
164                 if (this.InteractionMode == 3) {
165                         double zoomFactor;
166                         // double clippingRange[];
167
168                         zoomFactor = Math.pow(1.02, (y - lastY));
169                         if (cam.GetParallelProjection() == 1) {
170                                 cam.SetParallelScale(cam.GetParallelScale() / zoomFactor);
171                         } else {
172                                 cam.Dolly(zoomFactor);
173                                 resetCameraClippingRange();
174                         }
175                 }
176                 lastX = x;
177                 lastY = y;
178                 panel.refresh();
179                 return true;
180         }
181
182         @Override
183         public boolean mouseWheelMoved(MouseWheelEvent e) {
184                 double zoomFactor;
185                 // double clippingRange[];
186                 zoomFactor = Math.pow(1.02, (e.getWheelRotation()));
187                 if (cam.GetParallelProjection() == 1) {
188                         cam.SetParallelScale(cam.GetParallelScale() / zoomFactor);
189                 } else {
190                         cam.Dolly(zoomFactor);
191                         resetCameraClippingRange();
192                 }
193                 panel.refresh();
194                 return true;
195         }
196
197         protected List<vtkProp> selectActors = new ArrayList<vtkProp>();
198         protected List<vtkProp> hoverActor = new ArrayList<vtkProp>();
199
200         @Override
201         public boolean mouseClicked(MouseEvent e) {
202                 if (!panel.getComponent().isFocusControl())
203                         return false;
204                 if (e.getButton() != MouseEvent.BUTTON1)
205                         return false;
206                 vtkProp spick[] = panel.pick(e.getX(), e.getY());
207                 if (spick != null && spick.length > 0) {
208                         for (vtkProp selectActor : spick) {
209                                 if (!e.isControlDown()) {
210                                         selectActors.clear();
211                                         selectActors.add(selectActor);
212                                 } else {
213                                         if (selectActors.contains(selectActor))
214                                                 selectActors.remove(selectActor);
215                                         else
216                                                 selectActors.add(selectActor);
217                                 }
218                         }
219                         fireSelectionChanged();
220                 } else if (!e.isControlDown()) {
221                         selectActors.clear();
222                         fireSelectionChanged();
223                 }
224                 return true;
225                 // if (e.getClickCount() > 1)
226                 // updatePickRay(e.getX(), e.getY());
227
228         }
229
230         // private void updatePickRay(double x , double y) {
231         // Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(), x, y);
232         //
233         //
234         // System.out.println(ray.pos + " " + ray.dir);
235         // vtkPoints linePoints = new vtkPoints();
236         // linePoints.InsertPoint(0,ray.pos.x, ray.pos.y, ray.pos.z);
237         // linePoints.InsertPoint(1, ray.pos.x + ray.dir.x, ray.pos.y + ray.dir.y,
238         // ray.pos.z + ray.dir.z);
239         // vtkLine aLine = new vtkLine();
240         // aLine.GetPointIds().SetId(0, 0);
241         // aLine.GetPointIds().SetId(1, 1);
242         // vtkUnstructuredGrid aLineGrid = new vtkUnstructuredGrid();
243         // aLineGrid.Allocate(1, 1);
244         // aLineGrid.InsertNextCell(aLine.GetCellType(), aLine.GetPointIds());
245         // aLineGrid.SetPoints(linePoints);
246         // vtkDataSetMapper aLineMapper = new vtkDataSetMapper();
247         // aLineMapper.SetInput(aLineGrid);
248         // vtkActor aLineActor = new vtkActor();
249         // aLineActor.SetMapper(aLineMapper);
250         // aLineActor.GetProperty().SetDiffuseColor(.2, 1, 1);
251         //
252         // if (rayActor != null) {
253         // panel.GetRenderer().RemoveActor(rayActor);
254         // rayActor.Delete();
255         // }
256         // rayActor = aLineActor;
257         // panel.GetRenderer().AddActor(rayActor);
258         //
259         // linePoints.Delete();
260         // aLine.Delete();
261         // aLineGrid.Delete();
262         // aLineMapper.Delete();
263         // panel.repaint();
264         // }
265         //
266         // private vtkActor rayActor;
267
268         @Override
269         public boolean mouseMoved(MouseEvent e) {
270                 lastX = e.getX();
271                 lastY = e.getY();
272
273                 if (!panel.getComponent().isFocusControl())
274                         return false;
275                 List<vtkProp> prevHover = new ArrayList<vtkProp>();
276                 prevHover.addAll(hoverActor);
277                 hoverActor.clear();
278                 vtkProp pick[] = panel.pick(e.getX(), e.getY());
279                 if (pick != null) {
280                         for (vtkProp p : pick)
281                                 hoverActor.add(p);
282                 }
283
284                 if (!prevHover.containsAll(hoverActor) || !hoverActor.containsAll(prevHover)) {
285                         fireHoverChanged();
286                 }
287                 return true;
288         }
289
290         public List<vtkProp> getSelectActor() {
291                 return selectActors;
292         }
293
294         public List<vtkProp> getHoverActor() {
295                 return hoverActor;
296         }
297
298         private List<ISelectionChangedListener> selectionListeners = new ArrayList<ISelectionChangedListener>();
299
300         @Override
301         public void addSelectionChangedListener(ISelectionChangedListener listener) {
302                 selectionListeners.add(listener);
303         }
304
305         @Override
306         public ISelection getSelection() {
307                 return new StructuredSelection(selectActors);
308         }
309
310         @Override
311         public void removeSelectionChangedListener(ISelectionChangedListener listener) {
312                 selectionListeners.remove(listener);
313         }
314
315         @Override
316         public void setSelection(ISelection selection) {
317                 setSelection(selection, false);
318
319         }
320
321         public void setSelection(ISelection selection, boolean fire) {
322                 Collection<vtkProp> selectedProps = AdaptationUtils.adaptToCollection(selection, vtkProp.class);
323
324                 selectActors.clear();
325                 selectActors.addAll(selectedProps);
326                 if (fire)
327                         fireSelectionChanged();
328         }
329
330         protected void fireSelectionChanged() {
331                 Display.getDefault().asyncExec(new Runnable() {
332                         @Override
333                         public void run() {
334
335                                 SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this,
336                                                 new StructuredSelection(selectActors));
337                                 for (ISelectionChangedListener l : selectionListeners) {
338                                         l.selectionChanged(evt);
339                                 }
340
341                         }
342                 });
343         }
344
345         private List<ISelectionChangedListener> hoverListeners = new ArrayList<ISelectionChangedListener>();
346
347         public void addHoverChangedListener(ISelectionChangedListener listener) {
348                 hoverListeners.add(listener);
349         }
350
351         public ISelection getHoverSelection() {
352                 return new StructuredSelection(hoverActor);
353         }
354
355         public void removeHoverChangedListener(ISelectionChangedListener listener) {
356                 hoverListeners.remove(listener);
357         }
358
359         private void fireHoverChanged() {
360                 Display.getDefault().asyncExec(new Runnable() {
361                         @Override
362                         public void run() {
363                                 StructuredSelection sel = null;
364                                 if (hoverActor == null)
365                                         sel = new StructuredSelection();
366                                 else
367                                         sel = new StructuredSelection(hoverActor);
368                                 SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, sel);
369                                 for (ISelectionChangedListener l : hoverListeners) {
370                                         l.selectionChanged(evt);
371                                 }
372
373                         }
374                 });
375         }
376
377         public void focus(double x, double y, double z) {
378                 Lock();
379                 cam.SetFocalPoint(x, y, z);
380                 if (doNotRotate)
381                         cam.SetRoll(0);
382                 cam.OrthogonalizeViewUp();
383                 resetCameraClippingRange();
384                 // panel.UpdateLight();
385                 UnLock();
386         }
387
388 }