JClass Chart 3D

PreviousNextIndex

8

Programming with the Java 3D API

Java 3D - Overview  System Set-up  Browsers and Java 3D  Java 3D API

SceneGraphObject class  Scene Graph Viewing Object Classes  BranchGroup and TransformGroup

Rendering  Behaviors  Java 3D-Enabled Charting Features

As noted in the Preface, JClass Chart 3D allows you to create stunning 3D graphics using either the Java 2 API or the Java 3D API. In this section of the JClass Chart 3D manual, we provide an overview of the Java 3D API, and then delve into leveraging the power of the Java 3D API with JClass Chart 3D.

For your reference, here is the URL of the Java 3D API:
http://java.sun.com/products/java-media/3D/download.html


8.1 Java 3D - Overview

Java 3D is a standard suite of classes that extend Java 2's core Java platform capabilities to add 3D graphics and sound capabilities to applets and applications. Featuring interactive 3D graphics, behaviors, and spatialized sound capabilities, Java 3D can be integrated with standard Java programs. As a layered API, the high-level Java 3D API sits atop low-level 3D graphics APIs such as OpenGL and Direct3D.

The Java 3D API provides high-level constructs for generating and manipulating 3D geometry, and provides structures for rendering this geometry. Java 3D provides functions for creating imagery, animations, and interactive 3D graphics application programs.

Java 3D programs can be written to run as stand-alone applications, as applets, or both. (For information on applets, please see Section 8.3, Browsers and Java 3D.)

Please note that using Java 3D requires a sound knowledge of Java programming. Please see Related Documents in the Preface for helpful information.

8.1.1 Scene Graph Programming Model

Java 3D is based on a scene graph programming model. Here's a high level look at this model.

Java 3D developers use Java 3D classes to construct nodes. Nodes contain fields that a developer can manipulate in order to alter node properties. A collection of nodes is a scene graph. These nodes that make up a scene graph are rooted to a Locale object, which in turn is rooted to a VirtualUniverse object. A virtual universe, then, describes a 3D space populated with 3D objects.

Each scene graph has just one VirtualUniverse. Having only one instance of a VirtualUniverse in a Java 3D program is recommended. Also, while a VirtualUniverse object may reference many Locale objects, most Java 3D programs have just one Locale object.

Figure 25 :  Basic scene graph programming model. Java 3D scene graphs are linked to a Locale object, which is attached to a VirtualUniverse object.

For each Java 3D scene object, transform, or behavior, a programmer needs to create a new object instance (that is, a new node), set the fields of this instance, and add the instance to the scene.

To summarize, the Java 3D program creates instances of Java 3D objects (called nodes) and places them into a scene graph data structure (an arrangement of 3D objects in a tree structure that completely specifies the content of a virtual universe, and how it is to be rendered).


8.2 System Set-up

Here's a checklist of what you need installed on your system in order to work with Java 3D.

After you install Java 3D, verify that you have the vecmath.jar, j3dutils.jar and j3dcore.jar in your /jre/lib/ext/ directory.

While not essential to running a Java 3D application, it is highly recommended that you install the Javadoc for the Java 3D API.

The Javadocs for the entire Java 3D API can be downloaded from http://java.sun.com/products/java-media/3D/download.html

Hardware acceleration

Java 3D supports performance-enhancing features (such as hardware acceleration) of the underlying platform. Because Java 3D - which is layered atop of your graphics API - is a high-level API, Java 3D shields developers from the platform-specific details. If hardware acceleration is available, the Java runtime system will harness it without any effort from the developer.


8.3 Browsers and Java 3D

As noted above, Java 3D requires a Java 2 JRE. Two popular browsers - Internet Explorer and Netscape Navigator - ship with versions of Java that are older than Java 2. This means that end-users using these standard browsers will not be able to view Java 3D applets (an applet is a Java program to be included in an HTML page).

Thus, in order to experience Java 3D applets through a Web browser, end-users must install a Java 2 JRE, followed by the Java 3D libraries. This means that Java 3D applets require that Sun's Java Plug-in be installed and activated. This plug-in, which redirects Java 3D applets from the browser's internal JRE to the Java 2 JRE, is automatically installed when the Java 2 JRE is installed.


8.4 Java 3D API

There are about 150 classes in the Java 3D API. These classes are organized into three key packages. Java 3D applets and applications are constructed using classes found in the javax.media.j3d.javax.vecmath, and com.sun.j3d packages. The last package (com.sun.j3d) contains convenience classes.


.
Figure 26 :  The Java 3D API package hierarchy.

As an aside, Java package names with a "javax" preface typically indicate an extension to the core Java 2 platform. For instance, the main Java 3D package is javax.media.j3d.

