Issue
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
Solution
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);
}
}
Answered By - Giovanni Contreras
Answer Checked By - Robin (JavaFixing Admin)