-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.vtk.action;\r
-\r
-import java.awt.event.InputEvent;\r
-import java.awt.event.MouseEvent;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-\r
-import org.eclipse.jface.viewers.ISelection;\r
-import org.eclipse.jface.viewers.ISelectionChangedListener;\r
-import org.eclipse.jface.viewers.ISelectionProvider;\r
-import org.eclipse.jface.viewers.SelectionChangedEvent;\r
-import org.eclipse.jface.viewers.StructuredSelection;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.simantics.g3d.tools.AdaptationUtils;\r
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;\r
-\r
-import vtk.vtkActor;\r
-import vtk.vtkCamera;\r
-import vtk.vtkProp;\r
-import vtk.vtkRenderWindow;\r
-import vtk.vtkRenderer;\r
-\r
-public class vtkCameraAndSelectorAction extends vtkAction implements ISelectionProvider {\r
- \r
- protected vtkRenderer ren;\r
- protected int lastX;\r
- protected int lastY;\r
- protected vtkRenderWindow rw;\r
- protected vtkCamera cam;\r
- protected int InteractionMode = 1;\r
- \r
- public vtkCameraAndSelectorAction(InteractiveVtkPanel panel) {\r
- super(panel);\r
- this.ren = panel.GetRenderer();\r
- this.rw = panel.GetRenderWindow();\r
- this.cam = ren.GetActiveCamera();\r
- }\r
- \r
- public void Lock() {\r
- panel.lock();\r
- }\r
- \r
- public void UnLock() {\r
- panel.unlock();\r
- }\r
- \r
- public void InteractionModeRotate()\r
- {\r
- this.InteractionMode = 1;\r
- }\r
- \r
- public void InteractionModeTranslate()\r
- {\r
- this.InteractionMode = 2;\r
- }\r
- \r
- public void InteractionModeZoom()\r
- {\r
- this.InteractionMode = 3;\r
- }\r
- \r
- public void resetCameraClippingRange() {\r
- Lock();\r
- ren.ResetCameraClippingRange();\r
- UnLock();\r
- }\r
-\r
- public void resetCamera() {\r
- Lock();\r
- ren.ResetCamera();\r
- UnLock();\r
- }\r
- \r
- public void mousePressed(MouseEvent e)\r
- {\r
- \r
- if (ren.VisibleActorCount() == 0) return;\r
- rw.SetDesiredUpdateRate(5.0);\r
- lastX = e.getX();\r
- lastY = e.getY();\r
- if ((e.getModifiers()==InputEvent.BUTTON2_MASK) ||\r
- (e.getModifiers()==(InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK)))\r
- {\r
- InteractionModeTranslate();\r
- }\r
- else if (e.getModifiers()==InputEvent.BUTTON3_MASK)\r
- {\r
- InteractionModeZoom();\r
- }\r
- else \r
- {\r
- InteractionModeRotate();\r
- }\r
- }\r
- \r
- public void mouseReleased(MouseEvent e)\r
- {\r
- rw.SetDesiredUpdateRate(0.01);\r
- }\r
- \r
-\r
- \r
- public void mouseDragged(MouseEvent e)\r
- {\r
- if (ren.VisibleActorCount() == 0) return;\r
- int x = e.getX();\r
- int y = e.getY();\r
- // rotate\r
- if (this.InteractionMode == 1)\r
- {\r
- cam.Azimuth(lastX - x);\r
- cam.Elevation(y - lastY);\r
- cam.OrthogonalizeViewUp();\r
- resetCameraClippingRange();\r
- panel.UpdateLight();\r
- }\r
- // translate\r
- if (this.InteractionMode == 2)\r
- {\r
- double FPoint[];\r
- double PPoint[];\r
- double APoint[] = new double[3];\r
- double RPoint[];\r
- double focalDepth;\r
- \r
- // get the current focal point and position\r
- FPoint = cam.GetFocalPoint();\r
- PPoint = cam.GetPosition();\r
- \r
- // calculate the focal depth since we'll be using it a lot\r
- ren.SetWorldPoint(FPoint[0],FPoint[1],FPoint[2],1.0);\r
- ren.WorldToDisplay();\r
- focalDepth = ren.GetDisplayPoint()[2];\r
- \r
- APoint[0] = rw.GetSize()[0]/2.0 + (x - lastX);\r
- APoint[1] = rw.GetSize()[1]/2.0 - (y - lastY);\r
- APoint[2] = focalDepth;\r
- ren.SetDisplayPoint(APoint);\r
- ren.DisplayToWorld();\r
- RPoint = ren.GetWorldPoint();\r
- if (RPoint[3] != 0.0)\r
- {\r
- RPoint[0] = RPoint[0]/RPoint[3];\r
- RPoint[1] = RPoint[1]/RPoint[3];\r
- RPoint[2] = RPoint[2]/RPoint[3];\r
- }\r
- \r
- /*\r
- * Compute a translation vector, moving everything 1/2 \r
- * the distance to the cursor. (Arbitrary scale factor)\r
- */\r
- cam.SetFocalPoint(\r
- (FPoint[0]-RPoint[0])/2.0 + FPoint[0],\r
- (FPoint[1]-RPoint[1])/2.0 + FPoint[1],\r
- (FPoint[2]-RPoint[2])/2.0 + FPoint[2]);\r
- cam.SetPosition(\r
- (FPoint[0]-RPoint[0])/2.0 + PPoint[0],\r
- (FPoint[1]-RPoint[1])/2.0 + PPoint[1],\r
- (FPoint[2]-RPoint[2])/2.0 + PPoint[2]);\r
- resetCameraClippingRange();\r
- }\r
- // zoom\r
- if (this.InteractionMode == 3)\r
- {\r
- double zoomFactor;\r
- //double clippingRange[];\r
- \r
- zoomFactor = Math.pow(1.02,(y - lastY));\r
- if (cam.GetParallelProjection() == 1)\r
- {\r
- cam.SetParallelScale(cam.GetParallelScale()/zoomFactor);\r
- }\r
- else\r
- {\r
- cam.Dolly(zoomFactor);\r
- resetCameraClippingRange();\r
- }\r
- }\r
- lastX = x;\r
- lastY = y;\r
- panel.Render();\r
- }\r
-\r
- \r
- private List<vtkProp> selectActors = new ArrayList<vtkProp>();\r
- private List<vtkProp> hoverActor = new ArrayList<vtkProp>();\r
- \r
- @Override\r
- public void mouseClicked(MouseEvent e) {\r
- if (!panel.isFocusOwner())\r
- return;\r
- if (e.getButton() != MouseEvent.BUTTON1)\r
- return;\r
- vtkProp spick[] = panel.pick(e.getX(), e.getY());\r
- if (spick != null && spick.length > 0) {\r
- for (vtkProp selectActor : spick) {\r
- if (!e.isControlDown()) {\r
- selectActors.clear();\r
- selectActors.add(selectActor);\r
- } else {\r
- if (selectActors.contains(selectActor))\r
- selectActors.remove(selectActor);\r
- else\r
- selectActors.add(selectActor);\r
- }\r
- }\r
- fireSelectionChanged();\r
- } else if (!e.isControlDown()) {\r
- selectActors.clear();\r
- fireSelectionChanged();\r
- }\r
- \r
-// if (e.getClickCount() > 1)\r
-// updatePickRay(e.getX(), e.getY());\r
- \r
- }\r
- \r
-// private void updatePickRay(double x , double y) {\r
-// Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(), x, y);\r
-// \r
-// \r
-// System.out.println(ray.pos + " " + ray.dir);\r
-// vtkPoints linePoints = new vtkPoints();\r
-// linePoints.InsertPoint(0,ray.pos.x, ray.pos.y, ray.pos.z);\r
-// linePoints.InsertPoint(1, ray.pos.x + ray.dir.x, ray.pos.y + ray.dir.y, ray.pos.z + ray.dir.z);\r
-// vtkLine aLine = new vtkLine();\r
-// aLine.GetPointIds().SetId(0, 0);\r
-// aLine.GetPointIds().SetId(1, 1);\r
-// vtkUnstructuredGrid aLineGrid = new vtkUnstructuredGrid();\r
-// aLineGrid.Allocate(1, 1);\r
-// aLineGrid.InsertNextCell(aLine.GetCellType(), aLine.GetPointIds());\r
-// aLineGrid.SetPoints(linePoints);\r
-// vtkDataSetMapper aLineMapper = new vtkDataSetMapper();\r
-// aLineMapper.SetInput(aLineGrid);\r
-// vtkActor aLineActor = new vtkActor();\r
-// aLineActor.SetMapper(aLineMapper);\r
-// aLineActor.GetProperty().SetDiffuseColor(.2, 1, 1);\r
-// \r
-// if (rayActor != null) {\r
-// panel.GetRenderer().RemoveActor(rayActor);\r
-// rayActor.Delete();\r
-// }\r
-// rayActor = aLineActor;\r
-// panel.GetRenderer().AddActor(rayActor);\r
-// \r
-// linePoints.Delete();\r
-// aLine.Delete();\r
-// aLineGrid.Delete();\r
-// aLineMapper.Delete();\r
-// panel.repaint();\r
-// }\r
-// \r
-// private vtkActor rayActor;\r
- \r
- @Override\r
- public void mouseMoved(MouseEvent e) {\r
- lastX = e.getX();\r
- lastY = e.getY();\r
- \r
- if (!panel.isFocusOwner())\r
- return;\r
- List<vtkProp> prevHover = new ArrayList<vtkProp>();\r
- prevHover.addAll(hoverActor);\r
- hoverActor.clear();\r
- vtkProp pick[] = panel.pick(e.getX(),e.getY());\r
- if (pick != null) {\r
- for (vtkProp p : pick)\r
- hoverActor.add(p);\r
- }\r
- \r
- if (!prevHover.containsAll(hoverActor) || !hoverActor.containsAll(prevHover)) {\r
- fireHoverChanged();\r
- }\r
- }\r
- \r
- public List<vtkProp> getSelectActor() {\r
- return selectActors;\r
- }\r
- \r
- public List<vtkProp> getHoverActor() {\r
- return hoverActor;\r
- }\r
- \r
- private List<ISelectionChangedListener> selectionListeners = new ArrayList<ISelectionChangedListener>();\r
- \r
- @Override\r
- public void addSelectionChangedListener(ISelectionChangedListener listener) {\r
- selectionListeners.add(listener);\r
- }\r
- \r
- @Override\r
- public ISelection getSelection() {\r
- return new StructuredSelection(selectActors);\r
- }\r
- \r
- @Override\r
- public void removeSelectionChangedListener(\r
- ISelectionChangedListener listener) {\r
- selectionListeners.remove(listener);\r
- }\r
- \r
- @Override\r
- public void setSelection(ISelection selection) {\r
- setSelection(selection, false);\r
-\r
- }\r
- \r
- public void setSelection(ISelection selection, boolean fire) {\r
- Collection<vtkProp> selectedProps = AdaptationUtils.adaptToCollection(selection, vtkProp.class);\r
- \r
- selectActors.clear();\r
- selectActors.addAll(selectedProps);\r
- if (fire)\r
- fireSelectionChanged();\r
- }\r
- \r
- private void fireSelectionChanged() {\r
- Display.getDefault().asyncExec(new Runnable() {\r
- @Override\r
- public void run() {\r
- \r
- SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, new StructuredSelection(selectActors));\r
- for (ISelectionChangedListener l :selectionListeners) {\r
- l.selectionChanged(evt);\r
- }\r
- \r
- }\r
- });\r
- }\r
- \r
- \r
- private List<ISelectionChangedListener> hoverListeners = new ArrayList<ISelectionChangedListener>();\r
- \r
- \r
- public void addHoverChangedListener(ISelectionChangedListener listener) {\r
- hoverListeners.add(listener);\r
- }\r
- \r
- \r
- public ISelection getHoverSelection() {\r
- return new StructuredSelection(hoverActor);\r
- }\r
- \r
- public void removeHoverChangedListener(\r
- ISelectionChangedListener listener) {\r
- hoverListeners.remove(listener);\r
- }\r
-\r
- private void fireHoverChanged() {\r
- Display.getDefault().asyncExec(new Runnable() {\r
- @Override\r
- public void run() {\r
- StructuredSelection sel = null;\r
- if (hoverActor == null)\r
- sel = new StructuredSelection();\r
- else\r
- sel = new StructuredSelection(hoverActor);\r
- SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, sel);\r
- for (ISelectionChangedListener l :hoverListeners) {\r
- l.selectionChanged(evt);\r
- }\r
- \r
- }\r
- });\r
- }\r
- \r
- \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.vtk.action;
+
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.widgets.Display;
+import org.simantics.g3d.tools.AdaptationUtils;
+import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
+
+import vtk.vtkCamera;
+import vtk.vtkProp;
+import vtk.vtkRenderWindow;
+import vtk.vtkRenderer;
+
+public class vtkCameraAndSelectorAction extends vtkAction implements ISelectionProvider {
+
+ protected vtkRenderer ren;
+ protected int lastX;
+ protected int lastY;
+ protected vtkRenderWindow rw;
+ protected vtkCamera cam;
+ protected int InteractionMode = 1;
+
+ protected double activeRate = 5.0;
+ protected double passiveRate = 0.01;
+ protected boolean doNotRotate = true;
+
+ public vtkCameraAndSelectorAction(InteractiveVtkPanel panel) {
+ super(panel);
+ this.ren = panel.GetRenderer();
+ this.rw = panel.GetRenderWindow();
+ this.cam = ren.GetActiveCamera();
+ }
+
+ public void Lock() {
+ panel.lock();
+ }
+
+ public void UnLock() {
+ panel.unlock();
+ }
+
+ public void InteractionModeRotate()
+ {
+ this.InteractionMode = 1;
+ }
+
+ public void InteractionModeTranslate()
+ {
+ this.InteractionMode = 2;
+ }
+
+ public void InteractionModeZoom()
+ {
+ this.InteractionMode = 3;
+ }
+
+ public void resetCameraClippingRange() {
+ Lock();
+ ren.ResetCameraClippingRange();
+ UnLock();
+ }
+
+ public void resetCamera() {
+ Lock();
+ ren.ResetCamera();
+ UnLock();
+ }
+
+ public void mousePressed(MouseEvent e)
+ {
+
+ if (ren.VisibleActorCount() == 0) return;
+ rw.SetDesiredUpdateRate(activeRate);
+ lastX = e.getX();
+ lastY = e.getY();
+ if ((e.getModifiers()==InputEvent.BUTTON2_MASK) ||
+ (e.getModifiers()==(InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK)))
+ {
+ InteractionModeTranslate();
+ }
+ else if (e.getModifiers()==InputEvent.BUTTON3_MASK)
+ {
+ InteractionModeZoom();
+ }
+ else
+ {
+ InteractionModeRotate();
+ }
+ }
+
+ public void mouseReleased(MouseEvent e)
+ {
+ rw.SetDesiredUpdateRate(passiveRate);
+ }
+
+
+
+ public void mouseDragged(MouseEvent e)
+ {
+ if (ren.VisibleActorCount() == 0) return;
+ int x = e.getX();
+ int y = e.getY();
+ // rotate
+ if (this.InteractionMode == 1)
+ {
+ cam.Azimuth(lastX - x);
+ cam.Elevation(y - lastY);
+ if (doNotRotate)
+ cam.SetRoll(0);
+ cam.OrthogonalizeViewUp();
+ resetCameraClippingRange();
+ panel.UpdateLight();
+ }
+ // translate
+ if (this.InteractionMode == 2)
+ {
+ double FPoint[];
+ double PPoint[];
+ double APoint[] = new double[3];
+ double RPoint[];
+ double focalDepth;
+
+ // get the current focal point and position
+ FPoint = cam.GetFocalPoint();
+ PPoint = cam.GetPosition();
+
+ // calculate the focal depth since we'll be using it a lot
+ ren.SetWorldPoint(FPoint[0],FPoint[1],FPoint[2],1.0);
+ ren.WorldToDisplay();
+ focalDepth = ren.GetDisplayPoint()[2];
+
+ APoint[0] = rw.GetSize()[0]/2.0 + (x - lastX);
+ APoint[1] = rw.GetSize()[1]/2.0 - (y - lastY);
+ APoint[2] = focalDepth;
+ ren.SetDisplayPoint(APoint);
+ ren.DisplayToWorld();
+ RPoint = ren.GetWorldPoint();
+ if (RPoint[3] != 0.0)
+ {
+ RPoint[0] = RPoint[0]/RPoint[3];
+ RPoint[1] = RPoint[1]/RPoint[3];
+ RPoint[2] = RPoint[2]/RPoint[3];
+ }
+
+ /*
+ * Compute a translation vector, moving everything 1/2
+ * the distance to the cursor. (Arbitrary scale factor)
+ */
+ cam.SetFocalPoint(
+ (FPoint[0]-RPoint[0])/2.0 + FPoint[0],
+ (FPoint[1]-RPoint[1])/2.0 + FPoint[1],
+ (FPoint[2]-RPoint[2])/2.0 + FPoint[2]);
+ cam.SetPosition(
+ (FPoint[0]-RPoint[0])/2.0 + PPoint[0],
+ (FPoint[1]-RPoint[1])/2.0 + PPoint[1],
+ (FPoint[2]-RPoint[2])/2.0 + PPoint[2]);
+ resetCameraClippingRange();
+ }
+ // zoom
+ if (this.InteractionMode == 3)
+ {
+ double zoomFactor;
+ //double clippingRange[];
+
+ zoomFactor = Math.pow(1.02,(y - lastY));
+ if (cam.GetParallelProjection() == 1)
+ {
+ cam.SetParallelScale(cam.GetParallelScale()/zoomFactor);
+ }
+ else
+ {
+ cam.Dolly(zoomFactor);
+ resetCameraClippingRange();
+ }
+ }
+ lastX = x;
+ lastY = y;
+ panel.Render();
+ }
+
+
+ private List<vtkProp> selectActors = new ArrayList<vtkProp>();
+ private List<vtkProp> hoverActor = new ArrayList<vtkProp>();
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (!panel.isFocusOwner())
+ return;
+ if (e.getButton() != MouseEvent.BUTTON1)
+ return;
+ vtkProp spick[] = panel.pick(e.getX(), e.getY());
+ if (spick != null && spick.length > 0) {
+ for (vtkProp selectActor : spick) {
+ if (!e.isControlDown()) {
+ selectActors.clear();
+ selectActors.add(selectActor);
+ } else {
+ if (selectActors.contains(selectActor))
+ selectActors.remove(selectActor);
+ else
+ selectActors.add(selectActor);
+ }
+ }
+ fireSelectionChanged();
+ } else if (!e.isControlDown()) {
+ selectActors.clear();
+ fireSelectionChanged();
+ }
+
+// if (e.getClickCount() > 1)
+// updatePickRay(e.getX(), e.getY());
+
+ }
+
+// private void updatePickRay(double x , double y) {
+// Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(), x, y);
+//
+//
+// System.out.println(ray.pos + " " + ray.dir);
+// vtkPoints linePoints = new vtkPoints();
+// linePoints.InsertPoint(0,ray.pos.x, ray.pos.y, ray.pos.z);
+// linePoints.InsertPoint(1, ray.pos.x + ray.dir.x, ray.pos.y + ray.dir.y, ray.pos.z + ray.dir.z);
+// vtkLine aLine = new vtkLine();
+// aLine.GetPointIds().SetId(0, 0);
+// aLine.GetPointIds().SetId(1, 1);
+// vtkUnstructuredGrid aLineGrid = new vtkUnstructuredGrid();
+// aLineGrid.Allocate(1, 1);
+// aLineGrid.InsertNextCell(aLine.GetCellType(), aLine.GetPointIds());
+// aLineGrid.SetPoints(linePoints);
+// vtkDataSetMapper aLineMapper = new vtkDataSetMapper();
+// aLineMapper.SetInput(aLineGrid);
+// vtkActor aLineActor = new vtkActor();
+// aLineActor.SetMapper(aLineMapper);
+// aLineActor.GetProperty().SetDiffuseColor(.2, 1, 1);
+//
+// if (rayActor != null) {
+// panel.GetRenderer().RemoveActor(rayActor);
+// rayActor.Delete();
+// }
+// rayActor = aLineActor;
+// panel.GetRenderer().AddActor(rayActor);
+//
+// linePoints.Delete();
+// aLine.Delete();
+// aLineGrid.Delete();
+// aLineMapper.Delete();
+// panel.repaint();
+// }
+//
+// private vtkActor rayActor;
+
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ lastX = e.getX();
+ lastY = e.getY();
+
+ if (!panel.isFocusOwner())
+ return;
+ List<vtkProp> prevHover = new ArrayList<vtkProp>();
+ prevHover.addAll(hoverActor);
+ hoverActor.clear();
+ vtkProp pick[] = panel.pick(e.getX(),e.getY());
+ if (pick != null) {
+ for (vtkProp p : pick)
+ hoverActor.add(p);
+ }
+
+ if (!prevHover.containsAll(hoverActor) || !hoverActor.containsAll(prevHover)) {
+ fireHoverChanged();
+ }
+ }
+
+ public List<vtkProp> getSelectActor() {
+ return selectActors;
+ }
+
+ public List<vtkProp> getHoverActor() {
+ return hoverActor;
+ }
+
+ private List<ISelectionChangedListener> selectionListeners = new ArrayList<ISelectionChangedListener>();
+
+ @Override
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ selectionListeners.add(listener);
+ }
+
+ @Override
+ public ISelection getSelection() {
+ return new StructuredSelection(selectActors);
+ }
+
+ @Override
+ public void removeSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ selectionListeners.remove(listener);
+ }
+
+ @Override
+ public void setSelection(ISelection selection) {
+ setSelection(selection, false);
+
+ }
+
+ public void setSelection(ISelection selection, boolean fire) {
+ Collection<vtkProp> selectedProps = AdaptationUtils.adaptToCollection(selection, vtkProp.class);
+
+ selectActors.clear();
+ selectActors.addAll(selectedProps);
+ if (fire)
+ fireSelectionChanged();
+ }
+
+ private void fireSelectionChanged() {
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+
+ SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, new StructuredSelection(selectActors));
+ for (ISelectionChangedListener l :selectionListeners) {
+ l.selectionChanged(evt);
+ }
+
+ }
+ });
+ }
+
+
+ private List<ISelectionChangedListener> hoverListeners = new ArrayList<ISelectionChangedListener>();
+
+
+ public void addHoverChangedListener(ISelectionChangedListener listener) {
+ hoverListeners.add(listener);
+ }
+
+
+ public ISelection getHoverSelection() {
+ return new StructuredSelection(hoverActor);
+ }
+
+ public void removeHoverChangedListener(
+ ISelectionChangedListener listener) {
+ hoverListeners.remove(listener);
+ }
+
+ private void fireHoverChanged() {
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ StructuredSelection sel = null;
+ if (hoverActor == null)
+ sel = new StructuredSelection();
+ else
+ sel = new StructuredSelection(hoverActor);
+ SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, sel);
+ for (ISelectionChangedListener l :hoverListeners) {
+ l.selectionChanged(evt);
+ }
+
+ }
+ });
+ }
+
+ public void focus(double x, double y, double z) {
+ Lock();
+ cam.SetFocalPoint(x, y, z);
+ UnLock();
+ }
+
+
+}