The Java 3D API Specification |

A P P E N D I X G

The Example Programs

> THIS appendix describes the example programs available for download from the Java 3D web site.

> ## G.1 Introduction

> Before you can compile Java 3D applications or run the example programs, you need to have installed or you need to install the following software on your system:

> - Java 2 SDK version 1.2 or later

> - Java 3D API

> - OpenGL

> The `demo/java3d` directory contains 37 subdirectories. All but two of these directories (`geometry` and `images`) contain at least one example program. Some directories contain several example programs.

> Each example program consists of two files, a `.java` file and a `.class` file. For example, the `ConicWorld` directory contains the `.java` and `.class` files for six example programs: BoxExample, ConicWorld, FlipCylinder, SimpleCylinder, TexturedCone, and TexturedSphere.

> ## G.2 Running the Example Programs

> All of the example programs can be run as standalone applications from a UNIX shell or a DOS window. The syntax shown in this appendix is for UNIX. In DOS windows, you will need to replace "`/`" with "`\`" and specify the correct drive letter when referring to `<jdkhome>` (for example, "`c:\jdk1.2.2`").

> For example, to run the HelloUniverse program, change your current directory ("`cd`") to the `<jdkhome>/demo/java3d/HelloUniverse` directory, where `<jdkhome>` is the directory in which the Java 2 SDK is installed, and type the following:

>     % java HelloUniverse

> Each of the other example programs can be run in a similar manner.

> Some of the example programs require a larger heap size (memory pool) than the default provided by Java. To increase the maximum heap size to 64 megabytes, run `java` with the "`-Xmx64m`" option. For example,

>     % java -Xmx64m HelloUniverse

> Several of the example programs can be run as applets, either within a browser (using Java Plug-in) or by running the applet from within the Java utility program called `appletviewer`.

> ### G.2.1 Running within a Browser

> Java 2 applets, including many Java 3D example programs, can be run within a browser using Java Plug-in. Special HTML tags are required to cause Netscape or Internet Explorer to use the correct version of the Java 2 platform via Java Plug-in. All of the Java 3D example programs that can be run as applets include HTML files that have been converted to use Java Plug-in. Refer to the following URL for information on using Java Plug-in 1.2.2 HTML Converter to convert your own applets to run in a browser:

>     http://java.sun.com/products/plugin/

> On Windows, the Java Plug-in is automatically installed along with the Java 2 run-time environment. Applets can be run in either Netscape Communicator or Internet Explorer.

> On Solaris, Java 3D applets can be run in Netscape Communicator 4.51 or later on Solaris 2.6 or later. After installing Netscape Communicator, you need to install Java Plug-in version 1.2 or later. Netscape Communicator and Java Plug-in may be downloaded for free from

>     http://www.sun.com/solaris/netscape/

> Additional patches may be required (see the website for details).

> In both cases (Windows and Solaris), Java 3D applets are run within the Java Plug-in by opening the Java Plug-in version of the associated HTML file. These files are of the form `<demo-name>_plugin.html`, where `<demo-name>` is the name of the particular Java 3D applet. For example, to run the HelloUniverse example program within a browser, open the `HelloUniverse/HelloUniverse_plugin.html` file in your browser.

> The following page contains links to all of the Java 3D demos that can be run as applets:

>     <jdkhome>/demo/java3d/index.html

> Just click on the link for a given demo to run that demo within your browser.

> Some Java 3D applets require a larger heap size (memory pool) than the default provided by Java Plug-in. To increase the heap size to 64 megabytes, run the Java Plug-in Control Panel application (from the Start menu in the Programs section on Windows) and set the "Java Run Time Parameters" to "`-Xmx64m`".

> ### G.2.2 Running within Appletviewer

> To run Java 3D applets within `appletviewer`, open the original, unconverted version of the associated HTML file (not the "`_plugin`" version). For example,

>     % appletviewer HelloUniverse.html

> Some Java 3D applets require a larger heap size (memory pool) than the default provided by Java. To increase the maximum heap size to 64 megabytes, run `appletviewer` with the "`-J-Xmx64m`" option. For example,

>     % appletviewer -J-Xmx64m HelloUniverse.html

