1

我试图让一些形状相互“玩得很好”。我有 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 顺序中会更高。我希望边框出现在顶部。

4

2 回答 2

1

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

camera.setNearClip(10);

将解决您的前两个问题。

于 2016-10-29T09:33:19.727 回答
0

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

 setDepthTest(DepthTest.ENABLE);
于 2017-05-15T02:28:51.697 回答