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=a5ea614978ee803a6df23c252205ad583f0a1622;hb=3ef62df14340e2127ce21fc7ccab1f69f832abc0;hp=7a6f0d894173ad29e8eebb48be2c18da39ad20e6;hpb=eb7456300253668862a71f9d07fb558400e6ace6;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 7a6f0d89..a5ea6149 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 @@ -18,6 +18,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import javax.vecmath.Vector3d; + import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; @@ -28,6 +30,7 @@ import org.simantics.g3d.tools.AdaptationUtils; import vtk.vtkCamera; import vtk.vtkProp; +import vtk.vtkProp3D; import vtk.vtkRenderWindow; import vtk.vtkRenderer; @@ -167,16 +170,13 @@ public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelecti // zoom if (this.InteractionMode == 3) { double zoomFactor; - // double clippingRange[]; - zoomFactor = Math.pow(1.02, (y - lastY)); + cam.Dolly(zoomFactor); + if (cam.GetParallelProjection() == 1) { - cam.SetParallelScale(cam.GetParallelScale() / zoomFactor); - resetCameraClippingRange(); - } else { - cam.Dolly(zoomFactor); - resetCameraClippingRange(); + updateParallelScale(); } + resetCameraClippingRange(); } lastX = x; lastY = y; @@ -208,16 +208,21 @@ public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelecti double zoomFactor; // double clippingRange[]; zoomFactor = Math.pow(1.02, (e.getWheelRotation())); - if (cam.GetParallelProjection() == 1) { - cam.SetParallelScale(cam.GetParallelScale() / zoomFactor); - } else { - cam.Dolly(zoomFactor); - resetCameraClippingRange(); - } + cam.Dolly(zoomFactor); + updateParallelScale(); + resetCameraClippingRange(); panel.refresh(); return true; } + private void updateParallelScale() { + // Make height of parallel projection match the distance + double distance = cam.GetDistance(); + double angle = cam.GetViewAngle(); + double scale = Math.tan(Math.toRadians(angle / 2)) * distance; + cam.SetParallelScale(scale); + } + protected List selectActors = new ArrayList(); protected List hoverActor = new ArrayList(); @@ -415,5 +420,61 @@ public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelecti // panel.UpdateLight(); UnLock(); } + + public void fitToView(Collection props) { + if (props.isEmpty()) + return; + + double[] bounds = new double[] { Double.MAX_VALUE, -Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE }, b = new double[6]; + for (vtkProp3D prop : props) { + prop.GetBounds(b); + for (int i = 0; i < 6; i+=2) + bounds[i] = Math.min(bounds[i], b[i]); + for (int i = 1; i < 6; i+=2) + bounds[i] = Math.max(bounds[i], b[i]); + } + + fitToView(bounds); + } + + public void fitToView(double[] bounds) { + Vector3d center = new Vector3d((bounds[0] + bounds[1])/2, (bounds[2] + bounds[3])/2, (bounds[4] + bounds[5])/2); + Vector3d viewDir = new Vector3d(cam.GetDirectionOfProjection()); + Vector3d upDir = new Vector3d(cam.GetViewUp()); + viewDir.normalize(); + upDir.normalize(); + Vector3d sideDir = new Vector3d(); + sideDir.cross(viewDir, upDir); + sideDir.normalize(); + + double width = getBoxWidth(bounds, sideDir); + double height = getBoxWidth(bounds, upDir); + double depth = getBoxWidth(bounds, viewDir); + + int[] size = rw.GetActualSize(); + + double distance1 = height / 2 / Math.tan(Math.toRadians(cam.GetViewAngle()) / 2); + double distance2 = distance1 * (width / size[0] / (height / size[1])); + + double distance = Math.max(distance1, distance2) + depth / 2; + + viewDir.scale(-distance); + viewDir.add(center); + + cam.SetPosition(viewDir.x, viewDir.y, viewDir.z); + focus(center.x, center.y, center.z); + + if (cam.GetParallelProjection() == 1) { + cam.SetParallelScale(Math.max(height, width * size[1] / size[0]) / 2); + } + } + + private static double getBoxWidth(double[] bounds, Vector3d dir) { + double dx = bounds[1] - bounds[0]; + double dy = bounds[3] - bounds[2]; + double dz = bounds[5] - bounds[4]; + + return Math.abs(dx * dir.x) + Math.abs(dy * dir.y) + Math.abs(dz * dir.z); + } }