Issue
What I made in JavaFx: https://i.stack.imgur.com/OfOmO.gif
problem: The box is moving under the box instead of through the box
What supposed to be happen: href="https://i.stack.imgur.com/ZWgda.gif" rel="nofollow noreferrer">https://i.stack.imgur.com/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.stack.imgur.com/NQjGN.png
Help, please
Solution
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.
What it does is:
- Remove the
SubScene
, because it was not required for this example. - 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).
- Add an auto-translate animation capability.
- Set a blue color for one of the boxes so that the boxes can be more easily differentiated.
- 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.
Answered By - jewelsea
Answer Checked By - David Goodson (JavaFixing Volunteer)