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