Java FX 3D:对象不遵守其 Z 坐标

Java FX 3D: Objects not respecting their Z coordinate

我正在尝试为一个围绕另一个球体运行的球体设置动画,但是当 Z 坐标变小时,前面的球体不会移动到第二个球体后面。

例如(0,0,1) 和(0,0,-1) 都出现在(0,0,0) 的前面,只是它们的大小因视角不同而不同。不知道如何解决这个问题或我做错了什么,Java FX 的新手!

public class Main extends Application {

    private static final int WIDTH = 1280;
    private static final int HEIGHT = 720;

    Planet earth = new Planet("Earth",50,0,0,0);
    Planet earth2 = new Planet("Earth 2",50,25,0,50);

    public void start(Stage primaryStage) throws Exception {
        Group group = new Group();
        group.getChildren().addAll(earth,earth2);
        PerspectiveCamera camera = new PerspectiveCamera();

        Scene scene = new Scene(group, WIDTH, HEIGHT);
        scene.setFill(Color.BLACK);
        scene.setCamera(camera);

        camera.setNearClip(0);
        camera.setFarClip(1000);
        camera.setTranslateX(-WIDTH/2);
        camera.setTranslateY(-HEIGHT/2);
        camera.setTranslateZ(-1000);

        primaryStage.setTitle("3D Scene");
        primaryStage.setScene(scene);
        primaryStage.show();
        timeline();
    }

    public static void main(String[] args) {
        launch(args);
    }

    private void timeline(){
        final long start = System.nanoTime();
        double FACTOR = 1;
        new AnimationTimer(){
            @Override
            public void handle(long now) {
                double t = (now-start)/1000000000.0;
                //System.out.println(t);
                //earth2.setTranslateX(150*Math.cos(t));
                earth2.setTranslateZ(150+500*Math.sin(t));
                earth.setPosition(0,0,0);
                System.out.println(earth2+" | "+earth);
            }
        }.start();
    }
}
public class Planet extends Sphere {

    private String name;

    public Planet(String name, double radius, double x, double y, double z){
        super(radius);
        setPosition(x,y,z);
        this.name = name;
    }

    public void setPosition(double x, double y, double z){
        setTranslateX(x);
        setTranslateY(y);
        setTranslateZ(z);
    }

    public void move(double x, double y, double z){
        translateXProperty().add(x);
        translateYProperty().add(y);
        translateZProperty().add(z);
    }

    @Override
    public String toString() {
        return "["+name+"] - ("+getTranslateX()+","+getTranslateY()+","+getTranslateZ()+")";
    }
}

结果:

您需要在包含 3D 对象 and/or 变换的 Scene 上启用深度缓冲。这里是 the documentation:

An application may request depth buffer support or scene anti-aliasing support at the creation of a Scene. A scene with only 2D shapes and without any 3D transforms does not need a depth buffer nor scene anti-aliasing support. A scene containing 3D shapes or 2D shapes with 3D transforms may use depth buffer support for proper depth sorted rendering; to avoid depth fighting (also known as Z fighting), disable depth testing on 2D shapes that have no 3D transforms. See depthTest for more information. A scene with 3D shapes may enable scene anti-aliasing to improve its rendering quality.

The depthBuffer and antiAliasing flags are conditional features. With the respective default values of: false and SceneAntialiasing.DISABLED. See ConditionalFeature.SCENE3D for more information.

实例化 Scene 后无法启用深度缓冲,您必须使用以下构造函数之一:

boolean参数是深度缓冲标志。

注意:这也适用于SubScene


您还提到您必须将 Camera#nearClip 设置为 0.01 而不是 0。为方便起见,这里是 属性:

的文档

Specifies the distance from the eye of the near clipping plane of this Camera in the eye coordinate space. Objects closer to the eye than nearClip are not drawn. nearClip is specified as a value greater than zero. A value less than or equal to zero is treated as a very small positive number.

Default value:
0.1

它说该值应该大于零。当然,它还表示值 <= 0 将被视为“ 非常小的正数 ”,我理解这意味着值 <= 0 将被解释作为任意接近 但仍大于 的数字,零。所以我不确定为什么将值设置为 0 会导致任何问题。