Okay, this is driving me crazy. The documentation is pretty weak, the example application from Oracle is very weird, with a huge convoluted helper class, and even the questions about it on here have no answers!
I've largely followed and simplified this tutorial, but instead of rotating the object, I'm trying to rotate the camera, so when you drag the mouse, it should orbit the camera.
However, though I have confirmed via console logs and debugging that the event handlers are being called, and everything seems to have the right values, my rotates just never happen! What am I missing?
Furthermore, I can't manage to move the camera at all, even the (commented out) translateX
and the like don't work either, so I am quite stumped, but can't get the axis to look like anywhere but the upper left corner!
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
public class RotateCameraExample extends Group {
private double anchorX, anchorY;
private double anchorAngleX = 0;
private double anchorAngleY = 0;
private DoubleProperty angleX = new SimpleDoubleProperty(0);
private DoubleProperty angleY = new SimpleDoubleProperty(0);
Camera camera;
Group axes;
public RotateCameraExample() {
axes = buildAxes();
getChildren().add(axes);
camera = new PerspectiveCamera(true);
camera.setFarClip(6000);
camera.setNearClip(0.01);
//camera.translateYProperty().set(300); // this doesn't do anything! why?
getChildren().add(camera);
initMouseControl();
}
private void initMouseControl() {
Rotate xRotate = new Rotate(0, Rotate.X_AXIS);
Rotate yRotate = new Rotate(0, Rotate.Y_AXIS);
camera.getTransforms().addAll(xRotate, yRotate);
xRotate.angleProperty().bind(angleX);
yRotate.angleProperty().bind(angleY);
setOnMousePressed(event -> {
anchorX = event.getSceneX();
anchorY = event.getSceneY();
anchorAngleX = angleX.get();
anchorAngleY = angleY.get();
});
setOnMouseDragged(event -> {
angleX.set(anchorAngleX - (anchorY - event.getSceneY()));
angleY.set(anchorAngleY + anchorX - event.getSceneX());
});
}
private Group buildAxes() {
final Box xAxis = new Box(1200, 10, 10);
final Box yAxis = new Box(10, 1200, 10);
final Box zAxis = new Box(10, 10, 1200);
xAxis.setMaterial(new PhongMaterial(Color.RED));
yAxis.setMaterial(new PhongMaterial(Color.GREEN));
zAxis.setMaterial(new PhongMaterial(Color.BLUE));
Group axisGroup = new Group();
axisGroup.getChildren().addAll(xAxis, yAxis, zAxis);
return axisGroup;
}
}
Here can see that the axis is visible in the upper left, and I want it to remain at (0, 0, 0) while moving the camera around it.
Here is the Application
launch code, which is clearly not the issue:
public class TestApp extends Application {
@Override
public void start(Stage stage) throws IOException {
RotateCameraExample g = new RotateCameraExample();
Scene scene = new Scene(g, 800, 800, Color.BLACK);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}