javax.media.j3d

This package is required in the Java 3D API. This package, with over 100 classes, provides the core functionality of Java 3D. Every Java 3D program is created using at least one class from this package.

Figure 27 :  The javax.media.j3d hierarchy.

javax.vecmath

This package is required in the Java 3D API. This package defines vector mathematics classes for points, vectors, matrices, and other mathematical objects that are used in 3D object representation and manipulation. Many core Java 3D classes rely on classes in javax.vecmath.

Because the javax.vecmath package contains classes that are useful outside of Java 3D, they are packaged outside of the main javax.media.j3d package.

com.sun.j3d

This package is optional in the Java 3D API. This package contains convenience classes for Java 3D. The utility classes are placed into com.sun.j3d.util and are grouped into four categories: content loaders, scenegraph assembly aids, geometry classes, and convenience classes.


8.5 SceneGraphObject class

The SceneGraphObject class, the base class for nearly every object in a Java 3D scene graph, is an abstract class that defines a number of properties common to its two subclasses: Node and NodeComponent.

Figure 28 :  The javax.media.j3d.SceneGraphObject hierarchy.

8.5.1 Node class

The Node class is the abstract superclass of Group and Leaf classes. This Node class provides a template for scene graph objects, defining important common methods for its subclasses. The subclasses of Node provide most objects in the scene graph. A Node object is either a Group node or a Leaf node object. Group nodes can contain children, while Leaf nodes cannot. Group and Leaf are superclasses to several subclasses.

Group class

The Group class is the superclass to a family of classes that are used to specify the orientation and location of scene graph objects (visual objects in the virtual universe). As mentioned above, Group nodes can contain children. The role of a Group object is mainly to act as the parent of other Group nodes and Leaf nodes.

All subclasses of Group are considered to be grouping nodes.

Here are the subclasses of Group:

Two of these subclasses, BranchGroup and TransformGroup, are key to using JClass Chart 3D, so these will be expanded later on.

Leaf Class

The appearance, sound, and behavior of visual objects in the virtual universe are specified using subclasses of the Leaf class. Some of the subclasses of Leaf are Background, Behavior, Fog, Light, Shape3D, and Sound. Leaf nodes cannot contain children, but may reference NodeComponents.

Thus, Leaf nodes specify the shape, sound, and behavior of scene graph objects. As well, Leaf nodes provide a view platform that is used by the virtual universe to position and orient a view of the scene.

Here's a list of the top-level Leaf subclasses:

Figure 29 :  SceneObjectGraph hierarchy showing subclasses of Leaf and Group.

8.5.2 NodeComponent Class

The NodeComponent class is the superclass used to specify the geometry, appearance, texture, and material properties of a Shape3D (Leaf) node. NodeComponents are not part of the scene graph, but are referenced by it. A NodeComponent may be referenced by more than one Shape3D object.

Following is a list of the classes that are direct children of the NodeComponent abstract parent class:


8.6 Scene Graph Viewing Object Classes

The Java 3D API includes five classes that are used to view scene graphs:

These classes, while not strictly part of the Java 3D scene graph, define important viewing parameters for Java 3D programs, plus they provide a way for users to interact with the program.


8.7 BranchGroup and TransformGroup

Recall that the Group class is the superclass that is used to specify the orientation and location of scene graph objects. Two of its subclasses, BranchGroup and TransformGroup, are key to using JClass Chart 3D.

BranchGroup

The BranchGroup node is used to construct branches of a Java 3D scene graph by acting as the root for the subgraph (called branch graph). A branch graph contains the various nodes that make up a scene graph. To create a branch graph, a developer constructs a BranchGroup object, then constructs the nodes that it will contain. The nodes subsequently are added to the BranchGroup. BranchGroups are generally attached to a Locale, which acts as an anchor for objects in a scene branch graph (only BranchGroup objects can be attached to a Locale). A Locale, in turn, is attached to a VirtualUniverse object, which is the top-level object in every Java 3D scene graph.

BranchGroups can be selectively attached and detached from the scene graph. Once a branch graph is inserted into a Locale, each object in that branch graph becomes live. Once objects are live, they are subject to being rendered. Also, the parameters of live objects cannot be modified unless the corresponding capability has been specifically set before the object became live. By attaching and detaching branch graphs, a Java 3D developer can control when specific portions of a graph scene are rendered.

Capability bits (or "capabilities of the object") are a list of parameters that determine which properties of an object are changeable after that object is made live. Capability bits must be set before the object is compiled or made live.

Each SceneGraphObject has a suite of capability bits, which varies by class.

