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