3 Steps to Building a 3D Java World
In a few short steps you can start to create a relatively simple 3D program in JavaFX that displays the three-dimensional world (an example is shown below). As you can see, this 3D space includes four shapes: a sphere, a cube, a cylinder, and a pyramid. This short list shows you how to get started with a cylinder.
Put on your Thinking Cap, as this example is pretty technical at times, and many of the concepts relating to building 3D worlds can be confusing, especially if this is your first experience with 3D programming.
Step one: Add a cylinder
In this step, you add a basic 3D object to your world. JavaFX provides three basic shapes you can add: cylinders, boxes, and spheres. Start by adding a cylinder:
Cylinder cylinder = new Cylinder(100,50); root.getChildren().add(cylinder);
The Cylinder class constructor accepts two arguments: the radius of the cylinder and its height. This example creates a cylinder roughly the shape of a hockey puck, four times as wide as it is tall; then, it adds the cylinder to the scene’s root node.
At this point, the cylinder exists in the world, but is not visible. Based on what you know of 2D shapes, you may be tempted to make it visible by adding a fill color (setFill) or a stroke color (setStroke). But that’s not how 3D objects work. In the next step, you discover how to apply a material to the surface of the cylinder so that it will be visible in the scene.
Step two: Create a material
Rendering the faces of a 3D object is much more complicated than rendering flat, two-dimensional objects. For a 2D object, you just apply a Paint object via the setFill method. The paint can be a simple color, a gradient color, or an image.
For 3D objects, you don’t apply paint. Instead, you apply a special object called a Phong material, represented by the PhongMaterial class. A Phong material (named after Bui Tuong Phong, a pioneering computer graphics expert in the 1970’s) provides the means by which the faces of a 3D object are realistically rendered.
The following code creates a simple Phong material based on two shades of blue and then applies the material to the cylinder:
PhongMaterial blueStuff = new PhongMaterial(); blueStuff.setDiffuseColor(Color.LIGHTBLUE); blueStuff.setSpecularColor(Color.BLUE); cylinder.setMaterial(blueStuff);
After the Phong material has been applied to the cylinder, the cylinder will be visible within the scene, as shown.
Step three: Translate the cylinder
You undoubtedly noticed that the cylinder doesn’t look very three dimensional. That’s because you’re looking at it edge-on: The camera is pointing straight at the intersection of the x- and y-axes, and the cylinder is centered on that very spot.
To gain some perspective on the cylinder, you can move it to a different location in 3D space by translating the x-, y-, and z-coordinates. For example:
cylinder.setTranslateX(-200); cylinder.setTranslateY(200); cylinder.setTranslateZ(200);
Here, the cylinder is moved 200 units to the left, 200 units down, and 200 units away from the camera. The resulting view looks more like a cylinder, as you can see here.
In this figure, it looks as if the cylinder has been rotated forward so that you can see a bit of the top surface. This isn’t the case, however. What has actually happened is that you’re no longer looking at the cylinder edge-on.
Instead, because the cylinder is below the camera, you’re looking down on it. Thus, you can see a bit of the top face. You’re also looking at it from the side, which explains why it appears just a tad tilted.