A RestrictedAccessException is thrown when an attempt is made to set the capability bits of an object that is part of a live or a compiled scene graph.

Java 3D programs usually comprise two BranchGroup objects: the view branch graph and the content branch graph. The view branch graph outlines the viewing parameters, such as the viewing location and direction. The content branch graph specifies the contents of the virtual universe: appearance, behavior, geometry, lights, location, and sound. Together, the two branches stipulate much of the work the renderer has to do.

BranchGroup objects can be compiled. Compiling a BranchGroup converts the internal representation of the BranchGroup object and all of its ancestors to a more efficient form for the rendering engine. Compiling BranchGroup objects is recommended as the last step before making it live.

TransformGroup Class

The TransformGroup class is a subclass of the Group class. TransformGroup objects hold geometric transformations such as translation and rotation. A TransformGroup node specifies the position (relative to the Locale), orientation, and scale of the geometric objects in the virtual universe.

Figure 30 :  Basic Virtual Universe hierarchy diagram.

In the figure above, the Shape3D node references, for example, Appearance and Geometry node components. The Geometry object describes the geometric shape of a 3D object, while the Appearance object describes the appearance of the geometry, such as color, transparency, and other rendering attributes.

Again, in the figure above, TransformGroup specifies the position (relative to the Locale), orientation, and scale of ViewPlatform. ViewPlatform defines the end-user's view within the virtual universe.


8.8 Rendering

The Java 3D renderer traverses a Java 3D scene graph and displays its visible geometry in an on-screen window. In addition to drawing visible geometry, the Java 3D renderer also processes user input and performs behaviors.

The Java 3D API supports three rendering modes. The modes differ in the amount of control that the developer has over the rendering process, and that Java 3D has over optimizing rendering:

Figure 31 :  Rendering modes.

Immediate mode

The immediate mode offers the developer complete rendering control, which means that Java 3D has little opportunity to optimize rendering.

An application must provide a Java 3D draw() method with a complete set of points, lines, or triangles.

Retained mode

This mode balances the amount of rendering control between the developer and Java 3D. Retained mode requires that the developer construct a scene graph and specify the parts of the scene graph that may change during rendering. Scene graphs rendered in this mode allow the developer to add, delete, or modify nodes. The scene information is stored in a scene graph structure, so Java 3D is able to perform rendering optimizations in an effort to increase performance.

Compiled-retained mode

Similar to retained mode, compiled-retained mode requires that the developer construct a scene graph and specify the parts of the scene graph that may change in the rendering process.

A developer can compile individual Java 3D objects, and can specify portions of the scene graph for Java 3D to compile. While compiled entities are similar to noncompiled counterparts, compiled scene graphs and objects are stored in an internal format that is optimized for rendering.

Please note that once scene graphs and objects have been compiled, however, developers will have limited access to the internal structure.


8.9 Behaviors

To support interactivity, Java 3D allows developers the opportunity to create customized behaviors for objects in a virtual universe, embedding the logic into the scene graph so that an object can change in response to specific input or a stimulus.

Behavior node

A Behavior node can be added or removed from a scene graph. Every Behavior node contains a scheduling region that defines a spatial volume for enabling node scheduling.

A Behavior node contains an initialization() method that initializes the internal state of the behavior and specifies one or more wakeup conditions. The initialization() method is called when the BranchGroup object containing the behavior is added to the virtual universe.

As well, all Behavior nodes contain a processStimulation() method, which is used to receive and process stimulation. A behavior's processStimulation() method is invoked:


8.10 Java 3D-Enabled Charting Features

8.10.1 Texture Mapping

For more control over the output, the Java 3D implementation of JClass Chart 3D provides you with methods which allow you to apply an image to the walls of the chart plot cube. These easy methods enable you to add texture and graphics to objects, allowing an enhanced artistic representation.

The first step in applying a Texture Map is to ensure that the image you would like to use is a Java 3D Texture object. The JCTexture2D class will provide you with many static factory methods to convert your image into a valid Texture2D object. Please note that because OpenGL imposes limits on the size of a Texture2D object, the factory methods in JCTexture2D will help you create a valid Texture2D object using an arbitrarily sized image.

Note: If the dimension of your source image is not a power of 2 (for instance, 512 or 1024), JCTexture2D.createTexture(String filename, Color fill) will center the image specified by filename in a larger image that is dimensionally correct. Any empty space around the original image will be filled with the color specified by the specified Color argument fill.

For more control over the alignment of the image within the Texture object use the following factory method:

JCTexture.createTexture(String filename, boolean square,
    int hAlignment, int vAlignment, Color fill)

