title: JavaFX PickResult with SubScene gives wrong distance
body: <p>I am writing a program which uses simple 3D graphics and I have made it to a point where I need to drag objects with mouse. I have figured out how to do so <a href="https://stackoverflow.com/questions/28731460/javafx-moving-3d-objects-with-mouse-on-a-virtual-plane">here</a>, but unfortunately PickResult is acting weirdly with SubScene. I tested this with the code provided in the answers of the question (link above).</p>
  
  <p>If you put root into Scene, the distance is picked correctly. If used with SubScene, the getIntersectedDistance() method will return some kind of number based on window size - window height, specifically.</p>
  
  <p>If you use the getIntersectedPoint() - the coordinates are correct.</p>
  
  <p>I wrote my own methods of getting the camera to intersected point distance, but the calculations might not be very correct, so the dragging is still not on point.</p>
  
  <p>Why does this happen and how do I bypass it? Thanks in advance</p>
  
  <p>Below is the code I used to test this issue:</p>
  
  <pre><code>    public class Drag extends Application {
  
      private final Group root = new Group();
      private PerspectiveCamera camera;
      private final double sceneWidth = 800;
      private final double sceneHeight = 600;
  
      private double mousePosX;
      private double mousePosY;
      private double mouseOldX;
      private double mouseOldY;
      private final Rotate rotateX = new Rotate(-20, Rotate.X_AXIS);
      private final Rotate rotateY = new Rotate(-20, Rotate.Y_AXIS);
  
      private volatile boolean isPicking = false;
      private Point3D vecIni, vecPos;
      private double distance;
      private Sphere s;
  
      @Override
      public void start(Stage stage) {
          Box floor = new Box(1500, 10, 1500);
          floor.setMaterial(new PhongMaterial(Color.GRAY));
          floor.setTranslateY(150);
          root.getChildren().add(floor);
  
          Sphere sphere = new Sphere(40);
          sphere.setMaterial(new PhongMaterial(Color.RED));
          sphere.setTranslateY(-5);
          root.getChildren().add(sphere);
  
          camera = new PerspectiveCamera(true);
          camera.setVerticalFieldOfView(false);
  
          camera.setNearClip(0.1);
          camera.setFarClip(100000.0);
          camera.getTransforms().addAll(rotateX, rotateY, new Translate(0, 0, -3000));
  
          PointLight light = new PointLight(Color.GAINSBORO);
          root.getChildren().add(light);
          root.getChildren().add(new AmbientLight(Color.WHITE));
     /*Uncomment the section below to test subscene*/
     //SubScene subscene = new SubScene(root, sceneWidth, sceneHeight, true, SceneAntialiasing.BALANCED);
     //subscene.setFill(Color.web("3d3d3d"));
     //Pane pane = new Pane();
     //pane.getChildren().add(subscene);
     //Scene scene = new Scene(pane, 800,600);
     //stage.setScene(scene);
     //subscene.setCamera(camera);
     //System.out.println("SubScene built");
     /*Comment the section below to test subscene*/
          Scene scene = new Scene(root, sceneWidth, sceneHeight);
          scene.setFill(Color.web("3d3d3d"));
          stage.setScene(scene);
          scene.setCamera(camera);
          System.out.println("Scene built");
  /*                                          */
          scene.setOnMousePressed((MouseEvent me) -&gt; {
              mousePosX = me.getSceneX();
              mousePosY = me.getSceneY();
              PickResult pr = me.getPickResult();
              if (pr != null &amp;&amp; pr.getIntersectedNode() != null &amp;&amp; pr.getIntersectedNode() instanceof Sphere) {
                  System.out.println("getIntersectedDistance: " + distance);
                  System.out.println("getIntersectedPoint: " + pr.getIntersectedPoint().toString());
                  distance = pr.getIntersectedDistance();
  
                  s = (Sphere) pr.getIntersectedNode();
                  isPicking = true;
                  vecIni = unProjectDirection(mousePosX, mousePosY, scene.getWidth(), scene.getHeight());
              }
          });
          scene.setOnMouseDragged((MouseEvent me) -&gt; {
              mousePosX = me.getSceneX();
              mousePosY = me.getSceneY();
  
              if (isPicking) {
                  vecPos = unProjectDirection(mousePosX, mousePosY, scene.getWidth(), scene.getHeight());
  
                  Point3D p = vecPos.subtract(vecIni).multiply(distance);
                  s.getTransforms().add(new Translate(p.getX(), p.getY(), p.getZ()));
                  vecIni = vecPos;
                  PickResult pr = me.getPickResult();
              } else {
                  rotateX.setAngle(rotateX.getAngle() - (mousePosY - mouseOldY));
                  rotateY.setAngle(rotateY.getAngle() + (mousePosX - mouseOldX));
                  mouseOldX = mousePosX;
                  mouseOldY = mousePosY;
              }
          });
          scene.setOnMouseReleased((MouseEvent me) -&gt; {
              if (isPicking) {
                  isPicking = false;
              }
          });
          scene.setOnScroll((ScrollEvent event) -&gt; {
              double zoomFactor = camera.getTranslateZ();
              double deltaY = event.getDeltaY();
              if (deltaY &lt; 0) {
                  camera.setTranslateZ(zoomFactor + deltaY * 0.2);
              }
              if (deltaY &gt; 0) {
                  camera.setTranslateZ(zoomFactor + deltaY * 0.2);
              }
          });
  
          stage.setTitle("3D Dragging");
  
          stage.show();
      }
      /*
       From fx83dfeatures.Camera3D
       http://hg.openjdk.java.net/openjfx/8u-dev/rt/file/5d371a34ddf1/apps/toys/FX8-3DFeatures/src/fx83dfeatures/Camera3D.java
       */
      public Point3D unProjectDirection(double sceneX, double sceneY, double sWidth, double sHeight) {
          double tanHFov = Math.tan(Math.toRadians(camera.getFieldOfView()) * 0.5f);
          Point3D vMouse = new Point3D(tanHFov * (2 * sceneX / sWidth - 1), tanHFov * (2 * sceneY / sWidth - sHeight / sWidth), 1);
  
          Point3D result = localToSceneDirection(vMouse);
          return result.normalize();
      }
  
      public Point3D localToScene(Point3D pt) {
          Point3D res = camera.localToParentTransformProperty().get().transform(pt);
          if (camera.getParent() != null) {
              res = camera.getParent().localToSceneTransformProperty().get().transform(res);
          }
          return res;
      }
  
      public Point3D localToSceneDirection(Point3D dir) {
          Point3D res = localToScene(dir);
          return res.subtract(localToScene(new Point3D(0, 0, 0)));
      }
  
      public static void main(String[] args) {
          launch(args);
      }
  
  }
  </code></pre>
  
  <p>Edit: I've figured out a way to get the camera distance to the intersection point without using getIntersectedDistance method. If anyone is interested, feel free to ask.</p>