Apr 28, 2017

JavaFX Programming Example: 3D Box

JavaFX has built-in support for realistic 3D modeling. In fact, the JavaFX scene graph is three-dimensional in nature. Most JavaFX programs work in just two dimensions, specifying just x- and y-coordinates. But all you __have to do to step into the third dimension is specify z-coordinates to place the nodes of your scene graph in three-dimensional space.

JavaFX includes a rich set of classes that are dedicated to creating and visualizing 3D objects in 3D worlds. You can create three-dimensional shapes, such as cubes and cylinders. You can move the virtual camera around within the 3D space to look at your 3D objects from different angles and different perspectives.

And you can even add lighting sources to carefully control the final appearance of your virtual worlds. In short, JavaFX is capable of producing astonishing 3D scenes.

Add a 3D box to your Java world

In this step, add an object to the 3D world: In this case, a box, represented by the Box class. Here’s the code:

Box box = new Box(100, 100, 100);box.setMaterial(blueStuff);box.setTranslateX(150);box.setTranslateY(-100);box.setTranslateZ(-100);root.getChildren().add(box);

The Box constructor accepts three arguments representing the width, height, and depth of the box. In this example, all three are set to 100. Thus, the box will be drawn as a cube with each side measuring 100 units.

The box is given the same material as the cylinder; then, it is translated on all three axes so that you can __have a perspective view of the box. The figure shows how the box appears when rendered. As you can see, the left and bottom faces of the box are visible because you translated the position of the box up and to the right so that the camera can gain some perspective.

A 3D box created on JavaFX.

Rotate the 3D box

In this step, rotate the box to create an even more interesting perspective view. There are two ways to rotate a 3D object. The simplest is to call the object’s setRotate method and supply a rotation angle:

box.setRotate(25);

By default, this will rotate the object on its z-axis. If this is difficult to visualize, imagine skewering the object with a long stick that is parallel to the z-axis. Then, spin the object on the skewer.

If you want to rotate the object along a different axis, first call the setRotationAxis. For example, to spin the object on its x-axis, use this sequence:

box.setRotationAxis(Rotate.X_AXIS);box.setRotate(25);

Imagine running the skewer through the box with the skewer parallel to the x-axis and then spinning the box 25 degrees.

The only problem with using the setRotate method to rotate a 3D object is that it works only on one axis at a time. For example, suppose you want to rotate the box 25 degrees on both the z- and the x-axis. The following code will not accomplish this:

box.setRotationAxis(Rotate.X_AXIS);box.setRotate(25);box.setRotationAxis(Rotate.Z_AXIS);box.setRotate(25);

When the setRotate method is called the second time to rotate the box on the z-axis, the x-axis rotation is reset.

To rotate on more than one axis, you must use the Rotate class instead. You create a separate Rotate instance for each axis you want to rotate the object on and then add all the Rotate instances to the object’s Transforms collection via the getTransforms().addAll method, like this:

Rotate rxBox = new Rotate(0, 0, 0, 0, Rotate.X_AXIS);Rotate ryBox = new Rotate(0, 0, 0, 0, Rotate.Y_AXIS);Rotate rzBox = new Rotate(0, 0, 0, 0, Rotate.Z_AXIS);rxBox.setAngle(30);ryBox.setAngle(50);rzBox.setAngle(30);box.getTransforms().addAll(rxBox, ryBox, rzBox);

The Rotate constructor accepts four parameters. The first three are the x-, y-, and z-coordinates of the point within the object through which the rotation axis will pass. Typically, you specify zeros for these parameters to rotate the object around its center point. The fourth parameter specifies the rotation axis.

This figure shows how the box appears after it’s been rotated.

A rotated 3d box made on JavaFX
The box after it’s been rotated.