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