1

I've managed to move the camera using mouse drag. However, the problem is that once I've moved the camera and released the mouse press, the camera returns back to the origin.

I want the camera to remain in the changed position instead so that when I use the mouse again to move the camera, it moves from that position to wherever instead of from the origin.

package application;
    
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Sphere;


public class Main extends Application {
    
    private static final int WIDTH = 900;
    private static final int HEIGHT = 600;  

    //Tracks drag starting point for x and y
    private double anchorX, anchorY;
    
    @Override
    public void start(Stage primaryStage) {
        Sphere sphere = new Sphere(50);
        
        Group group = new Group();
        group.getChildren().add(sphere);
     
        Camera camera = new PerspectiveCamera();
        Scene scene = new Scene(group, WIDTH, HEIGHT);
        scene.setFill(Color.SILVER);
        scene.setCamera(camera);
     
        sphere.setTranslateX(WIDTH / 2);
        sphere.setTranslateY(HEIGHT / 2);
        
        initMouseControl(scene, camera, primaryStage, sphere);
     
        primaryStage.setTitle("Solar System Simulator");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    
    private void initMouseControl(Scene scene, Camera camera, Stage stage, Sphere sphere) {

           scene.setOnMousePressed(event -> {
                //Save start points
                anchorX = event.getSceneX();
                anchorY = event.getSceneY();
           });
         
           scene.setOnMouseDragged(event -> {
                camera.setTranslateY(anchorY - event.getSceneY());
                camera.setTranslateX(anchorX - event.getSceneX());
           });
           
           stage.addEventHandler(ScrollEvent.SCROLL, event -> {
               sphere.setTranslateZ(sphere.getTranslateZ() + event.getDeltaY());
           });
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}

I've tried googling to find a solution but couldn't find much on camera movement with javafx

2 Answers2

0

I don't know in how far Google can help you fix your logic problems. I did no further analysis of your code but at least each time when you press the mouse button your camera position is reset to zero by design. Your changes are not cumulative.

mipa
  • 10,369
  • 2
  • 16
  • 35
0

First of all, your scene does not have depth buffer enabled . These constructors enable 3d features in a scene instance Scene(Parent root,double width,double height,boolean depthBuffer) and Scene(Parent root,double width,double height,boolean depthBuffer,SceneAntialiasing antiAliasing) both with depthBufer boolean set to true. Second ,if you want to translate a node ; translate it getting its current coordinates and then add new coords . that will avoid reset coords . I divided the dragged result by 10 because it brought too high values

    public class Main extends Application {

    private static final int WIDTH = 900;
    private static final int HEIGHT = 600;

    //Tracks drag starting point for x and y
    private double anchorX, anchorY;

    @Override
    public void start(Stage primaryStage) {
        Sphere sphere = new Sphere(50);

        Group group = new Group();
        group.getChildren().add(sphere);

        Camera camera = new PerspectiveCamera();
        // for 3d  Scene constructor must have zbuffer= true and SceneAntialiasing
        Scene scene = new Scene(group, WIDTH, HEIGHT, true, SceneAntialiasing.BALANCED);
        scene.setFill(Color.SILVER);
        scene.setCamera(camera);

        sphere.setTranslateX(WIDTH / 2);
        sphere.setTranslateY(HEIGHT / 2);

        initMouseControl(scene, camera, primaryStage, sphere);

        primaryStage.setTitle("Solar System Simulator");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void initMouseControl(Scene scene, Camera camera, Stage stage, Sphere sphere) {

        scene.setOnMousePressed(event -> {
            //Save start points
            anchorX = event.getSceneX();
            anchorY = event.getSceneY();
        });
        // translating camera from its current coords pluss event 
        scene.setOnMouseDragged(event -> {
            camera.setTranslateY(camera.getTranslateY() + ((anchorY - event.getSceneY()) / 10));
            camera.setTranslateX(camera.getTranslateX() + ((anchorX - event.getSceneX()) / 10));
        });

        stage.addEventHandler(ScrollEvent.SCROLL, event -> {
            sphere.setTranslateZ(sphere.getTranslateZ() + event.getDeltaY());
        });
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Giovanni Contreras
  • 2,345
  • 1
  • 13
  • 22