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