]> gerrit.simantics Code Review - simantics/3d.git/commitdiff
Camera rotation with stable rotation speed 54/3954/1
authorReino Ruusu <reino.ruusu@semantum.fi>
Mon, 2 Mar 2020 09:24:54 +0000 (11:24 +0200)
committerReino Ruusu <reino.ruusu@semantum.fi>
Mon, 2 Mar 2020 09:24:54 +0000 (11:24 +0200)
gitlab #96

Change-Id: Iaf9a1a42f04dcf83f168e2fe0aa691c26876b024

org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java

index ebdfb245219a43990271074a2d8f253ffdf774cf..7a0cc0314d228a793e73ce3b2c49fe6c70e425da 100644 (file)
@@ -118,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.SetViewUp(upDirection);
+                       cam.Azimuth(lastX - x);
                        cam.OrthogonalizeViewUp();
                        resetCameraClippingRange();
                        // panel.UpdateLight();
@@ -184,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;