where hAlignment is one of SwingConstants.LEFT, SwingConstants.CENTER, or SwingConstants.RIGHT, vAlignment is one of SwingConstants.TOP, SwingConstants.CENTER, or SwingConstants.BOTTOM, and the Boolean square argument is used to force the final Texture object to be square if set to true. Please note that the filename argument must point to a valid image file which can be loaded by the Java AWT Toolkit, or by Java Advanced Imaging (JAI) if it is installed. Please refer to the respective APIs to find out which formats are valid.

For even more control over the construction of a Texture2D object, you can use any of the factory methods found in the TextureLoader class, or manipulate them yourself. Please refer to the Java 3D API for the Texture2D class for further details on constructing a Texture2D object, and for further details on the Texture2D object itself.

To apply your Texture2D object to the cube walls, use one of the JCPlotCube methods, such as setWallTexture(int face, Texture2D texture, double angle) or setTexture(Texture2D texture).

8.10.2 Lighting

In order to create a virtual universe that has a realistic appearance, one must consider the lighting in the environment. The way that the light influences the appearance of objects is essential to creating the view you want to achieve. Java 3D gives JClass Chart 3D the power of selecting among four types of lighting to use in your output:

Note: Lighting can become a resource-intensive feature for browsers. It is recommended that you do not overuse the amount of light sources you have in your 3D virtual universe.

Ambient Light

Ambient light is uniform light, and thus produces uniform shade. Ambient light is intended as fill light in the scene where other sources do not light.

// AmbientLight Code Example
chart3d = new JCChart3dJava3d();
      .
      .
      .
JCChart3dAreaX area = (JCChart3dAreaX)(chart3d.getChart3dArea());
AmbientLight light = new AmbientLight();
light.setColor(new Color3f(java.awt.Color.yellow));
light.setEnable(true);
area.addLighting(light);

Directional Light

Directional light is representational of the sun in our universe. In the virtual universe, however, the light has no source, only parallel rays that all approach from the same direction. A directional light source is very useful when creating an environment that requires proper lighting, without much consideration to the actual source. Directional light can either be on or off. Because directional light is not ambient light, thus it does not degrade in any way, that is, it will produce a uniform shade.

Figure 32 :  The effect of directional light on a cube.

Although you can manipulate the color and intensity of directional light, this type of lighting does not allow much other control. By setting the On field to true, the directional light will have been turned on.

// DirectionalLight Code Example
chart3d = new JCChart3dJava3d();
      .
      .
      .
JCChart3dAreaX area = (JCChart3dAreaX)(chart3d.getChart3dArea());
DirectionalLight light = new DirectionalLight();
light.setColor(new Color3f(java.awt.Color.yellow));
light.setDirection(new Vector3f(0.0f, -1.0f, 0.0f));
light.setEnable(true);
area.addLighting(light);

Point Light

A point light is a light source representative of a light bulb, where the light is emitted from one location in a radial pattern. One can select the source location of this type of light, as well as customizing the color and intensity.

Figure 33 :  The effect of point light on a cube.

Point light also has the added capacities of attenuation and ambient intensity. Attenuation is the reproduction of "light attenuation", the process by which light tapers off as it progresses in the distance. By using this feature, the scene will appear more realistic.

// PointLight Code Example

chart3d = new JCChart3dJava3d();
      .
      .
      .
JCChart3dAreaX area = (JCChart3dAreaX)(chart3d.getChart3dArea());
PointLight light = new PointLight();
light.setColor(new Color3f(java.awt.Color.yellow));
light.setPosition(new Point3f(0.0f, 2.0f, 0.0f));
light.setAttenuation(new Point3f(1.0f, 0.0f, 0.0f));
light.setEnable(true);
area.addLighting(light);

Spot Light

Similar to a spot light in the real world, the spot light node is used to create light that travels in one specified direction in what appears to be a cone. This "light cone" forces the light to concentrate upon specific locations, leaving the rest of the environment in the darkness.

Figure 34 :  The effect of spot light on a cube.

Spot light is the most complex light source, in that there are several fields that must be specified in order to create ideal lighting. These include location, concentration, and attenuation, along with direction, beamWidth and spreadAngle.

// SpotLight Code Example

chart3d = new JCChart3dJava3d();
      .
      .
      .
JCChart3dAreaX area = (JCChart3dAreaX)(chart3d.getChart3dArea());
SpotLight light = new SpotLight();
light.setColor(new Color3f(java.awt.Color.yellow));
light.setPosition(new Point3f(0.0f, 2.0f, 0.0f));
light.setAttenuation(new Point3f(1.0f, 0.0f, 0.0f));
light.setDirection(new Vector3f(0.0f, -1.0f, 0.0f));
light.setSpreadAngle((float)(Math.PI/2.0));
light.setConcentration(1.0f);
light.setEnable(true);
area.addLighting(light);

