X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.g3d.vtk%2Fsrc%2Forg%2Fsimantics%2Fg3d%2Fvtk%2Fswt%2FvtkCameraAndSelectorAction.java;h=7a0cc0314d228a793e73ce3b2c49fe6c70e425da;hb=9077bfb55726c21bbaa09b5d2b6e11310b677c67;hp=7eb4cfc93d7d0df69ea3a6adc181b0360b693256;hpb=7531a473ca1fa611ae1a1b84b09f89effd4fa919;p=simantics%2F3d.git diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java index 7eb4cfc9..7a0cc031 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java @@ -43,6 +43,7 @@ public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelecti protected double activeRate = 5.0; protected double passiveRate = 0.01; protected boolean doNotRotate = true; + private double[] upDirection = new double[] { 0, 1, 0 }; public vtkCameraAndSelectorAction(InteractiveVtkComposite panel) { super(panel); @@ -50,6 +51,10 @@ public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelecti this.rw = panel.getRenderWindow(); this.cam = ren.GetActiveCamera(); } + + public void setUpDirection(double[] upDirection) { + this.upDirection = upDirection; + } public void Lock() { panel.lock(); @@ -113,10 +118,10 @@ public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelecti int y = e.getY(); // rotate if (this.InteractionMode == 1) { - cam.Azimuth(lastX - x); - cam.Elevation(y - lastY); + cam.Elevation(clampElevationDelta(y - lastY)); if (doNotRotate) - cam.SetRoll(0); + cam.SetViewUp(upDirection); + cam.Azimuth(lastX - x); cam.OrthogonalizeViewUp(); resetCameraClippingRange(); // panel.UpdateLight(); @@ -125,9 +130,8 @@ public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelecti if (this.InteractionMode == 2) { double FPoint[]; double PPoint[]; - double APoint[] = new double[3]; + double APoint[]; double RPoint[]; - double focalDepth; // get the current focal point and position FPoint = cam.GetFocalPoint(); @@ -136,14 +140,15 @@ public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelecti // 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; + APoint = ren.GetDisplayPoint(); + +// int[] size = rw.GetSize(); + APoint[0] -= x - lastX; + APoint[1] += y - lastY; 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]; @@ -154,10 +159,9 @@ public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelecti * 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]); + cam.SetFocalPoint(RPoint); + cam.SetPosition((RPoint[0] - FPoint[0]) + PPoint[0], (RPoint[1] - FPoint[1]) + PPoint[1], + (RPoint[2] - FPoint[2]) + PPoint[2]); resetCameraClippingRange(); } // zoom @@ -168,6 +172,7 @@ public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelecti zoomFactor = Math.pow(1.02, (y - lastY)); if (cam.GetParallelProjection() == 1) { cam.SetParallelScale(cam.GetParallelScale() / zoomFactor); + resetCameraClippingRange(); } else { cam.Dolly(zoomFactor); resetCameraClippingRange(); @@ -179,6 +184,25 @@ public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelecti return true; } + private static double dot(double[] a, double[] b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + } + + /** Calculate change in elevation, clamped to vertical directions. */ + private double clampElevationDelta(double elevationDelta) { + if (!doNotRotate) + return elevationDelta; + + double[] direction = cam.GetDirectionOfProjection(); + double d = Math.min(1.0, Math.max(-1.0, dot(direction, upDirection))); + double elevation = Math.toDegrees(Math.acos(d)) + elevationDelta; + if (elevation < 0) + elevationDelta -= elevation - 1e-5; + else if (elevation > 180) + elevationDelta -= elevation - 180 + 1e-5; + return elevationDelta; + } + @Override public boolean mouseWheelMoved(MouseWheelEvent e) { double zoomFactor; @@ -378,7 +402,7 @@ public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelecti Lock(); cam.SetFocalPoint(x, y, z); if (doNotRotate) - cam.SetRoll(0); + cam.SetViewUp(upDirection); cam.OrthogonalizeViewUp(); resetCameraClippingRange(); // panel.UpdateLight();