1 /*******************************************************************************
2 * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.g3d.vtk.swt;
14 import java.awt.event.InputEvent;
15 import java.awt.event.MouseEvent;
16 import java.awt.event.MouseWheelEvent;
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.List;
21 import org.eclipse.jface.viewers.ISelection;
22 import org.eclipse.jface.viewers.ISelectionChangedListener;
23 import org.eclipse.jface.viewers.ISelectionProvider;
24 import org.eclipse.jface.viewers.SelectionChangedEvent;
25 import org.eclipse.jface.viewers.StructuredSelection;
26 import org.eclipse.swt.widgets.Display;
27 import org.simantics.g3d.tools.AdaptationUtils;
31 import vtk.vtkRenderWindow;
32 import vtk.vtkRenderer;
34 public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelectionProvider {
36 protected vtkRenderer ren;
39 protected vtkRenderWindow rw;
40 protected vtkCamera cam;
41 protected int InteractionMode = 1;
43 protected double activeRate = 5.0;
44 protected double passiveRate = 0.01;
45 protected boolean doNotRotate = true;
47 public vtkCameraAndSelectorAction(InteractiveVtkComposite panel) {
49 this.ren = panel.getRenderer();
50 this.rw = panel.getRenderWindow();
51 this.cam = ren.GetActiveCamera();
58 public void UnLock() {
62 public void InteractionModeRotate() {
63 this.InteractionMode = 1;
66 public void InteractionModeTranslate() {
67 this.InteractionMode = 2;
70 public void InteractionModeZoom() {
71 this.InteractionMode = 3;
74 public void resetCameraClippingRange() {
76 ren.ResetCameraClippingRange();
80 public void resetCamera() {
86 public boolean mousePressed(MouseEvent e) {
88 if (ren.VisibleActorCount() == 0)
90 rw.SetDesiredUpdateRate(activeRate);
93 if ((e.getModifiers() == InputEvent.BUTTON2_MASK)
94 || (e.getModifiers() == (InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK))) {
95 InteractionModeTranslate();
96 } else if (e.getModifiers() == InputEvent.BUTTON3_MASK) {
97 InteractionModeZoom();
99 InteractionModeRotate();
104 public boolean mouseReleased(MouseEvent e) {
105 rw.SetDesiredUpdateRate(passiveRate);
109 public boolean mouseDragged(MouseEvent e) {
110 if (ren.VisibleActorCount() == 0)
115 if (this.InteractionMode == 1) {
116 cam.Azimuth(lastX - x);
117 cam.Elevation(y - lastY);
120 cam.OrthogonalizeViewUp();
121 resetCameraClippingRange();
122 // panel.UpdateLight();
125 if (this.InteractionMode == 2) {
128 double APoint[] = new double[3];
132 // get the current focal point and position
133 FPoint = cam.GetFocalPoint();
134 PPoint = cam.GetPosition();
136 // calculate the focal depth since we'll be using it a lot
137 ren.SetWorldPoint(FPoint[0], FPoint[1], FPoint[2], 1.0);
138 ren.WorldToDisplay();
139 focalDepth = ren.GetDisplayPoint()[2];
141 APoint[0] = rw.GetSize()[0] / 2.0 + (x - lastX);
142 APoint[1] = rw.GetSize()[1] / 2.0 - (y - lastY);
143 APoint[2] = focalDepth;
144 ren.SetDisplayPoint(APoint);
145 ren.DisplayToWorld();
146 RPoint = ren.GetWorldPoint();
147 if (RPoint[3] != 0.0) {
148 RPoint[0] = RPoint[0] / RPoint[3];
149 RPoint[1] = RPoint[1] / RPoint[3];
150 RPoint[2] = RPoint[2] / RPoint[3];
154 * Compute a translation vector, moving everything 1/2 the distance to the
155 * cursor. (Arbitrary scale factor)
157 cam.SetFocalPoint((FPoint[0] - RPoint[0]) / 2.0 + FPoint[0], (FPoint[1] - RPoint[1]) / 2.0 + FPoint[1],
158 (FPoint[2] - RPoint[2]) / 2.0 + FPoint[2]);
159 cam.SetPosition((FPoint[0] - RPoint[0]) / 2.0 + PPoint[0], (FPoint[1] - RPoint[1]) / 2.0 + PPoint[1],
160 (FPoint[2] - RPoint[2]) / 2.0 + PPoint[2]);
161 resetCameraClippingRange();
164 if (this.InteractionMode == 3) {
166 // double clippingRange[];
168 zoomFactor = Math.pow(1.02, (y - lastY));
169 if (cam.GetParallelProjection() == 1) {
170 cam.SetParallelScale(cam.GetParallelScale() / zoomFactor);
171 resetCameraClippingRange();
173 cam.Dolly(zoomFactor);
174 resetCameraClippingRange();
184 public boolean mouseWheelMoved(MouseWheelEvent e) {
186 // double clippingRange[];
187 zoomFactor = Math.pow(1.02, (e.getWheelRotation()));
188 if (cam.GetParallelProjection() == 1) {
189 cam.SetParallelScale(cam.GetParallelScale() / zoomFactor);
191 cam.Dolly(zoomFactor);
192 resetCameraClippingRange();
198 protected List<vtkProp> selectActors = new ArrayList<vtkProp>();
199 protected List<vtkProp> hoverActor = new ArrayList<vtkProp>();
202 public boolean mouseClicked(MouseEvent e) {
203 if (!panel.getComponent().isFocusControl())
205 if (e.getButton() != MouseEvent.BUTTON1)
207 vtkProp spick[] = panel.pick(e.getX(), e.getY());
208 if (spick != null && spick.length > 0) {
209 for (vtkProp selectActor : spick) {
210 if (!e.isControlDown()) {
211 selectActors.clear();
212 selectActors.add(selectActor);
214 if (selectActors.contains(selectActor))
215 selectActors.remove(selectActor);
217 selectActors.add(selectActor);
220 fireSelectionChanged();
221 } else if (!e.isControlDown()) {
222 selectActors.clear();
223 fireSelectionChanged();
226 // if (e.getClickCount() > 1)
227 // updatePickRay(e.getX(), e.getY());
231 // private void updatePickRay(double x , double y) {
232 // Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(), x, y);
235 // System.out.println(ray.pos + " " + ray.dir);
236 // vtkPoints linePoints = new vtkPoints();
237 // linePoints.InsertPoint(0,ray.pos.x, ray.pos.y, ray.pos.z);
238 // linePoints.InsertPoint(1, ray.pos.x + ray.dir.x, ray.pos.y + ray.dir.y,
239 // ray.pos.z + ray.dir.z);
240 // vtkLine aLine = new vtkLine();
241 // aLine.GetPointIds().SetId(0, 0);
242 // aLine.GetPointIds().SetId(1, 1);
243 // vtkUnstructuredGrid aLineGrid = new vtkUnstructuredGrid();
244 // aLineGrid.Allocate(1, 1);
245 // aLineGrid.InsertNextCell(aLine.GetCellType(), aLine.GetPointIds());
246 // aLineGrid.SetPoints(linePoints);
247 // vtkDataSetMapper aLineMapper = new vtkDataSetMapper();
248 // aLineMapper.SetInput(aLineGrid);
249 // vtkActor aLineActor = new vtkActor();
250 // aLineActor.SetMapper(aLineMapper);
251 // aLineActor.GetProperty().SetDiffuseColor(.2, 1, 1);
253 // if (rayActor != null) {
254 // panel.GetRenderer().RemoveActor(rayActor);
255 // rayActor.Delete();
257 // rayActor = aLineActor;
258 // panel.GetRenderer().AddActor(rayActor);
260 // linePoints.Delete();
262 // aLineGrid.Delete();
263 // aLineMapper.Delete();
267 // private vtkActor rayActor;
270 public boolean mouseMoved(MouseEvent e) {
274 if (!panel.getComponent().isFocusControl())
276 List<vtkProp> prevHover = new ArrayList<vtkProp>();
277 prevHover.addAll(hoverActor);
279 vtkProp pick[] = panel.pick(e.getX(), e.getY());
281 for (vtkProp p : pick)
285 if (!prevHover.containsAll(hoverActor) || !hoverActor.containsAll(prevHover)) {
291 public List<vtkProp> getSelectActor() {
295 public List<vtkProp> getHoverActor() {
299 private List<ISelectionChangedListener> selectionListeners = new ArrayList<ISelectionChangedListener>();
302 public void addSelectionChangedListener(ISelectionChangedListener listener) {
303 selectionListeners.add(listener);
307 public ISelection getSelection() {
308 return new StructuredSelection(selectActors);
312 public void removeSelectionChangedListener(ISelectionChangedListener listener) {
313 selectionListeners.remove(listener);
317 public void setSelection(ISelection selection) {
318 setSelection(selection, false);
322 public void setSelection(ISelection selection, boolean fire) {
323 Collection<vtkProp> selectedProps = AdaptationUtils.adaptToCollection(selection, vtkProp.class);
325 selectActors.clear();
326 selectActors.addAll(selectedProps);
328 fireSelectionChanged();
331 protected void fireSelectionChanged() {
332 Display.getDefault().asyncExec(new Runnable() {
336 SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this,
337 new StructuredSelection(selectActors));
338 for (ISelectionChangedListener l : selectionListeners) {
339 l.selectionChanged(evt);
346 private List<ISelectionChangedListener> hoverListeners = new ArrayList<ISelectionChangedListener>();
348 public void addHoverChangedListener(ISelectionChangedListener listener) {
349 hoverListeners.add(listener);
352 public ISelection getHoverSelection() {
353 return new StructuredSelection(hoverActor);
356 public void removeHoverChangedListener(ISelectionChangedListener listener) {
357 hoverListeners.remove(listener);
360 private void fireHoverChanged() {
361 Display.getDefault().asyncExec(new Runnable() {
364 StructuredSelection sel = null;
365 if (hoverActor == null)
366 sel = new StructuredSelection();
368 sel = new StructuredSelection(hoverActor);
369 SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, sel);
370 for (ISelectionChangedListener l : hoverListeners) {
371 l.selectionChanged(evt);
378 public void focus(double x, double y, double z) {
380 cam.SetFocalPoint(x, y, z);
383 cam.OrthogonalizeViewUp();
384 resetCameraClippingRange();
385 // panel.UpdateLight();