简而言之 - 我有 2 个旋转矩形。在旋转(通过 Y 轴)时,它们应该相互重叠 - 不幸的是,尽管旋转了 180 度,但其中一个矩形“始终在前面”。如何解决该行为?看起来它与已添加到组中的矩形的顺序有关。最后添加的总是在前面。
场景:
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);
}
}
立方体类:
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
}
}
最佳答案
你应该 switch depth buffering on in your scene .
这个问题中的代码大部分已经过时,并且部分错误:
- JavaFX 3D work , 推荐使用Java 8 .
- 要构建立方体,请使用 Box形状。
- 对于其他几何类型,使用 Sphere , Cylinder或 MeshView .
- 使用Point和 Ambient灯光照亮您的场景。
- 申请Materials到您的 3D 对象以对其进行着色。
- 使用Model importers导入复杂的网格模型。
- Builders已弃用。
- 为了处理动画,不建议生成另一个线程,而是使用 JavaFX animation package .
- 对于您问题中的特定动画,RotateTransition是合适的动画。
- 您的解决方案不是线程安全的。您不应在应用程序线程之外修改 Activity 场景图中节点的属性(例如,显示节点的变换属性)(改为使用 Platform.runLater)。
- 您没有使用 depth buffering 创建场景设置为真。深度缓冲标志告诉 JavaFX 它应该对 3D 对象应用深度排序和剔除。
同时检查您的系统是否支持 JavaFX 3D:
System.out.println(
"3D supported? " +
Platform.isSupported(ConditionalFeature.SCENE3D)
);
旋转立方体的 Java 8 3D 示例代码
这是一个用 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 示例代码
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);
}
}
在第一张图片中,深色矩形已经旋转到浅色矩形的前面。
在第一张图片中,浅色矩形已旋转到深色矩形前面。
因此您可以看到 JavaFX 系统正确显示场景中的深度排序形状。
关于java - 重叠形状 - 错误的重叠形状行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19589210/