]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java
96f51c699435bd26243304bbf41144326a059c0c
[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     private List<vtkProp> selectActors = new ArrayList<vtkProp>();
198     private 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     private 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 }