I'm trying to get a few shapes to "play nicely" with each other. I have 2 boxes next to each other and a cylinder "on top" of one of the boxes. I put them in a SubScene
with a camera that can zoom in and out with a scrolling operation and pan by dragging. Here is my MCVE:
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.Cylinder;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
public class MyApp extends Application {
DoubleProperty transX = new SimpleDoubleProperty();
DoubleProperty transY = new SimpleDoubleProperty();
DoubleProperty transZ = new SimpleDoubleProperty();
double startX, startY, curX, curY;
@Override
public void start(Stage stage) throws Exception {
Box box1 = new Box(30, 30, 5);
box1.setMaterial(new PhongMaterial(Color.RED));
Box box2 = new Box(30, 30, 5);
box2.setMaterial(new PhongMaterial(Color.GREEN));
box2.setTranslateX(32);
Cylinder cyn = new Cylinder(5, 15);
Group root = new Group(box1, box2, cyn);
root.getTransforms().addAll(new Translate(0, 0, 200),
new Rotate(-60, Rotate.X_AXIS),
new Rotate(-45, Rotate.Z_AXIS));
SubScene subs = new SubScene(root, 0, 0, true, SceneAntialiasing.BALANCED);
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.setFarClip(1000);
camera.setNearClip(0);
camera.translateZProperty().bind(transZ);
camera.translateXProperty().bind(transX);
camera.translateYProperty().bind(transY);
subs.setCamera(camera);
Pane pane = new Pane(subs);
pane.setStyle("-fx-border-color: red;" +
"-fx-border-width: 3;");
subs.widthProperty().bind(pane.widthProperty());
subs.heightProperty().bind(pane.heightProperty());
pane.setOnScroll(e -> transZ.set(transZ.get() + e.getDeltaY() * 0.2));
pane.setOnMousePressed(e -> {
startX = curX = e.getX();
startY = curY = e.getY();
});
pane.setOnMouseDragged(e -> {
startX = curX;
startY = curY;
curX = e.getX();
curY = e.getY();
double deltaX = curX - startX;
double deltaY = curY - startY;
double deltaZ = deltaY * Math.sqrt(3);
transX.set(transX.get() - deltaX);
transY.set(transY.get() - deltaY);
transZ.set(transZ.get() + deltaZ);
});
Scene scene = new Scene(pane, 500, 500);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
public static void main(String[] args) throws Exception {
launch(args);
}
}
I have 2 problems here:
the Z order is specified by the order in which I put them in the group. I want the Z order to "Take care of itself". If I have shapes in space with specific coordinates and sizes and a camera at a specific position and angle I should be seeing a unique view without needing to specify the order. Here is a picture:
it looks like the green box is closer to the camera than the red box but my code doesn't imply this.
the cylinder moves relative to the box when the camera pans. In the image I mark in blue lines the location of the cylinder on the red box:
and now i pan the camera and get
I want the relative location of the shapes to not change as I pan the camera.
Edit: i removed this from the question and ask it in another one:
the shapes are shown on top of the border:i thought that because the shapes are in the pane then pane's border will be higher in the Z order. I want the border to appear on top.