tommY
tommY

Reputation: 109

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

What I made in JavaFx: https://i.sstatic.net/OfOmO.gif

problem: The box is moving under the box instead of through the box

What supposed to be happen: https://i.sstatic.net/ZWgda.gif //preview made in blender

explain: The moving cube should passes through the other cube when I'm pressing the down key

And here's my code:

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);
     }
}

Here's the texture: https://i.sstatic.net/NQjGN.png

Help, please

Upvotes: 2

Views: 107

Answers (1)

jewelsea
jewelsea

Reputation: 159436

I think the main issue you have is not having depth buffering switched on for your 3D scene.

Example fix, using depth buffering:

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);
    }
}

A gif animation of the program output. Some fidelity was lost in the gif encoding such that this encoding doesn't really reflect the actual program output very well. So try running the actual program instead of just observing the gif encoding.

boxes

What it does is:

  1. Remove the SubScene, because it was not required for this example.
  2. Switch on the depth buffer for the scene which is displaying the 3D models (previously the 3D models were displayed in a SubScene that had depth buffering switched off).
  3. Add an auto-translate animation capability.
  4. Set a blue color for one of the boxes so that the boxes can be more easily differentiated.
  5. Set a small z translation (.01) for one of the boxes to ensure that one box is slightly behind the other (which helps in a smooth resolution of the depth buffer ordering).

You can read up on depth buffering if you want to understand what it is doing:

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.

Upvotes: 6

Related Questions