]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java
9c444b4f7eac40aff2e6d5fe9af0f8a92c4681c3
[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                                 resetCameraClippingRange();
172                         } else {
173                                 cam.Dolly(zoomFactor);
174                                 resetCameraClippingRange();
175                         }
176                 }
177                 lastX = x;
178                 lastY = y;
179                 panel.refresh();
180                 return true;
181         }
182
183         @Override
184         public boolean mouseWheelMoved(MouseWheelEvent e) {
185                 double zoomFactor;
186                 // double clippingRange[];
187                 zoomFactor = Math.pow(1.02, (e.getWheelRotation()));
188                 if (cam.GetParallelProjection() == 1) {
189                         cam.SetParallelScale(cam.GetParallelScale() / zoomFactor);
190                 } else {
191                         cam.Dolly(zoomFactor);
192                         resetCameraClippingRange();
193                 }
194                 panel.refresh();
195                 return true;
196         }
197
198         protected List<vtkProp> selectActors = new ArrayList<vtkProp>();
199         protected List<vtkProp> hoverActor = new ArrayList<vtkProp>();
200
201         @Override
202         public boolean mouseClicked(MouseEvent e) {
203                 if (!panel.getComponent().isFocusControl())
204                         return false;
205                 if (e.getButton() != MouseEvent.BUTTON1)
206                         return false;
207                 vtkProp spick[] = panel.pick(e.getX(), e.getY());
208                 if (spick != null && spick.length > 0) {
209                         for (vtkProp selectActor : spick) {
210                                 if (!e.isControlDown()) {
211                                         selectActors.clear();
212                                         selectActors.add(selectActor);
213                                 } else {
214                                         if (selectActors.contains(selectActor))
215                                                 selectActors.remove(selectActor);
216                                         else
217                                                 selectActors.add(selectActor);
218                                 }
219                         }
220                         fireSelectionChanged();
221                 } else if (!e.isControlDown()) {
222                         selectActors.clear();
223                         fireSelectionChanged();
224                 }
225                 return true;
226                 // if (e.getClickCount() > 1)
227                 // updatePickRay(e.getX(), e.getY());
228
229         }
230
231         // private void updatePickRay(double x , double y) {
232         // Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(), x, y);
233         //
234         //
235         // System.out.println(ray.pos + " " + ray.dir);
236         // vtkPoints linePoints = new vtkPoints();
237         // linePoints.InsertPoint(0,ray.pos.x, ray.pos.y, ray.pos.z);
238         // linePoints.InsertPoint(1, ray.pos.x + ray.dir.x, ray.pos.y + ray.dir.y,
239         // ray.pos.z + ray.dir.z);
240         // vtkLine aLine = new vtkLine();
241         // aLine.GetPointIds().SetId(0, 0);
242         // aLine.GetPointIds().SetId(1, 1);
243         // vtkUnstructuredGrid aLineGrid = new vtkUnstructuredGrid();
244         // aLineGrid.Allocate(1, 1);
245         // aLineGrid.InsertNextCell(aLine.GetCellType(), aLine.GetPointIds());
246         // aLineGrid.SetPoints(linePoints);
247         // vtkDataSetMapper aLineMapper = new vtkDataSetMapper();
248         // aLineMapper.SetInput(aLineGrid);
249         // vtkActor aLineActor = new vtkActor();
250         // aLineActor.SetMapper(aLineMapper);
251         // aLineActor.GetProperty().SetDiffuseColor(.2, 1, 1);
252         //
253         // if (rayActor != null) {
254         // panel.GetRenderer().RemoveActor(rayActor);
255         // rayActor.Delete();
256         // }
257         // rayActor = aLineActor;
258         // panel.GetRenderer().AddActor(rayActor);
259         //
260         // linePoints.Delete();
261         // aLine.Delete();
262         // aLineGrid.Delete();
263         // aLineMapper.Delete();
264         // panel.repaint();
265         // }
266         //
267         // private vtkActor rayActor;
268
269         @Override
270         public boolean mouseMoved(MouseEvent e) {
271                 lastX = e.getX();
272                 lastY = e.getY();
273
274                 if (!panel.getComponent().isFocusControl())
275                         return false;
276                 List<vtkProp> prevHover = new ArrayList<vtkProp>();
277                 prevHover.addAll(hoverActor);
278                 hoverActor.clear();
279                 vtkProp pick[] = panel.pick(e.getX(), e.getY());
280                 if (pick != null) {
281                         for (vtkProp p : pick)
282                                 hoverActor.add(p);
283                 }
284
285                 if (!prevHover.containsAll(hoverActor) || !hoverActor.containsAll(prevHover)) {
286                         fireHoverChanged();
287                 }
288                 return true;
289         }
290
291         public List<vtkProp> getSelectActor() {
292                 return selectActors;
293         }
294
295         public List<vtkProp> getHoverActor() {
296                 return hoverActor;
297         }
298
299         private List<ISelectionChangedListener> selectionListeners = new ArrayList<ISelectionChangedListener>();
300
301         @Override
302         public void addSelectionChangedListener(ISelectionChangedListener listener) {
303                 selectionListeners.add(listener);
304         }
305
306         @Override
307         public ISelection getSelection() {
308                 return new StructuredSelection(selectActors);
309         }
310
311         @Override
312         public void removeSelectionChangedListener(ISelectionChangedListener listener) {
313                 selectionListeners.remove(listener);
314         }
315
316         @Override
317         public void setSelection(ISelection selection) {
318                 setSelection(selection, false);
319
320         }
321
322         public void setSelection(ISelection selection, boolean fire) {
323                 Collection<vtkProp> selectedProps = AdaptationUtils.adaptToCollection(selection, vtkProp.class);
324
325                 selectActors.clear();
326                 selectActors.addAll(selectedProps);
327                 if (fire)
328                         fireSelectionChanged();
329         }
330
331         protected void fireSelectionChanged() {
332                 Display.getDefault().asyncExec(new Runnable() {
333                         @Override
334                         public void run() {
335
336                                 SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this,
337                                                 new StructuredSelection(selectActors));
338                                 for (ISelectionChangedListener l : selectionListeners) {
339                                         l.selectionChanged(evt);
340                                 }
341
342                         }
343                 });
344         }
345
346         private List<ISelectionChangedListener> hoverListeners = new ArrayList<ISelectionChangedListener>();
347
348         public void addHoverChangedListener(ISelectionChangedListener listener) {
349                 hoverListeners.add(listener);
350         }
351
352         public ISelection getHoverSelection() {
353                 return new StructuredSelection(hoverActor);
354         }
355
356         public void removeHoverChangedListener(ISelectionChangedListener listener) {
357                 hoverListeners.remove(listener);
358         }
359
360         private void fireHoverChanged() {
361                 Display.getDefault().asyncExec(new Runnable() {
362                         @Override
363                         public void run() {
364                                 StructuredSelection sel = null;
365                                 if (hoverActor == null)
366                                         sel = new StructuredSelection();
367                                 else
368                                         sel = new StructuredSelection(hoverActor);
369                                 SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, sel);
370                                 for (ISelectionChangedListener l : hoverListeners) {
371                                         l.selectionChanged(evt);
372                                 }
373
374                         }
375                 });
376         }
377
378         public void focus(double x, double y, double z) {
379                 Lock();
380                 cam.SetFocalPoint(x, y, z);
381                 if (doNotRotate)
382                         cam.SetRoll(0);
383                 cam.OrthogonalizeViewUp();
384                 resetCameraClippingRange();
385                 // panel.UpdateLight();
386                 UnLock();
387         }
388
389 }