> ## G.3 Program Descriptions

> Several example programs are included in the `demo/java3d` directory. All of the example programs are described here. Code fragments are listed for a few of the example programs.

> The mouse can be used to manipulate the view in many of the example programs. In these examples, the left mouse button rotates the view, the middle mouse button zooms in and out, and the right mouse button pans the view.

> ### G.3.1 AWT_Interaction

> Directory: `demo/java3d/AWT_Interaction`

> The AWT_Interaction program displays a cube in a window. A "Rotate" button at the top of the window rotates the cube in steps each time the button is selected. This program demonstrates modifying the scene graph directly from the AWT event thread using the ActionListener interface. This example is derived from the Hello-Universe example, but instead of being continuously modified by a RotationInterpolator behavior, the object's TransformGroup is set to a new value that is computed each time the "Rotate" button is pressed.

> The relevant source code fragments from `AWT_Interaction.java` follow:

>     public class AWTInteraction extends Applet
>                                         implements ActionListener {
>         TransformGroup objTrans;
>         float angle = 0.0f;
>         Transform3D trans = new Transform3D();

>         Button rotateB = new Button("Rotate");

> This code creates instance variables for the current angle, the TransformGroup that will be modified, and a button that will trigger the modification. The AWTInteraction class implements ActionListener so that it can receive button press events. The `createSceneGraph` method (not shown here) creates a root BranchGroup, an object TransformGroup, and a color cube, much as in HelloUniverse.

>     public AWTInteraction() {
>         ...
>         Panel p = new Panel();
>         p.add(rotateB);
>         add("North", p);

>         rotateB.addActionListener(this);
>         ...
>     }

> The constructor puts the Rotate button in a panel and adds the AWTInteraction class as an action listener for the button.

>     public void actionPerformed(ActionEvent e) {
>         if (e.getSource() == rotateB) {
>             angle += Math.toRadians(10);
>             trans.rotY(angle);
>             objTrans.setTransform(trans);
>         }
>     }

> The `actionPerformed` method increments the `angle`, computes a new rotation matrix, and updates the object's TransformGroup. Since this is in an AWT event listener method rather than in a behavior, the transform update is not synchronized with the Java 3D renderer. In particular, if such an event listener method modifies two objects in the Java 3D scene graph, there is no guarantee that the effects of those two updates will be seen in the same frame. Also remember that it is never safe for two threads to modify the same Java 3D object simultaneously. This means that an object that is being updated by a behavior must not be modified by an AWT event listener.

> ### G.3.2 AlternateAppearance

> Directory: `demo/java3d/AlternateAppearance`

> The AlternateAppearanceBoundsTest and the AlternateAppearanceScopeTest programs demonstrate the ability of the AlternateAppearance node to override the appearance of Shape3D nodes. The programs display a 5 x 5 matrix of spheres and a control panel. The control panel allows you to select different scopes and appearance colors. The AlternateAppearanceBoundsTest program allows you to choose one of three different sizes of BoundingSpheres for the region of influence of the AlternateAppearance node, select whether a bounds object or a bounding leaf is used, and enable or disable the appearance override enable flag in each of the objects. The AlternateAppearanceScopeTest program allows you to set the hierarchical scoping of the AlternateAppearance node and enable or disable the appearance override enable flag in each object in a group of objects.

> ### G.3.3 Appearance

> Directory: `demo/java3d/Appearance`

> The AppearanceTest program displays an image background and nine rotating tetrahedron primitives. The tetrahedra are constructed with different material properties. The relevant source code fragments from `AppearanceTest.java` follow:

>         int row, col;
>         Appearance[][] app = new Appearance[3][3];

>         for (row = 0; row < 3; row++)
>             for (col = 0; col < 3; col++)
>                 app[row][col] = createAppearance(row * 3 + col);

>         for (int i = 0; i < 3; i++) {
>             double ypos = (double)(i - 1) * 0.6;
>             for (int j = 0; j < 3; j++) {
>                 double xpos = (double)(j - 1) * 0.6;
>                 objRoot.addChild(createObject(app[i][j],
>                                     0.12,    xpos, ypos));
>             }
>         }

> The above code, extracted from the `createSceneGraph` method, creates a 3 x 3 array of objects, each with its own Appearance, and adds them to the scene graph.

> The `createAppearance` method takes in an object index from 0 to 8 and generates a unique Appearance for each object (using a switch statement). The objects are, in order from left to right and from bottom to top; an unlit solid, an unlit wire frame, unlit points, a lit solid, a texture-mapped lit solid, a transparent lit solid, a lit solid with no specularity, a lit solid with only a specular highlight (black ambient and diffuse), and a lit solid with a different material color. The code fragments for the texture mapped and transparent cases follow:

>     private Appearance createAppearance(int idx) {
>         Appearance app = new Appearance();

>         // Globally used colors

>         Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
>         Color3f white = new Color3f(1.0f, 1.0f, 1.0f);

>         switch (idx) {
>         ...
>         case 4:
>             // Set up the texture map

>             TextureLoader tex = new TextureLoader(texImage, this);
>             app.setTexture(tex.getTexture());

>             TextureAttributes texAttr = new TextureAttributes();
>             texAttr.setTextureMode(TextureAttributes.MODULATE);
>             app.setTextureAttributes(texAttr);

>             app.setMaterial(new Material(white, black, white,
>                                             black, 1.0f));
>             break;

> For Appearance number 4, the TextureLoader utility is used to load a JPEG image from a file and create a Texture object. TextureAttributes are set up so that the lit color is blended with the texture map (`MODULATE`). Finally, a lighting Material object is created with a default color of white.

>         case 5:
>             // Set up the transparency properties

>             TransparencyAttributes ta = new TransparencyAttributes();
>             ta.setTransparencyMode(ta.BLENDED);
>             ta.setTransparency(0.6f);
>             app.setTransparencyAttributes(ta);

>             // Set up the polygon attributes

>             PolygonAttributes pa = new PolygonAttributes();
>             pa.setCullFace(pa.CULL_NONE);
>             app.setPolygonAttributes(pa);

>             // Set up the material properties

>             Color3f objColor = new Color3f(0.7f, 0.8f, 1.0f);
>             app.setMaterial(new Material(objColor, black, objColor,
>                                              black, 1.0f));
>             break;

>         ...

>         return app;
>     }

> For Appearance number 5, TransparencyAttributes are set up to use blended transparency with the object being 60 percent transparent. Back face culling is disabled in the PolygonAttributes object so that the front and back faces of the transparent object are visible. Finally, a lighting Material object is created with the specified object color.

> The `createObject` method (not shown) takes in an Appearance object, a scale value, and x and y position values. From these parameters, it creates a rotating tetrahedron that is positioned and scaled appropriately. The geometry for the tetrahedron is created by the `Tetrahedron.java` file.

> ### G.3.4 AppearanceMixed

> Directory: `demo/java3d/AppearanceMixed`

> The AppearanceMixed program displays the same image background and nine rotating tetrahedra (with different material properties) as the AppearanceTest program described earlier. It adds a pair of triangles that are drawn in immediate mode; this immediate-mode rendering is mixed in with the retained-mode objects (the tetrahedra).

> An application subclasses Canvas3D and overrides the renderField to render geometry in mixed-immediate mode. The relevant source code fragments from the MyCanvas3D class in `AppearanceMixed.java` follow:

>     static class MyCanvas3D extends Canvas3D {
>         private GraphicsContext3D gc;
>         ...

>         private IndexedTriangleArray tri =
>             new IndexedTriangleArray(4,
>                     IndexedTriangleArray.COORDINATES |
>                     IndexedTriangleArray.NORMALS, 6);

>         private Point3f vert[];
>         private Vector3f normals[];

>         public void renderField(int fieldDesc) {
>             computeVert();
>             computeNormals();
>             gc.draw(tri);
>         }

>         private void computeVert() {
>             <modify vert[] array>
>             ...
>             tri.setCoordinates(0, vert);
>         }

>         private void computeNormals() {
>             <compute new normals[] based on vert[] values>
>             ...
>             tri.setNormals(0, normals);
>         }

> The `renderField` method is called by Java 3D during the rendering loop for each frame. The AppearanceMixed example overrides this Canvas3D method to compute a new set of vertices and normals for the pair of triangles and to draw the triangles to the canvas. The `computeVert` and `computeNormals` update the `vert` and `normals` array and then call the methods to copy these changes to the IndexedTriangleArray object.

>         public MyCanvas3D(GraphicsConfiguration gcfg) {
>             super(gcfg);
>             ...

>             // Set up the graphics context

>             gc = getGraphicsContext3D();

>             // Create the appearance for the triangle fan

>             Appearance app = new Appearance();
>             ...
>             gc.setAppearance(app);

>             // Set up the global lights

>             Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
>             Vector3f lDir1    = new Vector3f(-1.0f, -1.0f, -1.0f);
>             Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
>             gc.addLight(new AmbientLight(alColor));
>             gc.addLight(new DirectionalLight(lColor1, lDir1));
>         }

> The constructor for MyCanvas creates a Graphics3D object and initializes its appearance and lights. Note that even though the scene graph also contains light objects, they are not used for immediate mode rendering-lights must be created and added to the graphics context in order for immediate mode geometry to be lit.

> ### G.3.5 Background

> Directory: `demo/java3d/Background`

> The BackgroundGeometry program demonstrates the use of background geometry. The inside of a Sphere is texture mapped and used as background geometry, which is rendered by Java 3D as if it were infinitely far away. The background is position- and scale-invariant-only rotations affect how the geometry is rendered. This demo demonstrates this with a group of boxes drawn in the virtual world. The viewing platform can be adjusted with the mouse buttons. Notice how translations do not affect the background, but rotations do.

> ### G.3.6 Billboard

> Directory: `demo/java3d/Billboard`

> The Bboard and BboardPt programs demonstrate the use of Java 3D's Billboard behavior to rotate a billboard around the y axis and around a fixed point, respectively. Use the left mouse button to rotate the scene, the middle button to zoom, and the right button to translate.

> Note: Billboard's functionality has largely been superseded by OrientedShape3D.

> ### G.3.7 ConicWorld

> Directory: `demo/java3d/ConicWorld`

> This directory contains a README file and six demonstration programs:

> - The ConicWorld program shows spheres, cylinders, and cones of different resolutions and colors.

> - The SimpleCylinder program demonstrates a simple cylinder object. The left mouse button rotates the cylinder, and the middle button zooms.

> - The BoxExample program demonstrates a rotating texture-mapped box. The left mouse button rotates the box, and the middle button zooms.

> - The FlipCylinder program puts up a textured cylinder that can be rotated and zoomed with the mouse. The left mouse button rotates, the middle button zooms, and the right button translates.

> - The TexturedCone and TexturedSphere programs demonstrate the use of texture mapping with the Cone and Sphere primitives, respectively.

> These programs demonstrate the use of the geometry primitives in the `com.sun.j3d.utils.geometry` package.

> ### G.3.8 FourByFour

> Directory: `demo/java3d/FourByFour`

> The FourByFour program is a three-dimensional game of tic-tac-toe on a 4 x 4 x 4 cube. Once loaded, press the "Instructions" button for information on how to play the game.

> ### G.3.9 GearTest

> Directory: `demo/java3d/GearTest`

> The GearTest program shows a single rotating gear. The GearBox program shows a rotating gear assembly with five gears and gear shafts. The entire gear assembly can be manipulated with the mouse. The geometry in this example program is mathematically computed and demonstrates the use of different Java 3D geometry types. The Gear, SpurGear, and Shaft classes contain most of the geometry creation methods.

> ### G.3.10 GeometryByReference

> Directory: `demo/java3d/GeometryByReference`

> The GeometryByReferenceTest program draws a pair of triangles using the new geometry-by-reference API in the GeometryArray object. The geometry or color data is modified when the corresponding item is selected from the "Update Data" combo box.

> The ImageComponentByReferenceTest program draws a small raster object in the upper left corner and a larger texture mapped square, using the same image as a texture, in the middle of the window. This program demonstrates the new by-reference API for passing image data to Java 3D. It also demonstrates the new y-up versus y-down attribute for images. Use the combo boxes at the bottom of the screen to select the desired mode for the raster image and the texture image.

> The InterleavedTest program draws a pair of triangles using the new interleaved geometry-by-reference API in the GeometryArray object.

> ### G.3.11 GeometryCompression

> Directory: `demo/java3d/GeometryCompression`

> The cgview program loads an object from a compressed geometry resource (.cg) file and displays it on the screen. The object can be manipulated with the mouse. Run the program with the following command:

>     java cgview <.cg file> [object-number]

> You can use one of the .cg resource files in the `demo/java3d/geometry` directory. The following example will display a galleon (ship):

>     % java cgview ../geometry/galleon.cg

> The obj2cg program reads one or more Wavefront .obj files, compresses them, and appends the corresponding compressed objects to the specified compressed geometry resource (.cg) file. Run the program with the following command:

>     java obj2cg <.obj file> [<.obj file> ...] <.cg file>

> If the .cg file does not exist, it is created. If the file does exist and is a valid .cg resource file, the new object(s) are appended to the objects in the existing file. If it is not a valid .cg file, an exception is thrown.

> The ObjectFileCompressor class provides the methods, used by obj2cg, to compress Wavefront .obj files into Java 3D CompressedGeometry nodes. The `ObjectFileCompressor.html` file is the javadoc that describes the methods.

> ### G.3.12 HelloUniverse

> Directory: `demo/java3d/HelloUniverse`

> The HelloUniverse program creates a cube and a RotationInterpolator behavior object that rotates the cube at a constant rate of /2 radians per second. The code for this program is described in Section 1.6.3, "HelloUniverse: A Sample Java 3D Program."

> ### G.3.13 LOD

> Directory: `demo/java3d/LOD`

> The LOD program demonstrates the use of the DistanceLOD behavior to select automatically from among four different resolutions of a shaded, lit sphere. The middle mouse button moves the object closer and farther away from the viewer. As the object gets farther away from the viewer, successively lower-resolution versions of the sphere are displayed.

> ### G.3.14 Lightwave

> Directory: `demo/java3d/Lightwave` directory

> The Viewer program is a loader and viewer for Lightwave 3D scene files. This program implements only a subset of the features in Lightwave 3D. The `README.txt` file contains release notes for the loader. The Viewer program takes the name of a Lightwave 3D scene (.lws) file as its only argument. For example,

>     % java Viewer ballcone.lws

> will display a red cone moving behind a stationary green ball.

> ### G.3.15 ModelClip

> Directory: `demo/java3d/ModelClip`

> The ModelClipTest and ModelClipTest2 programs show model clipping. The ModelClipTest program draws an object that is clipped by a model clipping plane. The mouse can be used to manipulate the object. Note that the clipping plane moves with the object. The ModelClipTest2 program has a fixed object with a movable model clipping plane. The mouse can be used to manipulate the model clipping plane.

> ### G.3.16 Morphing

> Directory: `demo/java3d/Morphing`

> The Morphing program displays at the bottom of the window a hand that morphs among the static views of the three hands at the top of the window. The Pyramid2Cube program is a simpler example that morphs among three cubes.

> ### G.3.17 ObjLoad

> Directory: `demo/java3d/ObjLoad`

> The ObjLoad program loads Wavefront object files. Run the program with the following command:

>     java ObjLoad [-s] [-n] [-t] [-c degrees] <.obj file>

>      where the options are

>     -s

>     Spin (no user interaction)

>     -n

>     No triangulation

>     -t

>     No stripification

>     -c

>     Set crease angle for normal generation (default is 60 without smoothing group info, otherwise 180 within smoothing groups)

> You can use one of the .obj files in the `demo/java3d/geometry` directory. The following example will display a galleon (ship):

>     % java ObjLoad ../geometry/galleon.obj

> The relevant source code fragment from `ObjLoad.java` follows:

>     public BranchGroup createSceneGraph(String args[]) {
>         ...
>         int flags = ObjectFile.RESIZE;
>         ...
>         ObjectFile f = new ObjectFile(flags,
>             (float)(creaseAngle * Math.PI / 180.0));
>         Scene s = null;
>         try {
>             s = f.load(filename);
>         }
>         catch (FileNotFoundException e) {
>             System.err.println(e);
>             System.exit(1);
>         }
>         catch (ParsingErrorException e) {
>             System.err.println(e);
>             System.exit(1);
>         }
>         catch (IncorrectFormatException e) {
>             System.err.println(e);
>             System.exit(1);
>         }

>         objTrans.addChild(s.getSceneGroup());

> The above code fragment creates an ObjectFile loader with the desired flags and crease angle, loads the specified filename (checking for file and parsing exceptions), and adds the loaded objects to the scene graph. This code fragment could easily be modified to accommodate a variety of loaders.

> ### G.3.18 OffScreenCanvas3D

> Directory: `demo/java3d/OffScreenCanvas3D`

> The OffScreenTest program creates a scene graph containing a cube and renders that cube to an on-screen Canvas3D. In the `postSwap` routine of the on-screen Canvas3D, an off-screen rendering of the same scene is done to the off-screen buffer. The resulting image is then used as the source image for a Raster object in the scene graph.

> The PrintFromButton program is similar to the OffScreenTest program, except that it doesn't automatically render to the off-screen buffer during the `postSwap` callback of its on-screen Canvas3D. The off-screen rendering is done when the "Print" button is pressed.

> ### G.3.19 OrientedShape3D

> Directory: `demo/java3d/OrientedShape3D`

> The OrientedTest and OrientedPtTest programs demonstrate the use of Java 3D's OrientedShape3D nodes to create geometry that is oriented about the y axis and around a fixed point, respectively. These are essentially the same example programs used in the Billboard example, except that they use an OrientedShape3D node rather than a Billboard behavior. Use the left mouse button to rotate the scene, the middle button to zoom, and the right button to translate. Notice how the text does not jump around as it does when using a Billboard behavior.

> ### G.3.20 PackageInfo

> Directory: `demo/java3d/PackageInfo`

> The PackageInfo program lists the package information for the Java 3D packages installed on the system. This can be used to determine which version of Java 3D you are running.

> The QueryProperties program lists the values of the properties returned by the `queryProperties` method of the Canvas3D that is created from the preferred GraphicsConfiguration returned by SimpleUniverse.

> ### G.3.21 PickTest

> Directory: `demo/java3d/PickTest`

> The PickTest program displays several 3D objects and a control panel. The control panel allows the user to change the pick mode, the pick tolerance, and the view mode. You can pick and rotate objects with the mouse. The PickTest program demonstrates the use of the PickMouseBehavior utility classes.

> The IntersectTest program demonstrates the ability to get geometric intersection information from a picked object. Use the mouse to pick a point on one of the objects in the window. The program illuminates the picked location and the vertices of the primitive with tiny spheres. Information about the picked primitive and the point of intersection is printed. The IntersectTest program uses a mouse-based behavior, IntersectInfoBehavior, to control the picking. The relevant source code fragments from `IntersectInfoBehavior.java` follow:

>     PickCanvas pickCanvas;
>     PickResult[] pickResult;
>     public IntersectInfoBehavior(Canvas3D canvas3D,
>             BranchGroup branchGroup,
>             float size) {

>         pickCanvas = new PickCanvas(canvas3D, branchGroup);
>         pickCanvas.setTolerance(5.0f);
>         pickCanvas.setMode(PickCanvas.GEOMETRY_INTERSECT_INFO);
>         ...

> The IntersectInfoBehavior class constructor creates a new PickCanvas object, initializes the PickCanvas with the desired tolerance, and sets the mode to allow geometry intersection information to be retrieved.

>     public void processStimulus(Enumeration criteria) {
>         ...
>         <check for mouse event>

>         if (eventId == MouseEvent.MOUSE_PRESSED) {
>             int x = ((MouseEvent)event[i]).getX();
>             int y = ((MouseEvent)event[i]).getY();
>             pickCanvas.setShapeLocation(x, y);
>             Point3d eyePos = pickCanvas.getStartPosition();
>             pickResult = pickCanvas.pickAllSorted();
>             if (pickResult != null) {
>                 // Get node info

>                 Node curNode = pickResult[0].getObject();
>                 Geometry curGeom = ((Shape3D)curNode).getGeometry();
>                 GeometryArray curGeomArray = (GeometryArray) curGeom;
>                 // Get closest intersection results

>                 PickIntersection pi =
>                     pickResult[0].getClosestIntersection(eyePos);

>                 <get specific info from PickIntersection>

>             }
>         }
>         ...

> The processStimulus method checks for a mouse event and initiates a pick, via the PickCanvas object, at the selected location. It then looks for pick results and extracts the intersection information from the pick result (if any).

> ### G.3.22 PickText3D

> Directory: `demo/java3d/PickText3D`

> The PickText3DBounds and PickText3DGeometry programs demonstrate bounds-based and geometry-based picking of Text3D objects, respectively. Both programs allow you to pick and rotate the text strings with the mouse. PickText3DBounds uses only bounds-based picking, so the string can be picked anywhere within the vicinity of its letters. PickText3DGeometry uses geometry-based picking, so the string can exactly be picked only on one of the letters in the string.

> ### G.3.23 PlatformGeometry

> Directory: `demo/java3d/PlatformGeometry`

> The SimpleGeometry program displays two geometry objects: a sphere and a rotating cube. The sphere is created as PlatformGeometry using the universe utilities. This means that it is always in a fixed location relative to the viewer.

> ### G.3.24 PureImmediate

> Directory: `demo/java3d/PureImmediate`

> The PureImmediate program demonstrates Java 3D's pure immediate mode. In this mode, objects are not placed into a scene graph but instead are drawn using the GraphicsContext3D drawing methods. The Java 3D renderer for the Canvas into which the immediate mode graphics are rendered must be stopped prior to immediate mode rendering. In this mode, the rendering is done from a user-controlled thread.

> The relevant source code fragments from `PureImmediate.java` follow:

>     public class PureImmediate extends Applet implements Runnable {
>         private Canvas3D canvas;
>         private GraphicsContext3D gc = null;
>         private Geometry cube = null;
>         private Transform3D cmt = new Transform3D();

>         // One rotation (2*PI radians) every 6 seconds

>         private Alpha rotAlpha = new Alpha(-1, 6000);

> The above code creates instance variables for a Canvas3D, the GraphicsContext associated with the canvas, a geometry object for drawing, a Transform3D object for rotation, and an alpha object to allow the rotation to be time-based. The PureImmediate class implements Runnable so that it can be run by a user-created drawing thread.

>     public void render() {
>         if (gc == null) {
>             // Set up Graphics context

>             gc = canvas.getGraphicsContext3D();
>             gc.setAppearance(new Appearance());

>             // Set up geometry

>             cube = new ColorCube(0.4).getGeometry();
>         }

>         // Compute angle of rotation based on alpha value

>         double angle = rotAlpha.value() * 2.0*Math.PI;
>         cmt.rotY(angle);

>         // Render the geometry for this frame

>         gc.clear();
>         gc.setModelTransform(cmt);
>         gc.draw(cube);
>         canvas.swap();
>     }

>     public void run() {
>         while (true) {
>             render();
>             Thread.yield();
>         }
>     }

> The `render` method renders a single frame. After ensuring that the graphics context is set up and the geometry is created, it computes the new rotation matrix, clears the canvas, draws the cube, and swaps the draw and display buffer. The `run` method is the entry point for our drawing thread. It calls the `render` method in a loop, yielding control to other threads once per frame.

>         public PureImmediate() {
>             <set layout of applet, get best graphics config>

>             canvas = new Canvas3D(config);
>             canvas.stopRenderer();
>             add("Center", canvas);

>             // Create the universe and viewing branch

>             SimpleUniverse u = new SimpleUniverse(canvas);
>             u.getViewingPlatform().setNominalViewingTransform();
>             // Start a new thread that will continuously render

>             new Thread(this).start();
>         }

> The constructor creates the 3D canvas, stops the Java 3D renderer, sets up the viewing branch (necessary even in pure immediate mode), and starts up the drawing thread.

> ### G.3.25 ReadRaster

> Directory: `demo/java3d/ReadRaster`

> The ReadRaster program creates a scene graph containing a cube and renders that cube. In the `postSwap` routine of the Canvas3D, the contents of the canvas are read back using the Immediate mode `readRaster` method. The resulting image is then used as the source image for a Raster object in the scene graph.

> ### G.3.26 Sound

> Directory: `demo/java3d/Sound`

> The SimpleSounds program shows a rotating cube and plays three different sounds, including a voice saying "Hello Universe."

> The ReverberateSound program demonstrates different amounts of reverberation. It plays a voice saying "Hello Universe" in several different environments, including a closet, an acoustic lab, a garage, a dungeon (both medium and large), and a cavern.

> The MoveAppBoundingLeaf program displays a large rotating cube and plays a single point sound source. Two Soundscape nodes are created and manipulated with a behavior. This results in one or the other being alternately selected.

> ### G.3.27 SphereMotion

> Directory: `demo/java3d/SphereMotion`

> The SphereMotion program shows a lit sphere that is continuously moving closer to and farther from the viewer. The sphere is lit by two light sources, one fixed and one rotating around the sphere. Depending on a command line option, the two light sources are created as directional lights (the default), point lights, or spot lights. Run the program with the following command:

>     java SphereMotion [-dir | -point | -spot]

> ### G.3.28 SplineAnim

> Directory: `demo/java3d/SplineAnim`

> The SplineAnim program demonstrates the use of KBRotPosScaleSplinePathInterpolator (see the description in Table F-10) to do spline animation paths using Kochanek-Bartels splines. A red cone is animated along a spline path specified by five knot points, which are shown as cyan spheres. Use the mouse to manipulate the scene.

> A control panel allows you to toggle between spline and linear interpolation, a slider to adjust the speed of the animation, and an animation start/stop button.

> ### G.3.29 Text2D

> Directory: `demo/java3d/Text2D`

> The Text2DTest program shows three different types of 2D text using the Text2D utility class.

> ### G.3.30 Text3D

> Directory: `demo/java3d/Text3D`

> The Text3DLoad program permits you to enter your own text and see how it displays in 3D. The command for running Text3DLoad is as follows:

>     java Text3DLoad [-f fontname] [-t tesselation] <text>

> The `fontname` variable allows you to specify one of the Java Font names, such as Helvetica, Times Roman, and Courier. The `tesselation` variable specifies how finely to tessellate the font glyphs. Once the text displays, the left mouse button rotates the text, the middle button zooms, and the right button translates.

> ### G.3.31 TextureByReference

> Directory: `demo/java3d/TextureByReference`

> The TextureByReference program shows a set of animating textures using the image component by-reference feature. A control panel allows you to flip the image or to set the texture and geometry by-reference flag, the image orientation flag (y-up or y-down), and the image type. It also allows you to control the texture animation speed and to stop and restart the animation.

> ### G.3.32 TextureTest

> Directory: `demo/java3d/TextureTest`

> The TextureImage program displays a rotating cube with a user-specified image file mapped onto the surface. The command for running TextureImage is

>     java TextureImage <image-filename> [-f ImageComponent format]

> The `ImageComponent format` variable allows you to specify the format of the pixel data. If you do not specify an image file, the rotating cube will appear white. You can use one of the image files in the `demo/java3d/images` directory. For example:

>     % java TextureImage ../images/earth.jpg

> will display the rotating cube with an image of earth mapped onto it.

> The MultiTextureTest program displays a box with two textures applied to it. You can enable different combinations of one or two textures with the pop-up menu. Use the mouse buttons to manipulate the object.

> ### G.3.33 TickTockCollision

> Directory: `demo/java3d/TickTockCollision`

> The TickTockCollision program shows an oscillating colored cube that collides with two rectangular objects. The rectangular objects change color when they collide with the cube.

> ### G.3.34 TickTockPicking

> Directory: `demo/java3d/TickTockPicking`

> The TickTockPicking program displays a set of nine spinning tetrahedra and an oscillating colored cube. Picking the cube or one of the tetrahedra with the left mouse button causes it to change color.

> ### G.3.35 VirtualInputDevice

> Directory: `demo/java3d/VirtualInputDevice`

> This directory contains another version of the HelloUniverse program with viewing position controls implemented via the InputDevice interface.

The Java 3D API Specification |

##### Copyright © 2000, Sun Microsystems, Inc. All rights reserved.