Since the spot light does not emit light in a radial range, it is necessary to direct the light to the appropriate location. Do this by customizing the direction field, knowing that the location field specifies the tip of the light, and the direction specifies its final destination.

The next two fields, concentration and spreadAngle, deal with the "light cone" that is emitted. In other words, it will indicate how large the light source will be when it hits its final destination, at full intensity.

8.10.3 Depth Cue

JClass Chart 3D has the capability, when using the Java 3D implementation, to add a fog-like appearance to the charts you produce. Hence, you can create visual effects to simulate haze, mist, smoke, or pollution, blurring the appearance of all objects to which the effect is applied.

The Fog node can be used to enhance the appearance of a JClass Chart 3D object, making it appear more realistic. Based on distance from the viewer, Java 3D will blend the fog color with objects in the scene - objects that are the furthest from the viewpoint will be the most blended. Typically the Fog node is used to make objects in the distance blur, although the opposite effect is possible.

It is suggested that one uses the same color for both the fog color and JCChart3dArea background color, forcing objects that are completely obscured by the fog to blend into the background.

To calculate the color of the fog applied to an object, the following equation is used:

foggedColor = fogFactor * originalColor + (1-fogFactor) * fogColor

where the fogFactor is some function of the distance the viewer is from the object (Z-depth). The exact relationship depends upon the type of fog used in the virtual universe - either LinearFog or ExponentialFog.

Fog

The Fog leaf node defines a set of fog parameters common to all types of fog. These parameters include the fog color and a region of influence in which this Fog node is active. A Fog node also contains a list of Group nodes that specifies the hierarchical scope of this Fog. If the scope list is empty, then the Fog node has universe scope: all nodes within the region of influence are affected by this Fog node. If the scope list is not empty, then only those Leaf nodes under the Group nodes in the scope list are affected by this Fog node (subject to the influencing bounds).

If the regions of influence of multiple Fog nodes overlap, Java 3D will choose a single set of fog parameters for those objects that lie in the intersection. This is done in an implementation-dependent manner, but in general, the Fog node that is closest to the object is chosen.

Fog is an abstract class with two subclasses: LinearFog and ExponentialFog.

LinearFog

LinearFog is a Leaf node that defines the parameters of fog distance for a linear fog. LinearFog extends the Fog node by adding a pair of distance values, in Z, at which the fog should start obscuring the scene and should maximally obscure the scene. The front and back fog distances are defined in the local coordinate system of the node, but the actual fog equation will ideally take place in eye coordinates.

// LinearFog Code Example

chart3d = new JCChart3dJava3d();
      .
      .
      .
JCChart3dAreaX area = (JCChart3dAreaX)(chart3d.getChart3dArea());
LinearFog fog = new LinearFog();
fog.setColor(new Color3f(java.awt.Color.black));
fog.setFrontDistance(4.5f);
fog.setBackDistance(7.0f);
area.addFog(fog);

Figure 35 :  The effect of LinearFog on a cube.

Figure 36 :  The effect of the Fog turned off.

When using LinearFog, the fogFactor is directly proportional to the Z-depth (distance of the viewer to the object). The fogFactor can be calculated using the following expression:

fogFactor = (backDistance - z) / (backDistance - frontDistance)

where z is the distance from the viewpoint, backDistance is the Z-depth at which all objects will be completely obscured by the fog, and frontDistance is the Z-depth at which fog begins to take effect.

ExponentialFog

The ExponentialFog leaf node extends the Fog node by adding fog density. This density is a value created through an exponent, based on distance, of the fogging. This creates the effect of a nearby object having no fog, and the more distant objects having an exponential amount of fog.

In addition to specifying the fog density, ExponentialFog lets you specify the fog color, which is represented by R, G, and B color values, where a color of (0,0,0) represents black and (1,1,1) represents white.

ExponentialFog increases the fogFactor exponentially as the Z-depth of the object increases, following the proceeding expression:

fogFactor = e-(density * z)

where z is the distance from the viewpoint and density is the density of the fog.

// ExponentialFog Code Example

chart3d = new JCChart3dJava3d();
      .
      .
      .
JCChart3dAreaX area = (JCChart3dAreaX)(chart3d.getChart3dArea());
ExponentialFog fog = new ExponentialFog();
fog.setColor(new Color3f(java.awt.Color.black));
fog.setDensity(1.0f);
area.addFog(fog);

PreviousNextIndex