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