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

问题描述 投票:1回答:1

我正在尝试使一个球体绕另一个球体运动,但是当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()+")";
    }
}

结果:

java 3d javafx-8
1个回答
0
投票

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

应用程序可以在创建Scene时请求深度缓冲区支持或场景抗锯齿支持。仅具有2D形状且没有任何3D变换的场景不需要深度缓冲区,也不需要场景抗锯齿支持。包含3D形状或具有3D变换的2D形状的场景可以使用深度缓冲区支持来进行适当的深度排序渲染。为了避免进行深度战斗(也称为Z战斗),请对没有3D变换的2D形状禁用深度测试。有关更多信息,请参见depthTest。具有3D形状的场景可以启用场景抗锯齿功能以提高其渲染质量。

depthBuffer和antiAliasing标志是条件功能。各自的默认值为:false和SceneAntialiasing.DISABLED。有关更多信息,请参见ConditionalFeature.SCENE3D

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

Scene(Parent,double,double,boolean,SceneAntialiasing)参数是深度缓冲标志。


您还提到您必须将Scene(Parent,double,double,boolean,SceneAntialiasing)设置为boolean,而不是Camera#nearClip。为了方便起见,这是该属性的文档:

指定在眼睛坐标空间中此Camera#nearClip的近裁剪平面到眼睛的距离。没有绘制比0.01更靠近眼睛的对象。 0被指定为大于零的值。小于或等于零的值将被视为非常小的正数。

默认值:Camera

它表示该值应大于零。当然,它也说值nearClip将被视为“ 非常小的正数”,我理解这意味着值nearClip将被解释为任意接近的数字,但是仍然大于,零。因此,我不确定是否将值设置为0.1会引起任何问题。

© www.soinside.com 2019 - 2024. All rights reserved.