盒子在另一个盒子下面移动而不是穿过盒子 - JavaFX

The box is moving under the other box instead of moving through the box - JavaFX

我用 JavaFx 做了什么: https://i.stack.imgur.com/OfOmO.gif

问题:盒子在盒子下面移动,而不是穿过盒子

应该发生什么: https://i.stack.imgur.com/ZWgda.gif //在blender中制作的预览

解释:当我按下向下键时,移动的立方体应该穿过另一个立方体

这是我的代码:

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.image.Image;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.scene.transform.*;
import javafx.stage.Stage;

public class Main extends Application {
    @Override public void start(Stage stage) throws Exception {
        Group root3D = new Group();
        AnchorPane globalRoot = new AnchorPane();
        Scene scene = new Scene(globalRoot, 800, 400, true);
        PerspectiveCamera camera = new PerspectiveCamera(true);
        SubScene sub = new SubScene(root3D,800,400,false,SceneAntialiasing.BALANCED);
        
        camera.getTransforms().addAll(new Translate(),new Rotate(0, Rotate.Z_AXIS),new Rotate(0, Rotate.Y_AXIS), new Rotate(30, Rotate.X_AXIS), new Translate(0, 0, -50));
        sub.setCamera(camera);
        globalRoot.getChildren().add(sub);
        stage.setScene(scene);
        stage.show();
        
        PhongMaterial material = new PhongMaterial();
        Image image = new Image(getClass().getResourceAsStream("texture.png"));
        material.setDiffuseMap(image);
        material.setSpecularColor(Color.WHITE);
           
        Box box1 = new Box(5,5,5);
        box1.setMaterial(material);
        box1.setTranslateY(-5);
        root3D.getChildren().add(box1);
        
        Box box2 = new Box(5,5,5);
        box2.setMaterial(material);
        root3D.getChildren().add(box2);
        
        scene.setOnKeyPressed((EventHandler<? super KeyEvent>) new EventHandler <KeyEvent>() {
            @Override public void handle(KeyEvent arg0) {
                if (arg0.getCode().toString() == "DOWN") {
                        box1.setTranslateY(box1.getTranslateY()+1);
                    }}});
    }
    public static void main(String[] args) {
       launch(args);
     }
}

这是纹理:https://i.stack.imgur.com/NQjGN.png

求助

我认为您遇到的主要问题是没有为您的 3D 场景打开深度缓冲。

示例修复,使用深度缓冲:

import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.image.Image;
import javafx.scene.input.KeyCode;
import javafx.scene.paint.*;
import javafx.scene.shape.Box;
import javafx.scene.transform.*;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Boxes extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        Group group = new Group();
        Scene scene = new Scene(
                group,
                800, 400,
                true,
                SceneAntialiasing.BALANCED
        );
        PerspectiveCamera camera = new PerspectiveCamera(true);

        camera.getTransforms().addAll(
                new Translate(),
                new Rotate(0, Rotate.Z_AXIS),
                new Rotate(0, Rotate.Y_AXIS),
                new Rotate(30, Rotate.X_AXIS),
                new Translate(0, 0, -50)
        );
        scene.setCamera(camera);

        Image image = new Image(
                Boxes.class.getResourceAsStream(
                        "texture.png"
                )
        );

        PhongMaterial material1 = new PhongMaterial();
        material1.setDiffuseMap(image);

        PhongMaterial material2 = new PhongMaterial();
        material2.setDiffuseMap(image);
        material2.setDiffuseColor(Color.LIGHTBLUE);

        Box box1 = new Box(5, 5, 5);
        box1.setMaterial(material1);
        box1.setTranslateY(-5);
        group.getChildren().add(box1);

        Box box2 = new Box(5, 5, 5);
        box2.setMaterial(material2);
        group.getChildren().add(box2);
        box2.setTranslateZ(.01);

        TranslateTransition autoMover = new TranslateTransition(
                Duration.seconds(3),
                box1
        );
        autoMover.setFromY(-10);
        autoMover.setToY(10);
        autoMover.setAutoReverse(true);
        autoMover.setCycleCount(Animation.INDEFINITE);
        autoMover.play();

        scene.setOnKeyPressed(keyEvent -> {
            if (KeyCode.DOWN.equals(keyEvent.getCode())) {
                box1.setTranslateY(box1.getTranslateY() + 1);
            }

            if (KeyCode.UP.equals(keyEvent.getCode())) {
                box1.setTranslateY(box1.getTranslateY() - 1);
            }

            if (KeyCode.SPACE.equals(keyEvent.getCode())) {
                if (Animation.Status.RUNNING.equals(autoMover.getStatus())) {
                    autoMover.pause();
                } else {
                    autoMover.play();
                }
            }
        });

        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

程序输出的gif动画。 gif 编码中丢失了一些保真度,因此这种编码并不能很好地反映实际的程序输出。所以尝试 运行 实际程序而不是仅仅观察 gif 编码。

它的作用是:

  1. 删除 SubScene,因为此示例不需要它。
  2. 为显示 3D 模型的场景打开深度缓冲区(之前 3D 模型显示在深度缓冲关闭的 SubScene 中)。
  3. 添加自动翻译动画功能。
  4. 为其中一个框设置蓝色,以便更容易区分框。
  5. 为其中一个框设置一个小的 z 平移 (.01) 以确保一个框稍微落后于另一个(这有助于深度缓冲区排序的平滑分辨率)。

如果你想了解它在做什么,你可以阅读深度缓冲:

A depth buffer, also known as a z-buffer, is a type of data buffer used in computer graphics to represent depth information of objects in 3D space from a particular perspective. Depth buffers are an aid to rendering a scene to ensure that the correct polygons properly occlude other polygons.