import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.RectangleBuilder;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
* @author Jasper Potts
*/
public class Cube3D extends Application {
@Override
public void start(Stage stage) throws Exception {
stage.setTitle("Cube 3D");
// stage.initDepthBuffer(true);
Cube c = new Cube(50, Color.RED, 1);
c.rx.setAngle(45);
c.ry.setAngle(45);
Cube c2 = new Cube(50, Color.GREEN, 1);
c2.setTranslateX(100);
c2.rx.setAngle(45);
c2.ry.setAngle(45);
Cube c3 = new Cube(50, Color.ORANGE, 1);
c3.setTranslateX(-100);
c3.rx.setAngle(45);
c3.ry.setAngle(45);
Timeline animation = new Timeline();
animation.getKeyFrames().addAll(
new KeyFrame(Duration.ZERO, new KeyValue(c.ry.angleProperty(),
0d), new KeyValue(c2.rx.angleProperty(), 0d),
new KeyValue(c3.rz.angleProperty(), 0d)),
new KeyFrame(Duration.millis(1000), new KeyValue(c.ry
.angleProperty(), 360d), new KeyValue(c2.rx
.angleProperty(), 360d), new KeyValue(c3.rz
.angleProperty(), 360d)));
animation.setCycleCount(Animation.INDEFINITE);
// create root group
Group root = new Group(c, c2, c3);
// translate and rotate group so that origin is center and +Y is up
root.setTranslateX(400 / 2);
root.setTranslateY(150 / 2);
root.getTransforms().add(new Rotate(180, Rotate.X_AXIS));
// create scene
Scene scene = new Scene(root, 400, 150);
scene.setCamera(new PerspectiveCamera());
stage.setScene(scene);
stage.show();
// start spining animation
animation.play();
}
public static void main(String[] args) {
launch(args);
}
public class Cube extends Group {
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);
public Cube(double size, Color color, double shade) {
getTransforms().addAll(rz, ry, rx);
getChildren().addAll(
RectangleBuilder
.create()
// back face
.width(size)
.height(size)
.fill(color.deriveColor(0.0, 1.0,
(1 - 0.5 * shade), 1.0))
.translateX(-0.5 * size).translateY(-0.5 * size)
.translateZ(0.5 * size).build(),
RectangleBuilder
.create()
// bottom face
.width(size)
.height(size)
.fill(color.deriveColor(0.0, 1.0,
(1 - 0.4 * shade), 1.0))
.translateX(-0.5 * size).translateY(0)
.rotationAxis(Rotate.X_AXIS).rotate(90).build(),
RectangleBuilder
.create()
// right face
.width(size)
.height(size)
.fill(color.deriveColor(0.0, 1.0,
(1 - 0.3 * shade), 1.0))
.translateX(-1 * size).translateY(-0.5 * size)
.rotationAxis(Rotate.Y_AXIS).rotate(90).build(),
RectangleBuilder
.create()
// left face
.width(size)
.height(size)
.fill(color.deriveColor(0.0, 1.0,
(1 - 0.2 * shade), 1.0)).translateX(0)
.translateY(-0.5 * size)
.rotationAxis(Rotate.Y_AXIS).rotate(90).build(),
RectangleBuilder
.create()
// top face
.width(size)
.height(size)
.fill(color.deriveColor(0.0, 1.0,
(1 - 0.1 * shade), 1.0))
.translateX(-0.5 * size).translateY(-1 * size)
.rotationAxis(Rotate.X_AXIS).rotate(90).build(),
RectangleBuilder
.create()
// top face
.width(size).height(size).fill(color)
.translateX(-0.5 * size).translateY(-0.5 * size)
.translateZ(-0.5 * size).build());
}
}
}