]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkCameraAndSelectorAction.java
Scale tooltip font by display DPI.
[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                 if (hoverActor.size() > 0) {
200                         hoverActor.clear();
201                         fireHoverChanged();
202                 }
203                 lastX = x;
204                 lastY = y;
205                 panel.Render();
206         }
207
208         
209                 private List<vtkProp> selectActors = new ArrayList<vtkProp>();
210                 private List<vtkProp> hoverActor = new ArrayList<vtkProp>();
211         
212                 @Override
213                 public void mouseClicked(MouseEvent e) {
214                         if (!panel.isFocusOwner())
215                                 return;
216                         if (e.getButton() != MouseEvent.BUTTON1)
217                                 return;
218                         lastX = e.getX();
219                         lastY = e.getY();
220                         vtkProp spick[] = panel.pick(e.getX(), e.getY());
221                         if (spick != null && spick.length > 0) {
222                                 for (vtkProp selectActor : spick) {
223                                         if (!e.isControlDown()) {
224                                                 selectActors.clear();
225                                                 selectActors.add(selectActor);
226                                         } else {
227                                                 if (selectActors.contains(selectActor))
228                                                         selectActors.remove(selectActor);
229                                                 else
230                                                         selectActors.add(selectActor);
231                                         }
232                                 }
233                                 fireSelectionChanged();
234                         } else if (!e.isControlDown()) {
235                                 selectActors.clear();
236                                 fireSelectionChanged();
237                         }
238                         
239 //                      if (e.getClickCount() > 1)
240 //                              updatePickRay(e.getX(), e.getY());
241                         
242                 }
243                 
244 //              private void updatePickRay(double x , double y) {
245 //                      Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(), x, y);
246 //                      
247 //                      
248 //                      System.out.println(ray.pos + " " + ray.dir);
249 //                      vtkPoints linePoints = new vtkPoints();
250 //                      linePoints.InsertPoint(0,ray.pos.x, ray.pos.y, ray.pos.z);
251 //                      linePoints.InsertPoint(1, ray.pos.x + ray.dir.x, ray.pos.y + ray.dir.y, ray.pos.z + ray.dir.z);
252 //                      vtkLine aLine = new vtkLine();
253 //                      aLine.GetPointIds().SetId(0, 0);
254 //                      aLine.GetPointIds().SetId(1, 1);
255 //                      vtkUnstructuredGrid aLineGrid = new vtkUnstructuredGrid();
256 //                      aLineGrid.Allocate(1, 1);
257 //                      aLineGrid.InsertNextCell(aLine.GetCellType(), aLine.GetPointIds());
258 //                      aLineGrid.SetPoints(linePoints);
259 //                      vtkDataSetMapper aLineMapper = new vtkDataSetMapper();
260 //                      aLineMapper.SetInput(aLineGrid);
261 //                      vtkActor aLineActor = new vtkActor();
262 //                      aLineActor.SetMapper(aLineMapper);
263 //                      aLineActor.GetProperty().SetDiffuseColor(.2, 1, 1);
264 //                      
265 //                  if (rayActor != null) {
266 //                      panel.GetRenderer().RemoveActor(rayActor);
267 //                      rayActor.Delete();
268 //                  }
269 //                  rayActor = aLineActor;
270 //                  panel.GetRenderer().AddActor(rayActor);
271 //                  
272 //                  linePoints.Delete();
273 //                  aLine.Delete();
274 //                  aLineGrid.Delete();
275 //                  aLineMapper.Delete();
276 //                  panel.repaint();
277 //              }
278 //              
279 //              private vtkActor rayActor;
280                 
281                 @Override
282                 public void mouseMoved(MouseEvent e) {
283                         lastX = e.getX();
284                         lastY = e.getY();
285                         
286                         if (!panel.isFocusOwner())
287                                 return;
288                         List<vtkProp> prevHover = new ArrayList<vtkProp>();
289                         prevHover.addAll(hoverActor);
290                         hoverActor.clear();
291                         vtkProp pick[] =  panel.pick(e.getX(),e.getY());
292                         if (pick != null) {
293                                 for (vtkProp p : pick)
294                                         hoverActor.add(p);
295                         }
296                                 
297                         if (!prevHover.containsAll(hoverActor) || !hoverActor.containsAll(prevHover)) {
298                                 fireHoverChanged();
299                         }
300                 }
301                 
302                 @Override
303                 public void mouseExited(MouseEvent e) {
304                         if (hoverActor.size() > 0) {
305                                 hoverActor.clear();
306                                 fireHoverChanged();
307                         }
308                 }
309                 
310                 /**
311                  * Returns mouse position in AWT screen coordinates. 
312                  * @return
313                  */
314                 public Point2i getMousePositionAWT() {
315                         return new Point2i(lastX, lastY);
316                 }
317                 
318                 /**
319                  * Returns mouse position in VTK screen coordinates. 
320                  * @return
321                  */
322                 public Point2d getMousePosition() {
323                         return new Point2d(lastX, rw.GetSize()[1]-lastY);
324                 }
325                 
326                 public List<vtkProp> getSelectActor() {
327                         return selectActors;
328                 }
329                 
330                 public List<vtkProp> getHoverActor() {
331                         return hoverActor;
332                 }
333                 
334                 private List<ISelectionChangedListener> selectionListeners = new ArrayList<ISelectionChangedListener>();
335                 
336                 @Override
337                 public void addSelectionChangedListener(ISelectionChangedListener listener) {
338                         selectionListeners.add(listener);
339                 }
340                 
341                 @Override
342                 public ISelection getSelection() {
343                         return new StructuredSelection(selectActors);
344                 }
345                 
346                 @Override
347                 public void removeSelectionChangedListener(
348                                 ISelectionChangedListener listener) {
349                         selectionListeners.remove(listener);
350                 }
351                 
352                 @Override
353                 public void setSelection(ISelection selection) {
354                         setSelection(selection, false);
355
356                 }
357                 
358                 public void setSelection(ISelection selection, boolean fire) {
359                         Collection<vtkProp> selectedProps = AdaptationUtils.adaptToCollection(selection, vtkProp.class);
360                         
361                         selectActors.clear();
362                         selectActors.addAll(selectedProps);
363                         if (fire)
364                                 fireSelectionChanged();
365                 }
366                 
367                 private void fireSelectionChanged() {
368                         Display.getDefault().asyncExec(new Runnable() {
369                                 @Override
370                                 public void run() {
371                                         
372                                         SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, new StructuredSelection(selectActors));
373                                         for (ISelectionChangedListener l :selectionListeners) {
374                                                 l.selectionChanged(evt);
375                                         }
376                                         
377                                 }
378                         });
379                 }
380                 
381                 
382                 private List<ISelectionChangedListener> hoverListeners = new ArrayList<ISelectionChangedListener>();
383                 
384         
385                 public void addHoverChangedListener(ISelectionChangedListener listener) {
386                         hoverListeners.add(listener);
387                 }
388                 
389                 
390                 public ISelection getHoverSelection() {
391                         return new StructuredSelection(hoverActor);
392                 }
393                 
394                 public void removeHoverChangedListener(
395                                 ISelectionChangedListener listener) {
396                         hoverListeners.remove(listener);
397                 }
398
399                 private void fireHoverChanged() {
400                         Display.getDefault().asyncExec(new Runnable() {
401                                 @Override
402                                 public void run() {
403                                         StructuredSelection sel = null;
404                                         if (hoverActor == null)
405                                                 sel = new StructuredSelection();
406                                         else
407                                                 sel = new StructuredSelection(hoverActor);
408                                         SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, sel);
409                                         for (ISelectionChangedListener l :hoverListeners) {
410                                                 l.selectionChanged(evt);
411                                         }
412                                         
413                                 }
414                         });
415                 }
416                 
417                 public vtkCamera getCamera() {
418                         return cam;
419                 }
420                 
421                 public Point3d getPosition() {
422                         double pos[] = cam.GetPosition();
423                         return new Point3d(pos);
424                 }
425                 
426                 public Point3d getFocus() {
427                         double pos[] = cam.GetFocalPoint();
428                         return new Point3d(pos);
429                 }
430                 
431                 public void setFocus(Point3d focus) {
432                         setFocus(focus.x,focus.y,focus.z);
433                 }
434                 
435                 public void setFocus(double x, double y, double z) {
436                         Lock();
437                         cam.SetFocalPoint(x, y, z);
438                         if (doNotRotate)
439                                 cam.SetRoll(0);
440                         cam.OrthogonalizeViewUp();
441                         ren.ResetCameraClippingRange();
442                         panel.UpdateLight();
443                         UnLock();
444                 }
445                 
446                 public void setPosition(Point3d position) {
447                         setPosition(position.x,position.y,position.z);
448                 }
449                 
450                 public void setPosition(double x, double y, double z) {
451                         Lock();
452                         cam.SetPosition(x, y, z);
453                         if (doNotRotate)
454                                 cam.SetRoll(0);
455                         cam.OrthogonalizeViewUp();
456                         ren.ResetCameraClippingRange();
457                         panel.UpdateLight();
458                         UnLock();
459                 }
460                 
461                 
462                 
463                 
464 }