0

I am trying to develop a tool with JavaFX that has multiple viewports and I think the best way to do that is through the use of SubScenes. One requirement I have is the ability to know where on a given plane in the scene corresponds to the pixel clicked by the mouse. I thought that I could use the Node.localToScreen() and Node.screenToLocal() functions to do this, however when adding a SubScene I get different values, despite nothing else changing.

Below is an example, where running the code with withSubScene = false, the console shows:

Point2D [x = 996.0, y = 514.8333400189878]
Point2D [x = 117.98005476276654, y = 514.8333400189878]

And running with withSubScene = true, the console shows:

Point2D [x = 997.0, y = 529.3333400189878]
Point2D [x = 64.91937872905163, y = 529.3333400189878]

Why would these values be different, when the camera is in the same location and looking at the same object?

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class ScreenToLocalTest extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        // Change this variable to swap to adding a SubScene
        boolean withSubScene = false;

        // Set the stage to be the same size each time
        primaryStage.setWidth(1000);
        primaryStage.setHeight(500);

        Group root = new Group();
        Scene rootScene = new Scene(root);

        // Create out camera
        Camera camera = new PerspectiveCamera(true);
        camera.setTranslateZ(-1000);
        camera.setNearClip(1);
        camera.setFarClip(10000);

        Group groupToAddRectangle;

        if(withSubScene) {
            Group sceneRoot = new Group();
            SubScene subScene = new SubScene(sceneRoot, primaryStage.getWidth(), primaryStage.getHeight());
            root.getChildren().add(subScene);

            subScene.setCamera(camera);

            groupToAddRectangle = sceneRoot;
        } else {
            rootScene.setCamera(camera);

            groupToAddRectangle = root;
        }

        Rectangle rectangle = new Rectangle(1000, 300, Color.ALICEBLUE);
        groupToAddRectangle.getChildren().add(rectangle);
        rectangle.setTranslateZ(1);

        root.setOnMouseMoved(event-> {
            System.out.println(rectangle.screenToLocal(event.getScreenX(), event.getScreenY()));
        });

        primaryStage.setScene(rootScene);
        primaryStage.show();


        System.out.println(rectangle.localToScreen(0, 0));
        rectangle.translateXProperty().set(-1000);
        System.out.println(rectangle.localToScreen(0, 0));
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Alan Race
  • 41
  • 3
  • 1
    This [question](https://stackoverflow.com/questions/52017893/how-to-get-2d-coordinates-on-window-for-3d-object-in-javafx) will help you. See edited part of accepted answer. – José Pereda Aug 07 '20 at 08:48
  • Thanks for pointing me to that question, however I still can't figure out how I can use that to convert to screen coordinates. I thought that I should be able to then do something like (but it still gives different results with and without the SubScene): Point2D locationInScreen = root.localToScreen(root.sceneToLocal(rectangle.localToScene(0, 0, true))); – Alan Race Aug 07 '20 at 09:47

0 Answers0