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