首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何选择三维场景中的二维节点?

如何选择三维场景中的二维节点?
EN

Stack Overflow用户
提问于 2016-10-14 16:54:17
回答 1查看 297关注 0票数 1

这是我的密码。你可以复制粘贴,并跟随我所写的内容,自己看问题。

代码语言:javascript
复制
public class MyApp extends Application {

    @Override
    public void start(Stage stage) throws Exception {

        Scene scene = new Scene(new MyView(), 100, 150);
        stage.setScene(scene);
        stage.show();
    }

    private class MyView extends BorderPane {

        MyView() {

            GridPane board = new GridPane();
            int size = 3;
            for (int i = 0; i < size*size; i++) {
                BorderPane pane = new BorderPane();
                pane.setMinSize(30, 30);
                pane.setBackground(new Background(new BackgroundFill(Color.RED, null, null)));
                pane.setBorder(new Border(new BorderStroke(null, BorderStrokeStyle.SOLID,
                                                           null, null, null)));
                pane.setOnMousePressed(e -> {
                    PickResult pick = e.getPickResult();
                    Pane selectedNode = (Pane) pick.getIntersectedNode();
                    selectedNode.setBackground(new Background(new BackgroundFill(Color.GREEN, null, null)));
                });
                board.add(pane, i / size, i % size);
            }
            Box box = new Box(20d, 20d, 20d);
            BorderPane boardPane = new BorderPane(box, null, null, board, null);
            Group root = new Group(boardPane);

            SubScene scene = new SubScene(root, USE_PREF_SIZE, USE_PREF_SIZE, true, SceneAntialiasing.BALANCED);
            scene.widthProperty().bind(widthProperty());
            scene.heightProperty().bind(heightProperty());

            setCenter(scene);
        }
    }

    public static void main(String[] args) throws Exception {

        launch(args);
    }
}

我创建了一个带有方格的子场景。当我按下一个正方形,我希望它的背景改变颜色。这种方法适用于两种情况:

  1. 如果我不把这个盒子添加到boardPane
  2. 如果我不用深度缓冲区设置场景

或者两者都是。但是,如果我都添加了这个框并设置了一个深度缓冲区,那么方块就不会接收到事件。相反,boardPane接收它。我想这与3D场景中的2D节点有关。

我尝试设置这些方法的组合:setPickOnBoundssetDepthTestsetMouseTransparent,但都没有效果。

解决办法是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-01 00:35:39

一旦有了3D场景,就没有真正的2D节点,场景图中的所有东西都有x、y和z的协调;甚至当深度缓冲区设置为false时,以前被当作2D节点的东西也是如此。

当您在根边框窗格中放置一个框时,该根边框窗格将假定该框的三维协调。对于拾取目的,您定义的框在z坐标-10到10之间的3D空间中表示,因此根边框窗格被定义为-10用于拾取目的。在根边框窗格中放置的边框窗格没有为它们定义z协调,因此它们最终以z坐标0结束,从查看者的角度来看,z坐标位于根边框窗格的后面。

因此,根边框窗格正在接收单击,但由于它现在位于与其其他内容不同的z平面上,所以您定义的其他2D方框内容不接收单击。人们可能会争辩说,根本没有呈现根边框,因为它没有颜色,因此应该将其视为透明的,单击只会传递到子节点,但这似乎并不是JavaFX的3D拾取算法的工作方式。

对于您的示例,要使所有东西都位于相同的Z平面上并正确工作,请在For循环中添加以下行:pane.setTranslateZ(-10);

注意:我通过在源代码中添加以下一行(它向我报告了鼠标单击的目标和每次单击的x、y、z选择结果协调)来调试此功能:

代码语言:javascript
复制
root.setOnMouseClicked(System.out::println);

我的建议是避免使用为2D目的而设计的布局窗格(例如边框)来尝试在3D空间中布局元素。JavaFX布局窗格实际上只适用于2D布局。要处理3D空间中的定位,您应该自己管理协调,只使用组而不是从窗格派生的任何东西。至少不要尝试将3D元素添加到2D布局窗格中,因为结果可能会令人困惑(正如您已经发现的)。

通过将2D和3D项目放置在不同的子场景中,您可以进一步分离它们(我认为这正是JavaFX中的JavaFX概念)。具有多个子场景的应用程序示例如下所示:How to create custom 3d model in JavaFX 8?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40048335

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档