In short - I have 2 rotating rectangles. While rotating (by Y axis) they should overlap one over another - unfortunetlny one of ractangles is "always in front" despite of 180 degree turn. How to fix that behaviour? It looks like it is relevant to order in whitch rectangles hass been added to group. The one that was added as last is always in front.
scene:
package drawing.scene;
import javafx.application.Application;
import javafx.geometry.Point3D;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import drawing.objects.Clock;
import drawing.objects.Cube;
public class MyScene extends Application {
private int sceneEdgeSize = 800;
private int clolcSize = 400;
@Override
public void start(Stage primaryStage) throws Exception {
Group g = new Group();
g.setTranslateX((sceneEdgeSize - clolcSize) / 2f);
g.setTranslateY((sceneEdgeSize - clolcSize) / 2f);
final Cube c = new Cube(clolcSize);
g.getChildren().add(c);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
Rotate r = rotate(0, Rotate.Y_AXIS);
c.getTransforms().add(r);
double angle = 0.0;
while (true) {
r.setAngle(angle += 2);
try {
Thread.sleep(25);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
t.setDaemon(true);
primaryStage.setScene(new Scene(g, sceneEdgeSize, sceneEdgeSize));
PerspectiveCamera camera = new PerspectiveCamera();
primaryStage.getScene().setCamera(camera);
primaryStage.show();
t.start();
}
public static void main(String[] args) {
launch(args);
}
public Rotate rotate(double angle, Point3D axis) {
return new Rotate(angle, clolcSize / 2f, clolcSize / 2f, 0, axis);
}
}
cube class:
package drawing.objects;
import javafx.collections.ObservableList;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.RectangleBuilder;
import javafx.scene.transform.Rotate;
public class Cube extends Group {
private double edgeLength = 0;
public Cube(double edgeLength) {
super();
this.edgeLength = edgeLength;
create();
}
private void create() {
final Rotate rx = new Rotate(0, Rotate.X_AXIS);
final Rotate ry = new Rotate(0, Rotate.Y_AXIS);
final Rotate rz = new Rotate(0, Rotate.Z_AXIS);
this.getTransforms().addAll(rx, ry, rz);
ObservableList<Node> children = this.getChildren();
//@formatter:off
Rectangle rect;
rect = RectangleBuilder // face
.create()
.width(edgeLength-20)
.height(edgeLength-20)
.translateZ(edgeLength * 0.5)
// .translateY(edgeLength * 0.5)
// .translateX(-edgeLength * 0.5)
.fill(Color.LIGHTGREEN)
.build()
;
children.add(rect);
rect = RectangleBuilder // face
.create()
.width(edgeLength-20)
.height(edgeLength-20)
.translateZ(-edgeLength * 0.5)
// .translateY(-edgeLength * 0.5)
// .translateX(-edgeLength * 0.5)
.fill(Color.DARKGREEN)
.build()
;
children.add(rect);
//@formatter:on
}
}
You should switch depth buffering on in your scene.
The code in this question is largely obsolete and is also incorrect in parts:
Also check that your system supports JavaFX 3D:
System.out.println(
"3D supported? " +
Platform.isSupported(ConditionalFeature.SCENE3D)
);
Java 8 3D sample code for a rotating cube
Here is a rotating cube coded in Java 8.
import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class RotatingCube extends Application {
private static final double SCENE_SIZE = 300;
private static final double BOX_EDGE_LENGTH = SCENE_SIZE / 2d;
private static final Color BOX_COLOR = Color.DARKGREEN;
private static final Color AMBIENT_COLOR = Color.rgb(30, 30, 30);
private static final Color LIGHT_COLOR = Color.WHITE;
private static final Duration ROTATION_DURATION = Duration.seconds(4.5);
@Override
public void start(Stage stage) throws Exception {
Scene scene = new Scene(
new Group(
new AmbientLight(AMBIENT_COLOR),
createPointLight(),
createRotatingBox()
),
SCENE_SIZE, SCENE_SIZE,
true,
SceneAntialiasing.BALANCED
);
scene.setFill(Color.MIDNIGHTBLUE.darker().darker().darker());
scene.setCamera(new PerspectiveCamera());
stage.setScene(scene);
stage.show();
}
private PointLight createPointLight() {
PointLight light = new PointLight(LIGHT_COLOR);
light.setTranslateX( SCENE_SIZE / 2d);
light.setTranslateY( SCENE_SIZE / 2d);
light.setTranslateZ(-SCENE_SIZE);
return light;
}
private Box createRotatingBox() {
final Box box = new Box(BOX_EDGE_LENGTH, BOX_EDGE_LENGTH, BOX_EDGE_LENGTH);
box.setTranslateX(SCENE_SIZE / 2d);
box.setTranslateY(SCENE_SIZE / 2d);
box.setTranslateZ(BOX_EDGE_LENGTH / 2d);
box.setMaterial(new PhongMaterial(BOX_COLOR));
rotateAroundYAxis(box);
return box;
}
private void rotateAroundYAxis(Box box) {
RotateTransition rotate = new RotateTransition(ROTATION_DURATION, box);
rotate.setFromAngle(0);
rotate.setToAngle(360);
rotate.setAxis(Rotate.Y_AXIS);
rotate.setCycleCount(RotateTransition.INDEFINITE);
rotate.setInterpolator(Interpolator.LINEAR);
rotate.play();
}
public static void main(String[] args) {
launch(args);
}
}
Java 8 3D sample code for two rotating rectangles
import javafx.animation.*;
import javafx.application.*;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class RotatingRectangles extends Application {
private static final double SCENE_SIZE = 300;
private static final double EDGE_LENGTH = SCENE_SIZE / 2d;
private static final Duration ROTATION_DURATION = Duration.seconds(4.5);
@Override
public void start(Stage stage) throws Exception {
System.out.println(
"3D supported? " +
Platform.isSupported(ConditionalFeature.SCENE3D)
);
Scene scene = new Scene(
createRotatingShapes(),
SCENE_SIZE, SCENE_SIZE,
true,
SceneAntialiasing.BALANCED
);
scene.setFill(Color.MIDNIGHTBLUE.darker().darker().darker());
scene.setCamera(new PerspectiveCamera());
stage.setScene(scene);
stage.show();
}
private Group createRotatingShapes() {
final Rectangle rect1 = new Rectangle(
EDGE_LENGTH, EDGE_LENGTH,
Color.LIGHTGREEN
);
rect1.setTranslateX(-EDGE_LENGTH / 2d);
rect1.setTranslateY(-EDGE_LENGTH / 2d);
rect1.setTranslateZ( EDGE_LENGTH / 2d);
final Rectangle rect2 = new Rectangle(
EDGE_LENGTH, EDGE_LENGTH,
Color.DARKGREEN
);
rect2.setTranslateX(-EDGE_LENGTH / 2d);
rect2.setTranslateY(-EDGE_LENGTH / 2d);
rect2.setTranslateZ(-EDGE_LENGTH / 2d);
final Group shapes = new Group(
rect1, rect2
);
shapes.setTranslateX(SCENE_SIZE / 2d);
shapes.setTranslateY(SCENE_SIZE / 2d);
shapes.setTranslateZ(EDGE_LENGTH / 2d);
rotateAroundYAxis(shapes);
return shapes;
}
private void rotateAroundYAxis(Node node) {
RotateTransition rotate = new RotateTransition(ROTATION_DURATION, node);
rotate.setFromAngle(0);
rotate.setToAngle(360);
rotate.setAxis(Rotate.Y_AXIS);
rotate.setCycleCount(RotateTransition.INDEFINITE);
rotate.setInterpolator(Interpolator.LINEAR);
rotate.play();
}
public static void main(String[] args) {
launch(args);
}
}
In the first picture the dark rectangle has been rotated in front of the light rectangle.
In the first picture the light rectangle has been rotated in front of the dark rectangle.
So you can see that the JavaFX system is correctly displaying the depth sorted shapes in the scene.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With