有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我正在尝试设置一个球体绕另一个球体旋转的动画,但是当它的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()+")";
    }
}

结果:


共 (1) 个答案

  1. # 1 楼答案

    需要在包含3D对象和/或变换的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参数是深度缓冲标志

    注意:这也适用于^{}


    您还提到必须将^{}设置为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会导致任何问题