Getting Started with JavaFX 3D Graphics


Beta Draft: 2013-09-17

1 Overview

This chapter provides an overview of the JavaFX 3D graphics features currently available through the Java APIs for JavaFX.

The JavaFX 3D graphics APIs provide a general purpose three-dimensional graphics library for the JavaFX platform. You can use 3D geometry, cameras, and lights to create, display, and manipulate objects in 3D space.

Sample of 3D Graphics Use Cases

Figure 1-1 shows a snapshot of the JavaFX 3D application example that was demonstrated at the JavaOne 2012 keynote session. It was built as a proof of concept on an early prototype of JavaFX SDK with added 3D Mesh, Camera and Lighting support. You can view it at web site.

Figure 1-1 JavaFX 3D Application Sample

Description of Figure 1-1 follows
Description of "Figure 1-1 JavaFX 3D Application Sample"

A sampling of other JavaFX 3D graphics use cases are as follows:

  • Inventory and Process Visualization

  • Scientific and Engineering Visualization

  • 3D Charting

  • Mechanical CAD and CAE

  • Medical Imaging

  • Product Marketing

  • Architectural Design and Walkthroughs

  • Advanced User Experience

  • Mission Planning

  • Training

  • Entertainment

3D Feature in JavaFX 2.x Releases

In the JavaFX 2.x releases, it is possible to create two-dimensional objects and transform them in 3D space. You can subclass the Group class to create your own custom group and set the transform sub-matrices to anything you want. You are able to simulate the behavior of transform groups of other 3D content concentration packages, such as Maya and 3D Studio Max, because you can customize which sub-matrices are part of that transform group. See Applying Transformations in JavaFX to learn more about this transformation feature.

Example 1-1 shows a sample code that creates a Group subclass, Xform, that has a translation, a pivot, three rotations, a scale, and the inverse pivot.

Example 1-1 3D Transforms Code Sample

public class XformWithPivot extends Group {
    public Translate t = new Translate();
    public Translate p = new Translate();
    public Translate ip = new Translate();
    public Rotate rx = new Rotate();
    { rx.setAxis(Rotate.X_AXIS); }
    public Rotate ry = new Rotate();
    { ry.setAxis(Rotate.Y_AXIS); }
    public Rotate rz = new Rotate();
    { rz.setAxis(Rotate.Z_AXIS); }
    public Scale s = new Scale();
    public XformWithPivot() {
       getTransforms().addAll(t, p, rz, ry, rx, s, ip); 

The Xform subclass is created from Group because groups are originally designed for two-dimensional (2D) UI layout. The pivot of a node is recalculated under certain conditions for 2D UI layout, but if you subclass group and create Xform, as shown in Example 1-1 and use those new transforms, it bypasses the 2D UI layout.

Although, 2D UI pivot recalculation is very desirable for UI controls in a 2D layout, it is not something you would want in a 3D layout. The pivot point is recomputed as the center of the Node's layout bounds and so any change to the layout bounds will cause the pivot point to change, which ends up automatically moving your object. So, for a Group node, any change to its children, including position, geometry, effect, orientation, or scale, will cause the group's layout bounds to change. This will automatically move the object in unintended ways, when it comes to 3D layout, but in desirable ways when it comes to 2D. So, in a 3D layout, you definitely want to bypass the automatic pivot recomputation.

Some of the useful 3D Transform methods on Node are listed in Example 1-2.

Example 1-2 Useful 3D Transform Methods on Node

Transform getLocalToParentTransform()
Transform getLocalToSceneTransform()
public Point3D sceneToLocal(Point3D scenePoint)
public Point3D sceneToLocal(double sceneX, double sceneY, double sceneZ)
public Point3D localToScene(Point3D localPoint)
public Point3D localToScene(double x, double y, double z)
public Point3D parentToLocal(Point3D parentPoint)
public Point3D parentToLocal(double parentX, double parentY, double parentZ)
public Point3D localToParent(Point3D localPoint)
public Point3D localToParent(double x, double y, double z)