【问题标题】:How to make 3D shapes appear correctly with a camera?如何使用相机正确显示 3D 形状?
【发布时间】:2023-03-06 19:40:02
【问题描述】:

我正在尝试让一些形状相互“玩得很好”。我有 2 个彼此相邻的盒子,其中一个盒子“顶部”有一个圆柱体。我将它们放在SubScene 中,并带有一个可以通过滚动操作放大和缩小并通过拖动进行平移的相机。这是我的 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);
    }
}

我这里有两个问题:

  1. Z 顺序由我将它们放入组中的顺序指定。我希望 Z 订单“照顾好自己”。如果我在空间中有具有特定坐标和大小的形状以及处于特定位置和角度的相机,我应该看到一个独特的视图,而无需指定顺序。这是一张图片:

    看起来绿色框比红色框更靠近相机,但我的代码并没有暗示这一点。

  2. 当相机平移时,圆柱体相对于盒子移动。在图片中,我用蓝线在红框上标出了圆柱体的位置:

    现在我平移相机并得到

    我希望形状的相对位置在我平移相机时不会改变。

  3. 编辑:我从问题中删除了这个并在另一个问题中提问:
    形状显示在边框顶部:

    我认为因为形状在窗格中,所以窗格的边框在 Z 顺序中会更高。我希望边框出现在顶部。

【问题讨论】:

    标签: java javafx javafx-8 javafx-3d


    【解决方案1】:

    我猜这实际上是 JavaFX 中的一个错误,但至少它很容易修复。只是不要将相机的近剪切窗格设置为 0。将这行代码更改为

    camera.setNearClip(10);
    

    将解决您的前两个问题。

    【讨论】:

    • 你指的是3个问题中的哪一个?
    • 第 1 号和第 2 号,据我了解您的问题。 3 号是一个不同的问题。
    • 旁注:如果您认为这是 JavaFX 中的错误,请在此处提交问题:bugs.java.com
    • @Puce 我个人不确定我提到的任何问题都是错误。你认为应该提交吗?
    • @mipa 提到这可能是一个错误。我不熟悉 API 的那部分。
    【解决方案2】:

    尝试使用以下行启用组深度测试:

     setDepthTest(DepthTest.ENABLE);
    

    【讨论】:

      猜你喜欢
      • 2012-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-17
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多