j3d Tutorial
j3d Tutorial
j3d Tutorial
2)
Getting Started with
the Java 3D
API
A Tutorial for Beginners
Chapter 0
Overview and Appendices
Dennis J Bouvier
K Computing
Getting Started with Java 3D Tutorial Preface
The Java 3D Tutorial
1999 Sun Microsystems, Inc.
2550 Garcia Avenue, Mountain View, California 94043-1100 U.S.A
All Rights Reserved.
The information contained in this document is subject to change without notice.
SUN MICROSYSTEMS PROVIDES THIS MATERIAL "AS IS" AND MAKES NO WARRANTY OF ANY KIND,
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS SHALL NOT BE
LIABLE FOR ERRORS CONTAINED HEREIN OR FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING
LOST PROFITS IN CONNECTION WITH THE FURNISHING, PERFORMANCE OR USE OF THIS MATERIAL,
WHETHER BASED ON WARRANTY, CONTRACT, OR OTHER LEGAL THEORY).
THIS DOCUMENT COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE
PERIODICALLY MADE TO THE INFORMATION HEREIN; THESE CHANGES WILL BE INCORPORATED IN NEW
EDITIONS OF THE PUBLICATION. SUN MICROSYSTEMS, INC. MAY MAKE IMPROVEMENTS AND/OR CHANGES
IN THE PRODUCT(S) AND/OR PROGRAM(S) DESCRIBED IN THIS PUBLICATION AT ANY TIME.
Some states do not allow the exclusion of implied warranties or the limitations or exclusion of liability for incidental or
consequential damages, so the above limitations and exclusion may not apply to you. This warranty gives you specific legal
rights, and you also may have other rights which vary from state to state.
Permission to use, copy, modify, and distribute this documentation for NON-COMMERCIAL purposes and without fee is
hereby granted provided that this copyright notice appears in all copies.
This documentation was prepared for Sun Microsystems by K Computing (530 Showers Drive, Suite 7-225, Mountain View,
CA 94040, 770-982-7881, www.kcomputing.com). For further information about course development or course delivery,
please contact either Sun Microsystems or K Computing.
Java, JavaScript, Java 3D, HotJava, Sun, Sun Microsystems, and the Sun logo are trademarks or registered trademarks of Sun
Microsystems, Inc. All other product names mentioned herein are the trademarks of their respective owners.
Getting Started with Java 3D Tutorial Preface
The Java 3D Tutorial 0-i
Table of Contents
OVERVIEW AND APPENDICES .................................................................................................................. 0-1
0.1 NAVIGATING THE TUTORIAL .................................................................................................................... 0-1
0.1.1 Tutorial Contents ........................................................................................................................... 0-2
Module Overview.................................................................................................................................................... 0-2
Chapter Contents..................................................................................................................................................... 0-3
What is Not in the Tutorial...................................................................................................................................... 0-5
0.1.2 How Can I Use the Tutorial ........................................................................................................... 0-5
0.1.3 Preface to the Tutorial ................................................................................................................... 0-6
Whats Inside.......................................................................................................................................................... 0-6
How to download this document .............................................................................................................................. 0-6
Audience................................................................................................................................................................. 0-6
Feedback................................................................................................................................................................. 0-6
Typographic Conventions ........................................................................................................................................ 0-6
What software is required........................................................................................................................................ 0-6
Cover Image............................................................................................................................................................ 0-6
0.1.4 Disclaimers.................................................................................................................................... 0-7
0.2 (APPENDIX A) SUMMARY OF EXAMPLE PROGRAMS ................................................................................... 0-8
0.2.1 HelloJava3D.................................................................................................................................. 0-8
examples/HelloJava3D/HelloJava3Da...................................................................................................................... 0-8
examples/HelloJava3D/HelloJava3Db ..................................................................................................................... 0-8
examples/HelloJava3D/HelloJava3Dc...................................................................................................................... 0-8
examples/HelloJava3D/HelloJava3Dd ..................................................................................................................... 0-8
0.2.2 Geometry ....................................................................................................................................... 0-8
examples/Geometry/Axis.java ................................................................................................................................. 0-8
examples/Geometry/AxisApp.java........................................................................................................................... 0-8
examples/Geometry/AxisClassDemoApp.java.......................................................................................................... 0-9
examples/Geometry/ColorConstants.java................................................................................................................. 0-9
examples/Geometry/ColorYoyoApp.java.................................................................................................................. 0-9
examples/Geometry/ConeYoyoApp.java .................................................................................................................. 0-9
examples/Geometry/TwistStrip.java ........................................................................................................................ 0-9
examples/Geometry/YoyoApp.java.......................................................................................................................... 0-9
examples/Geometry/YoyoLineApp.java ................................................................................................................... 0-9
examples/Geometry/YoyoPointApp.java.................................................................................................................. 0-9
0.2.3 EasyContent................................................................................................................................. 0-10
examples/easyContent/BackgroundApp.java.......................................................................................................... 0-10
examples/easyContent/GeomInfoApp.java ............................................................................................................. 0-10
examples/easyContent/Text2Dapp.java.................................................................................................................. 0-10
examples/easyContent/Text3Dapp.java.................................................................................................................. 0-10
0.2.4 Interaction ................................................................................................................................... 0-10
examples/Interaction/DoorApp.java....................................................................................................................... 0-10
examples/Interaction/KeyNavigatorApp.java.......................................................................................................... 0-10
examples/Interaction/MouseBehaviorApp.java....................................................................................................... 0-11
examples/Interaction/MouseNavigatorApp.java ..................................................................................................... 0-11
examples/Interaction/MousePickApp.java.............................................................................................................. 0-11
examples/Interaction/MouseRotateApp.java .......................................................................................................... 0-11
examples/Interaction/MouseRotate2App.java......................................................................................................... 0-11
examples/Interaction/PickCallbackApp.java .......................................................................................................... 0-11
examples/Interaction/SimpleBehaviorApp.java...................................................................................................... 0-11
Getting Started with Java 3D Tutorial Preface
The Java 3D Tutorial 0-ii
0.2.5 Animation .................................................................................................................................... 0-11
examples/Animation/AlphaApp.java...................................................................................................................... 0-11
examples/Animation/BillboardApp.java ................................................................................................................ 0-12
examples/Animation/ClockApp.java...................................................................................................................... 0-12
examples/Animation/InterpolatorApp.java............................................................................................................. 0-12
examples/Animation/LODApp.java ....................................................................................................................... 0-12
examples/Animation/MorphApp.java..................................................................................................................... 0-12
examples/Animation/Morph3App.java................................................................................................................... 0-12
0.2.6 Light ............................................................................................................................................ 0-12
examples/light/LightsNPlanes.java........................................................................................................................ 0-12
examples/light/LitPlane.java ................................................................................................................................. 0-12
examples/light/LitSphere.java ............................................................................................................................... 0-12
examples/light/LitTwist.java ................................................................................................................................. 0-12
examples/light/LightScope.java ............................................................................................................................. 0-13
examples/light/LocalEyeApp.java.......................................................................................................................... 0-13
examples/light/ShadowApp.java............................................................................................................................ 0-13
examples/light/ShininessApp.java ......................................................................................................................... 0-13
examples/light/SpotLightApp.java......................................................................................................................... 0-13
0.2.7 Texture......................................................................................................................................... 0-13
examples/texture/BoundaryColorApp .................................................................................................................... 0-13
examples/texture/BoundaryModeApp.................................................................................................................... 0-13
examples/texture/MIPmapApp .............................................................................................................................. 0-13
examples/texture/MIPmapApp2............................................................................................................................. 0-13
examples/texture/MIPmapDemo............................................................................................................................ 0-13
examples/texture/SimpleTextureApp..................................................................................................................... 0-14
examples/texture/SimpleTextureSpinApp.............................................................................................................. 0-14
examples/texture/Text2DTextureApp.................................................................................................................... 0-14
examples/texture/TextureCoordApp ...................................................................................................................... 0-14
examples/texture/TextureCoordGenApp................................................................................................................ 0-14
examples/texture/TexturedLineApp....................................................................................................................... 0-14
examples/texture/TexturedPlaneApp ..................................................................................................................... 0-14
examples/texture/TexturedPrimitiveApp................................................................................................................ 0-14
examples/texture/TexturedSceneApp..................................................................................................................... 0-14
examples/texture/TextureRequestApp ................................................................................................................... 0-14
0.3 (APPENDIX B) REFERENCE MATERIAL .................................................................................................... 0-15
0.3.1 Books........................................................................................................................................... 0-15
0.3.2 The Java 3D API can be downloaded from the Java 3D Home Page: ........................................... 0-15
0.3.3 Sun Java Web Pages .................................................................................................................... 0-15
0.3.4 Other Web Pages ......................................................................................................................... 0-16
0.4 (APPENDIX C) SOLUTIONS TO SELECTED SELF TEST QUESTIONS ............................................................. 0-17
0.4.1 Answers to Questions in Chapter 1............................................................................................... 0-17
0.4.2 Answers to Questions in Chapter 2............................................................................................... 0-19
0.4.3 Answers to Questions in Chapter 3............................................................................................... 0-20
0.4.4 Answers to Questions in Chapter 4............................................................................................... 0-21
0.4.5 Answers to Questions in Chapter 5............................................................................................... 0-22
0.4.6 Answers to Questions in Chapter 6............................................................................................... 0-23
0.4.7 Answers to Questions in Chapter 7............................................................................................... 0-23
0.5 GLOSSARY ............................................................................................................................................ 0-25
Getting Started with Java 3D Tutorial Preface
The Java 3D Tutorial 0-1
0
Overview and Appendices
Welcome to version 1.5 of The Java 3D API Tutorial. This tutorial contains seven chapters explaining the
most frequently used features of the Java 3D API.
Since the tutorial has been developed and released incrementally, several versions of the tutorial exist. For
this reason the revision history may be important to readers of earlier versions. The following table presents
the revision history for the tutorial.
Table 0-1 Revision History of the Tutorial.
tutorial
version
date new chapter(s)
major* revision
of chapters
minor* revision
of chapters
1.0 Feb 99 1 and 2 n/a n/a
1.1 Apr 99 0 and 6 1 and 2 n/a
1.2 May 99 3 0 and 2 1 and 6
1.3 Jun 99 4 0 1, 2, 3 and 6
1.4 August 99 5 0, 1 and 4 2, 3, and 6
1.5 October 99 7 0 1, 2, 3, 4, 5, and 6
*For the purposes of this table, a major revision is a change to fix a mistake of fact in some part of the
chapter. It could be as little as little as changing one line of code, fixing a single sentence, or adding
something inadvertently omitted, but involves a fix of substance. A minor revision is a change that does
not affect the meaning of the chapter (e.g. formatting, or including new links in the PDF file).
0.1 Navigating the Tutorial
The tutorial is a collection of modules. Each Module is a collection of chapters (except this one, Module 0
has only one chapter, Chapter 0). The chapters in a Module are related. See section 0.1.2 for more
information on module and chapter dependencies.
With each chapter of the tutorial being published as separate documents, the following features have been
employed:
Appendices: To allow easy updates to the Appendices while keeping them centrally located,
including the Glossary, are published with Chapter 0 (this chapter). As a consequence, they
appear as numbered sections in this document. However, the letter names used in version 1.0 of
the tutorial ('A', 'B', and 'C') are retained for compatibility with the older chapters.
Page numbering: To allow easy reference to pages in specific chapters, each document's page
numbering is prepended with the chapter number. For example, this is page 0-1, which is page one
of chapter zero.
Module
Getting Started with Java 3D Tutorial Preface
The Java 3D Tutorial 0-2
T(dx, dy, dz) =
1 0 0 dx
0 1 0 dy
0 0 1 dz
0 0 0 1
0.1.1 Tutorial Contents
The tutorial is organized as a collection of four modules; each is outlined in the following sections.
Beginning on page 0-3 the section titled "Chapter Contents" presents the contents of each chapter.
Module Overview
Module 0: Navigation and Appendices
The document you are reading is Module 0. In addition to the navigational material, it contains the
appendix material and the glossary. This document will be updated with each new chapter.
Module 1: Getting Started with the Java 3D API
The introductory module presents the basics of Java 3D
programming. Chapter 1 begins at the level of a Java programmer
who has never used Java 3D. By the end of the Chapter 2, the
novice Java 3D programmer understands the Java 3D scene graph,
how to create a virtual universe by specifying a scene graph, how
to create geometry, appearances, and program custom visual
objects for use in simple virtual universes
Chapter 1: Getting Started ............................................ 33 pages, February 1999
Chapter 2: Creating Content ......................................... 45 pages, February 1999
Chapter 3: Easier Content Creation.............................. 29 pages, May 1999
Module 2: Interaction and Animation
Chapter 4 covers behavior basics, along with topics related to
making interactive virtual worlds. Chapter 4 includes material
on virtual universe navigation with the mouse and keyboard and
picking. Chapter 5 continues with specialized behavior classes
such as interpolators, level of detail, and billboard behaviors to
create animated visual objects.
Chapter 4: Interaction.................................................... 52 pages, June 1999
Chapter 5: Animation .................................................... 38 pages, August 1999
Getting Started with Java 3D Tutorial Preface
The Java 3D Tutorial 0-3
Module 3: Lights and Textures
Visual richness is added to the virtual universe in this module.
Using lights, material properties, and textures, a Java 3D
programmer can create visually rich objects without creating
complex geometry.
Chapter 6: Lights ........................................................... 34 pages, April 1999
Chapter 7: Textures........................................................ 35 pages, October 1999
Chapter Contents
Here is a listing of the table of contents for each of the published chapters. If you are reading this online
you can use the links to the appropriate place in the appropriate document.
Module 1: Getting Started with the Java 3D API
Chapter 1: Getting Started
1.1 What is Java 3D...................................................................................... 1-1
1.2 The Java 3D API .................................................................................... 1-2
1.3 Building a Scene Graph........................................................................... 1-2
1.4 A Basic Recipe for Writing Java 3D Programs ........................................ 1-8
1.5 Some Java 3D Terminology..................................................................... 1-12
1.6 Simple Recipe Example: HelloJava3Da ................................................... 1-13
1.7 Rotating the Cube ................................................................................... 1-19
1.8 Capabilities and Performance .................................................................. 1-22
1.9 Adding Animation Behavior .................................................................... 1-25
1.10 Chapter Summary................................................................................... 1-33
1.11 Self Test ................................................................................................. 1-33
Chapter 2: Creating Content
2.1 Virtual Universe Coordinate System........................................................ 2-1
2.2 Visual Object Definition Basics............................................................... 2-2
2.3 Geometric Utility Classes ........................................................................ 2-6
2.4 Mathematical Classes.............................................................................. 2-15
2.5 Geometry Classes.................................................................................... 2-20
2.6 Appearance and Attributes ...................................................................... 2-34
2.7 Self Test ................................................................................................. 2-44
Getting Started with Java 3D Tutorial Preface
The Java 3D Tutorial 0-4
Chapter 3: Easier Content Creation
3.1 What is in This Chapter .......................................................................... 3-1
3.2 Loaders................................................................................................... 3-2
3.3 GeometryInfo.......................................................................................... 3-7
3.4 Text2D................................................................................................... 3-13
3.5 Text3D................................................................................................... 3-16
3.6 Background............................................................................................. 3-22
3.7 BoundingLeaf ......................................................................................... 3-26
3.8 User Data ............................................................................................... 3-28
3.9 Chapter Summary................................................................................... 3-29
3.10 Self Test ................................................................................................. 3-29
Module 2: Interaction and Animation
Chapter 4: Interaction
4.1 Behavior: the Base for Interaction and Animation ................................... 4-1
4.2 Behavior Basics ..................................................................................... 4-4
4.3 Wakeup Conditions: How Behaviors are Triggered ................................. 4-12
4.4 Behavior Utility Classes for Keyboard Navigation .................................. 4-25
4.5 Utility Classes for Mouse Interaction ...................................................... 4-29
4.6 Picking ................................................................................................... 4-35
4.7 Chapter Summary .................................................................................. 4-51
4.8 Self Test ................................................................................................ 4-51
Chapter 5: Animation
5.1 Animations.............................................................................................. 5-1
5.2 Interpolators and Alpha Object Provide Time-based Animations .............. 5-2
5.3 Billboard Class ....................................................................................... 5-24
5.4 Level of Detail (LOD) Animations........................................................... 5-28
5.5 Morph..................................................................................................... 5-33
5.6 Chapter Summary................................................................................... 5-38
5.7 Self Test ................................................................................................. 5-38
Module 3: Lights and Textures
Chapter 6: Lights
6.1 Shading in Java 3D................................................................................. 6-1
6.2 Recipe for Lit Visual Objects .................................................................. 6-4
6.3 Light Classes .......................................................................................... 6-9
6.4 Material Object ....................................................................................... 6-20
6.5 Surface Normals ..................................................................................... 6-24
6.6 Specifying the Influence of Lights............................................................ 6-25
6.7 Creating Glow-in-the-Dark Objects, Shadows and Other Lighting Issues . 6-29
6.9 Chapter Summary................................................................................... 6-34
6.10 Self-Test ................................................................................................. 6-34
Getting Started with Java 3D Tutorial Preface
The Java 3D Tutorial 0-5
Chapter 7: Textures
7.1 What is Texturing ................................................................................... 7-1
7.2 Basic Texturing....................................................................................... 7-2
7.3 Some Texturing Applications .................................................................. 7-14
7.4 Texture Attributes................................................................................... 7-16
7.5 Automatic Texture Coordinate Generation............................................... 7-20
7.6 Multiple Levels of Texture (Mipmaps) .................................................... 7-24
7.7 Texture, Texture2D, and Texture3D API................................................. 7-29
7.8 TextureLoader and NewTextureLoader API ............................................ 7-33
7.9 Chapter Summary................................................................................... 7-34
7.10 Self Test ................................................................................................. 7-35
What is Not in the Tutorial
This tutorial is on the use of the Java 3D API. The most commonly used features of the Java 3D API are
covered. Java 3D API features not covered include collisions, sensors, geometry compression, spatial
sound, multiple views. While many of the Java 3D utilities distributed with the core API are covered in the
tutorial, not all are. In addition, non-API issues such as artistic considerations, specific application
suggestions, and unusual display devices are also not covered.
0.1.2 How Can I Use the Tutorial
Modules are collections of related chapters. However, you may pick and choose the chapters that suit your
needs. In general, chapters in the same module are dependent on the earlier chapters in the same module.
For example, Chapter 2 depends on knowing the material in Chapter 1. Likewise, the reader of Chapter 5
is expected to be familiar with the topics in Chapter 4.
Module dependencies are represented in the following figure. If you have no experience with Java 3D, start
with Module 1 and proceed to either Module 2 or Module 3.
Module 1:
Getting Started
with the Java 3D
API
Module 2:
Interaction
and
Animation
Module 3:
Lights
and
Textures
START
Figure 0-1 Paths Through The Java 3D Tutorial
Getting Started with Java 3D Tutorial Preface
The Java 3D Tutorial 0-6
Throughout the tutorial are reference blocks - summaries of the API for certain classes. The reference
blocks are provided in the tutorial to make reading easier, not to replace the Java 3D API Specification
Guide or any other reference.
The reference blocks were checked for accuracy when this document was published, but the Java 3D API
may have changed. If you are having trouble with a program, be sure to check a current edition of the Java
3D API Specification. Also, refer to section 2.2 (page 2-4) for more information on reference blocks.
0.1.3 Preface to the Tutorial
Whats Inside
This is a tutorial for the Java 3D API version 1.1.2. It is composed of the text (this document), several
other text documents and a number of example applications. The text of the tutorial is available in the
Acrobat (PDF) file format. The PDF files include thumbnails, links, and bookmarks making them easier
to use online. The files are also readable in hardcopy form. However, several of the images are in color
and details are lost when printed monochromatically.
How to download this document
The tutorial documents are available online with the source for the example programs, all of which can be
downloaded from http://java.sun.com/products/java-media/3D/collateral/
Audience
This tutorial is meant for the Java programmer with some graphics experience, with little or no knowledge
of Java 3D. If in addition to being familiar with Java you are familiar with the terms pixel, image plane,
RGB, and render, then you have the background to proceed. You dont need to know about z-buffer, 3D
transforms, or any other 3D graphics API to understand this tutorial, but it may help. In any case, this
tutorial is written to be very accessible.
Feedback
As with all of our products, we strive for excellence in quality. If you have any questions, comments, or
have an error to report, please consult the Java 3D Home Page,
http://www.java.sun.com/products/java-media/3D, for contact information.
Typographic Conventions
Courier type is used to represent computer code and names of files and directories.
Italic type is used for emphasis.
Bold is used in the text to indicate program elements
Gray background represents Reference Blocks
Double outline sections are advanced sections
Single outline sections are document meta-information sections
What software is required
Consult the Java 3D Home Page for the most current information.
Cover Image
The cover image is of a twisted strip rendered by Java 3D. The program is discussed in Section 2.6. The
code is available with the examples distributed with this tutorial.
Getting Started with Java 3D Tutorial Preface
The Java 3D Tutorial 0-7
0.1.4 Disclaimers
All software associated with this tutorial is provided "AS IS," without a warranty of any kind. ALL EXPRESS OR
IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED
WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-
INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR
ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
This software included with this tutorial is not designed or intended for use in on-line control of aircraft, air traffic,
aircraft navigation or aircraft communications; or in the design, construction, operation or maintenance of any
nuclear facility. Licensee represents and warrants that it will not use or redistribute the Software for such purposes.
Getting Started with the Java 3D API A. Summary of Example Programs
The Java 3D Tutorial 0-8
0.2 (Appendix A) Summary of Example Programs
This tutorial is distributed with a set of example programs. Each example program included in the
distribution is described here. If you do not have the example programs, refer to the preface for download
instructions.
0.2.1 HelloJava3D
HelloJava3D is a series of programs used in the first chapter of the tutorial. The complexity of these
examples begins at the extreme end of simplicity and builds slightly.
examples/HelloJava3D/HelloJava3Da
This program displays a single color cube object that is static, and is neither transformed nor rotated from
the origin. Consequently, it appears as a single rectangle. This program is only intended to demonstrate
the basic construction of a Java 3D program. It is also used as the basis for the subsequent examples.
examples/HelloJava3D/HelloJava3Db
This program displays a single color cube object that is static but rotated from the original orientation.
Consequently, more than one face of the cube is visible when rendered. This program is only intended to
demonstrate the basic construction of a Java 3D program. It is also used as the basis for the subsequent
examples.
examples/HelloJava3D/HelloJava3Dc
This program displays a single color cube object that is animated. The cube spins in place at the origin.
Consequently, more than one face of the cube is visible as the animation takes place. This program is
intended to demonstrate the basic construction of an animated Java 3D program.
examples/HelloJava3D/HelloJava3Dd
This program displays a single color cube object that is transformed and animated. The cube spins in place
at the origin. Consequently, more than one face of the cube is visible as the animation takes place. This
program is intended to demonstrate the basic construction of an animated Java 3D program.
0.2.2 Geometry
The examples/Geometry subdirectory contains the program examples for the second chapter of the
tutorial. Each of these programs demonstrates something about specifying geometry for visual objects.
examples/Geometry/Axis.java
Axis.java defines a visual object class using an IndexedLineArray object used to visualize the axis.
This code of this program does not appear in the text of the tutorial, it is intended as a class available for
your use. The program AxisClassDemoApp.java uses this Axis class (see below).
examples/Geometry/AxisApp.java
This program displays the axis to demonstrate using LineArray object.
Getting Started with the Java 3D API A. Summary of Example Programs
The Java 3D Tutorial 0-9
examples/Geometry/AxisClassDemoApp.java
A ColorCube orbits around the origin in this program. The code of
this program does not appear in the text of the tutorial. It simply
demonstrates a use of the Axis.java class (see above).
examples/Geometry/ColorConstants.java
This code is an example of a class that defines a number of color
constants. The application spins the yo-yo about the y-axis to
show the geometry.
examples/Geometry/ColorYoyoApp.java
This program displays a yo-yo using four TriangleFanArray
geometry objects with colors. The application spins the yo-yo
about the y-axis to show the geometry.
examples/Geometry/ConeYoyoApp.java
This program displays a yo-yo created with two Cone objects. A
default Appearance object is used. The application spins the yo-yo
about the y-axis to show the geometry.
examples/Geometry/TwistStrip.java
This program displays a twisted strip as an example of using the
TriangleStripArray. The twist strip program also demonstrates
culling.
examples/Geometry/YoyoApp.java
This program displays a yo-yo visual object created with four
TriangleFanArray objects. A default Appearance object is used.
The application spins the yo-yo about the y-axis to show the
geometry.
examples/Geometry/YoyoLineApp.java
This program displays the TriangleFanArray object with the
Appearance set to display lines only. The application spins the
yo-yo about the y-axis to show the geometry.
examples/Geometry/YoyoPointApp.java
This program displays the TriangleFanArray object with the
Appearance set to points lines only. The application spins the
yo-yo about the y-axis to show the geometry.
Getting Started with the Java 3D API A. Summary of Example Programs
The Java 3D Tutorial 0-10
0.2.3 EasyContent
examples/easyContent/BackgroundApp.java
This application demonstrates defining geometry for the background of a virtual world. The scene is of a
grid of lines to represent the ground, a PointArray for stars, and a LineArray for a constellation. The stars
and constellation are in the background. The viewer can move around in the scene and experience the
relative motion between the ground and the stars in the background.
The interaction (motion) is provided through the KeyNavigator class (documented in Chapter 4) and a
BoundingLeaf application bounds, which provides interaction in the virtual world without bounds. The
BoundingLeaf is added to the view branch graph in this application.
examples/easyContent/GeomInfoApp.java
This application demonstrates the use of the GeometryInfo class to create Java 3D geometry specified by
arbitrary polygons. This application creates the surface of a car using polygons. The Triangulator,
Stripifier, and NormalGenerator classes are used to convert the polygons into triangle strips with normals
so the specified geometry can be shaded. A wire frame view of the geometry can be viewed by providing
any command line argument when invoking the program. For example: java GeomInfoApp -lines
will show the wire frame instead of the shaded surfaces.
examples/easyContent/Text2Dapp.java
A simple example of using the Text2D object to add text to a Java 3D virtual world. The Text2D object
rotates in the virtual world.
examples/easyContent/Text3Dapp.java
A simple example of using the Text3D object to add text to a Java 3D virtual world. The Text3D object
rotates in the virtual world.
0.2.4 Interaction
The programs collected in the examples/Interaction subdirectory correspond to the topics presented in
Chapter 4. Creating and using behaviors to provide user interaction is the subject of the chapter.
examples/Interaction/DoorApp.java
This program demonstrates using the postId() method and WakeupOnBehaviorPost WakeupCriterion
objects to coordinate behavior objects. In this program two behavior classes are defined: OpenBehavior
and CloseBehavior. Then one instance of each behavior class are used to open and close a door. Actually,
a ColorCube is used as a stand-in for the door.
examples/Interaction/KeyNavigatorApp.java
This program demonstrates using a KeyNavigatorBehavior object to provide keyboard based viewer
navigation in the virtual world. The user is able to press keys to move forward, back, left, right, up and
down as well as rotate left, right, up and down.
Getting Started with the Java 3D API A. Summary of Example Programs
The Java 3D Tutorial 0-11
examples/Interaction/MouseBehaviorApp.java
This program shows how all three MouseBehavior classes (MouseRotate, MouseTranslate, and
MouseZoom) can be combined to provide a variety of interactions using the mouse. MouseRotateApp is a
simpler version of this program as it only uses the MouseRotate class.
examples/Interaction/MouseNavigatorApp.java
This program demonstrates how the MouseBehavior classes (MouseRotate, MouseTranslate, and
MouseZoom) can be used to provide mouse-based viewer navigation in the virtual world. The user is able
to move and rotate in response to combinations of mouse button presses and movements.
examples/Interaction/MousePickApp.java
This program demonstrates the picking interaction possible using the PickRotateBehavior class. The user
is able to pick a visual object and rotate it with mouse movements. This is in contrast to
MouseRotate2App where the program demonstrates that without picking, the user is constrained as to
which objects are available for interaction.
examples/Interaction/MouseRotateApp.java
A demonstration of using the MouseRotate class to provide interaction with specific visual objects. The
user is able to rotate the programmer-specified visual object with the mouse. MouseBehaviorApp is a more
complex version of this program providing translation and zoom interactive capabilities in addition to
rotation. MouseRotate2App demonstrates a limitation of this class.
examples/Interaction/MouseRotate2App.java
A demonstration of using the MouseRotate class to provide interaction with specific visual objects. Two
cubes rotate in response to user actions. There is no way to interact with just one of the cubes in this
program. This program intentionally demonstrates the limitation of interaction with this class.
MouseRotateApp is a one cube version of this program.
examples/Interaction/PickCallbackApp.java
This is MousePickApp modified to include a callback from the picking behavior. The user is able to pick a
visual object and rotate it with mouse movements. The simple callback behavior displays a message to the
console. This is the answer to question 6 in the self test section.
examples/Interaction/SimpleBehaviorApp.java
A simple behavior class is created and then used in this program. The simple behavior changes a
TransformGroup object in response to key presses. The effect is to rotate a visual object using key strokes.
The program demonstrates behavior usage basics and how to write custom behavior classes.
0.2.5 Animation
examples/Animation/AlphaApp.java
This program illustrates the smoothing possible for the waveform produced by an Alpha object. Three
visual objects are translated using three PositionInterpolators and three Alpha objects. Only the
IncreasingAlphaRampDuration parameter of the Alpha objects differ among the three car-interpolator-
alpha sets. Refer to Section 5.2 and Figure 5-7 for more information.
Getting Started with the Java 3D API A. Summary of Example Programs
The Java 3D Tutorial 0-12
examples/Animation/BillboardApp.java
This program illustrates the billboard behavior provided by Billboard Class objects. A Billboard object
orients a visual object such that it always faces the viewer. The user of this program is free to navigate the
virtual world using the arrow keys. Refer to Section 5.3 for more information on applications and API of
the Billboard Class.
examples/Animation/ClockApp.java
This program uses one Alpha object and one RotationInterpolator to rotate an analog clock face once per
minute. The clock face, defined in Clock.java, is constructed from one Alpha object and two
RotationInterplotors. The main program, in ClockApp.java, is a simple example of using a
RotationInterpolator. The construction of the clock is somewhat more complex.
examples/Animation/InterpolatorApp.java
This program illustrates six different interpolator classes in one scene to illustrate the variety of
interpolator classes available.
examples/Animation/LODApp.java
This program uses a DistanceLOD object to represent a visual object as one of several different geometric
representations of varying levels of detail. The DistanceLOD object picks one of the geometric
representations based on the distance between the visual object and the viewer.
examples/Animation/MorphApp.java
In this program, a custom behavior classes animates a stick figure walking based on four GeometryArray
object key frames. Of course, to truly appreciate the animations, you have to run the program.
examples/Animation/Morph3App.java
In this program, three other behavior classes create animations based on some, or all, of the
GeometryArray objects of MorphApp. They are called (left to right in the figure) "In Place", "Tango", and
"Broken". Not all of the animations are good. Of course, to truly appreciate the animations, you have to
run the program.
0.2.6 Light
examples/light/LightsNPlanes.java
This program renders a scene where three planes are lit by three different lights. One light is directional,
one is a point light, and one is a spot light. See Figure 6-16.
examples/light/LitPlane.java
This program is a basic example of using lights. It renders a scene with a plane and a sphere. See Figure
6-2.
examples/light/LitSphere.java
This program is a basic example of using lights. It renders a scene with a single sphere. See Figure 6-15,
among others.
examples/light/LitTwist.java
This program demonstrates the lighting of a two sided object (setBackFaceNormalsFlip()).See
Figure 6-21.
Getting Started with the Java 3D API A. Summary of Example Programs
The Java 3D Tutorial 0-13
examples/light/LightScope.java
This program demonstrates the use of scoping to limit the influence of light sources. See Figure 6-25.
examples/light/LocalEyeApp.java
This program illustrates the difference between local eye lighting and infinite eye lighting. See Figure 6-29.
examples/light/ShadowApp.java
This program demonstates SimpleShadow class. SimpleShadow creates shadow polygons for simple visual
objects in certain scenes. See Figure 6-28.
examples/light/ShininessApp.java
This program renders a static scene of nine spheres with different material properties. The only difference
among the material properties of the spheres is the shininess value. See Figure 6-20.
examples/light/SpotLightApp.java
This program illustrates the difference various values for the spot light parameters make in rendering. See
Figure 6-18.
0.2.7 Texture
examples/texture/BoundaryColorApp
This program loads a single texture image into four Texture2D objects for use with four visual objects.
Each of the four textures are configured with a Boundary Color and different Boundary Mode settings.
The resulting image illustrates the interaction between the Boundary Mode setting in the presence of a
Boundary Color.
examples/texture/BoundaryModeApp
This program loads a single texture image into four Texture2D objects for use with four visual objects.
Each of the four textures are configured with a different set of Boundary Mode settings (CLAMP or
WRAP). The resulting image illustrates the possible combinations of Boundary Mode setting for a 2D
texture.
examples/texture/MIPmapApp
This program loads a single texture image into a Texture2D object with the MIPmap Mode set to
MULTI_LEVEL. The images for each level (other than the base level) are created at runtime from the
loaded base image by the TextureLoader utility. Compare this program to MIPmapApp2.
examples/texture/MIPmapApp2
This program loads multiple texture images into a Texture2D object with the MIPmap Mode set to
MULTI_LEVEL. Each image is loaded by the TextureLoader utility. Compare this program to
MIPmapApp.
examples/texture/MIPmapDemo
This program loads multiple texture images into a Texture2D object with the MIPmap Mode set to
MULTI_LEVEL. Each image is loaded by the TextureLoader utility. The texture images used distinguish
this application from the typical MIPmap application. The textures are solid color and alternate between
red and green on each level. The resulting image shows how textures from a variety of levels can be used
for a single visual object.
Getting Started with the Java 3D API A. Summary of Example Programs
The Java 3D Tutorial 0-14
examples/texture/SimpleTextureApp
This is a very simple example using a texture for a single plane. This application is the result of the
straightforward application of the simple texture recipe presented in Section 7.2. See also the
TexturedPlaneApp.
examples/texture/SimpleTextureSpinApp
This application takes the SimpleTextureApp one step further and animates the textured plane. It
illustrates the single sided nature of textured objects.
examples/texture/Text2DTextureApp
A Text2D object (see chapter 3)creates its image using a Texture2D object. This program applies the
texture created by texture Text2D object to another object.
examples/texture/TextureCoordApp
Each of the four planes in this application is textured with the same texture, but each plane is different.
This program demonstrates some of the alternate orientations a texture may have when applied to a plane.
More texture orientations are demonstrated in TextureRequestApp.
examples/texture/TextureCoordGenApp
In this program a TexCoordGeneration object is used to create the texture coordinates at runtime. This
allows the programmer to ignore this detail. It is especially useful for adding textures to visual objects
loaded from files. Also, the TexCoordGeneration object is capable of creating varying texture coordinates
(in EYE_LINEAR mode) which would hardly be possible otherwise.
examples/texture/TexturedLineApp
This program uses a 1D texture to texture the lines (not the filled polygons) of some geometry. It is an
example of a less common application of textures.
examples/texture/TexturedPlaneApp
This application is a demonstration of the TexturedPlane class, which is separately compiled. The
difficulty in having a separately compiled class that loads textures lies in using a TextureLoader object
outside of an applet. This simple example shows one way to solve the problem.
examples/texture/TexturedPrimitiveApp
This program demonstrates the use of the texture coordinates created by a primitive geometric object (see
Chapter 2 for a discussion of geometric primitives).
examples/texture/TexturedSceneApp
This application generates the image on the cover of this chapter.
examples/texture/TextureRequestApp
This program shows some of the possible renderings for a plane using the same texture. The scene is of
four planes that differ only in the assignment of texture coordinate values. One plane is solid blue when
rendered, the others are striped, but none look like the others nor the texture image. The texture
assignments made in this program are examples of possible mistakes while all are legitimate applications.
This is the illustration of the phrase "In texturing, you get what you ask for." Other texture orientations are
illustrated in TextureCoordApp.
Getting Started with the Java 3D API B. Reference Material
The Java 3D Tutorial 0-15
0.3 (Appendix B) Reference Material
0.3.1 Books
Henry Sowizral, Kevin Rushforth, and Michael Deering, The Java 3D API Specification, Addison-
Wesley, Reading, Mass., December 1997. ISBN 0-201-32576-4
This book describes version 1.0 of the Java 3D API. There are some differences between this specification
and the current release of the product. It is comprehensive in coverage, but not intended as a programmers
guide.
It is also available online at http://java.sun.com/products/java-media/3D
It is also available in Japanese: translated by Yukio Andoh, Rika Takeuchi; ISBN 4-7561-3017-8
Ken Arnold and James Gosling, The Java Programming Language, Addison-Wesley, Reading, Mass.
The Java reference.
David M. Geary, graphic JAVA Mastering the AWT, Sunsoft Press, 1997
Complete coverage of the AWT.
Foley, vanDam, Feiner, and Hughes, Computer Graphics, Addison-Wesley
This book is widely considered the bible of computer graphics. Comprehensive coverage of general
computer graphics concepts including representation of points, lines, surfaces, and transformations. Other
topics include projection, texturing, z-buffer, and many, many others.
OpenGL ARB, OpenGL Programming Guide, Addison-Wesley
While not directly related, this book provides a good foundation in graphics programming via the OpenGL
API. Java 3D resembles OpenGL in many ways and some implementations of Java 3D are built on an
OpenGL implementation.
0.3.2 The Java 3D API can be downloaded from the Java 3D Home Page:
http://java.sun.com/products/java-media/3D/
Follow the "Java 3D Implementation" link to the download.html page. Also from this page, you can
download documentation for Java 3D API classes.
0.3.3 Sun Java Web Pages
For additional information, refer to these Sun Microsystems pages on the World Wide Web:
http://java.sun.com/products/java-media/3D
The Java 3D marketing homepage, this links to many related pages.
http://java.sun.com/
The Java Software web site, with the latest information on Java technology, product information, news, and
features.
Getting Started with the Java 3D API B. Reference Material
The Java 3D Tutorial 0-16
http://java.sun.com/products/jdk/1.2/
JDK 1.2 Product and Download Page
http://java.sun.com/docs
Java Platform Documentation provides access to white papers, the Java Tutorial and other documents.
http://developer.java.sun.com/
The Java Developer Connection web site. (Free registration required.) Additional technical information,
news, and features; user forums; support information, and much more.
http://java.sun.com/products/
Java Technology Products & API
http://www.sun.com/solaris/java/
Java Development Kit for Solaris - Production Release
0.3.4 Other Web Pages
For additional information, refer to the the Java 3D web page for links to related resources.
Getting Started with the Java 3D API C. Solutions to Selected Questions
The Java 3D Tutorial 0-17
0.4 (Appendix C) Solutions To Selected Self Test Questions
Each chapter concludes with a Self Test section containing questions designed to test and increase the
readers understanding of the material in that chapter. This section presents answers to some of those
questions.
Note for questions relating to programming. As in any programming task, there are many answers possible
to the programming questions. This section only provides one possible programming solution.
0.4.1 Answers to Questions in Chapter 1
1. In the HelloJava3Db program, which combines two rotations in one TransformGroup, what would be
the difference if you reverse the order of the multiplication in the specification of the rotation? Alter
the program to see if your answer is correct. There are only two lines of code to change to make this
change.
Answer:
In general, the final orientation of an object depends on the
order of rotations applied. There are cases when the order
of rotations will not change the final orientation.
To effect the change in the order of application of the
rotations make the following two edits to
HelloJava3Db.java. Then compile and run the changed
program. Note, if you change the name of the file, you
also need to change the name of the high level class in the
file. For example, if you change the file to
HelloJava3Dbalt.java, then class HelloJava3Db must be
changed to HelloJava3Dbalt, along with the name of the
constructor and the call to the constructor. Of course, the
comments should change to reflect programming changes.
Change:
rotate.mul(tempRotate);
to:
tempRotate.mul(rotate);
Change:
TransformGroup objRotate = new TransformGroup(rotate);
to:
TransformGroup objRotate = new TransformGroup(tempRotate);
After making these changes, compiling, and running the program, the above image at the is produced. If
you compare this image to Figure 1-12 in Chapter 1, you can see the difference changing the order of
rotations made in this program.
Getting Started with the Java 3D API C. Solutions to Selected Questions
The Java 3D Tutorial 0-18
2. In the HelloJava3Dd program, what would be the difference if you reverse the order of the Transform
Nodes above the ColorCube in the content branch graph? Alter the program to see if your answer is
correct.
Answer:
As in the previous program, the change in order does make a difference. Also as in the first question, only
two lines of code need be edited to test the results of the change the question asks about.
3. In search of performance improvements, a programmer might want to make the scene graph smaller.
Can you combine the rotation and the spin target transform of HelloJava3Dd into one TransformGroup
object?
Answer:
It can be done; however, it is not worth the effort. Unless a change in the scene graph results in fewer
Shape3D objects, it does not make sense to make the program harder to write, read, and maintain.
4. Translate the ColorCube 1 unit in the Y dimension and rotate the cube. You can use HelloJava3Db as
a starting point. The code that follows the question shows the specification of a translation
transformation. Try the transformation in the opposite order. Do you expect to see a difference in the
results? If so, why? If not, why not? Try it and compare your expectations to the actual results.
Transform3D translate = new Transform3D();
Vector3f vector = new Vector3f(0.0f, 1.0f, 0.0f);
translate.setTranslation(vector);
Answer:
The order of transformations does make a difference.
5. In HelloJava3Dc, the bounding sphere has a radius of 1 meter. Is this value larger or smaller than it
needs to be? What is the smallest value that would guarantees the cube be rotating if it is in view?
Experiment with the program to verify your answers. The following line of code can be used to specify
a bounding sphere. In this line, the center is specified using the Point3D object followed by the radius.
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
Answer:
The BoundingSphere only needs a radius of 0.8 (0.4 * 2.0). The center should be (0, 0, 0). The location of
the BoundingSphere will be transformed by any TransformGroup objects above it in its scene graph path.
Getting Started with the Java 3D API C. Solutions to Selected Questions
The Java 3D Tutorial 0-19
6. The example programs give sufficient information for assembling a virtual universe with multiple color
cubes. How do you construct such a scene graph? In what part of the code would this be
accomplished?
Answer:
There are many ways to add a new visible object to a virtual universe. Some possibilities include:
Add a ColorCube object as a child of the existing BranchGroup.
Add a ColorCube object as a child of a new BranchGroup and adding this BranchGroup to the Locale
of the SimpleUniverse.
Add a ColorCube object as a child of the existing TransformGroup. Note that since two ColorCube
objects will coincide, only one will be visible.
Add a ColorCube object as a child of a new TransformGroup object and making the new
TransformGroup a child of the Locale of the SimpleUniverse.
Combinations of the above possibilities.
A ColorCube object can not be added as the child of the Locale object.
0.4.2 Answers to Questions in Chapter 2
1. Try your hand at creating a new yo-yo using two cylinders instead of two cones. Using
ConeYoyoApp.java as a starting point, what changes are needed?
Answer:
All that is needed is to replace the Cone objects with Cylinder objects.
2. A two-cylinder yo-yo can be created with two quad-strip objects and four triangle-fan objects. Another
way is to reuse one quad-strip and one triangle fan. What objects would form this yo-yo visual object?
The same approach can be used to create the cone yo-yo. What object would form this yo-yo visual
object?
Answer:
In each of the solutions, the visual object can be defined by one Group with two TransformGroup objects,
each with a Shape3D child. Each of the Shape3D objects refers to the same Geometry NodeComponent.
Getting Started with the Java 3D API C. Solutions to Selected Questions
The Java 3D Tutorial 0-20
3. The default culling mode is used in YoyoLineApp.java and YoyoPointApp.java. Change either, or
both, of these programs to cull nothing, then compile and run the modified program. What difference
do you see?
Answer:
With the default, the lines (or points) are culled from back faces. Turning culling off allows all lines
(points) to be rendered in all orientations. If you haven't already, try culling front faces.
0.4.3 Answers to Questions in Chapter 3
1. Using the GeomInfoApp.java example program as a starting point, try the various settings for ear
clipping (see the Triangulator reference block in Chapter 3). Using the wire frame view in the
program, you can see the effect of the triangulation. For more experience, change the specification of
the polygons to use three polygons (one for each side, and one for the roof, hood, trunk lid and other
surfaces. How does the Triangulator do with this surface?
Answer:
The code for the single polygon description of the hood, roof, trunk, and front and rear glass is embedded
in the application code. See the source code for more details. However, there are three other lines of code
that must be changed to use this alternative polygon.
Unfortunately, the Triangulator does not triangulate this polygon correctly. You might try breaking the one
large polygon into smaller ones to see what works. The lesson here is you still have to give some thought to
how surfaces are described, even when using GeometryInfo.
2. The code to make the Text2D object visible from both sides is included in Text2DApp.java. You
can uncomment the code, recompile and run it. Other experiments with this program include using the
texture from the Text2D object on other visual objects. For example, try adding a geometric primitive
and apply the texture to that object. Of course, you may want to wait until you read Chapter 7 for this
exercise.
Answer:
The code to make the Text2D object visible from both sides is embedded in the comments of the
Text2DApp.java example program. See the source code file for more information.
3. Using Text3DApp.java as a starting point, experiment with the various alignment and path
settings. Other experiments include changing the appearance of the Text3D object.
Answer:
Just try some difference settings and observe the results.
4. Playing with the BackgroundApp.java example program, if you move far enough away from the
origin of the virtual world the background disappears. Why does this happen? If you add another
Background object to the BackgroundApp, what will the effect be?
Answer:
The application of a background is controlled by the ApplicationBounds (or ApplicationBoundingLeaf) for
the background. In the example program, the background has an ApplicationBounds sphere centered at the
origin with a radius of 10,000.
Getting Started with the Java 3D API C. Solutions to Selected Questions
The Java 3D Tutorial 0-21
If another background were added, the effect would depend on the ApplicationBounds specified for the new
background. In any case, only one background is rendered at a time for any scene. The selection of the
background depends on the ApplicationBounds and the position of the viewer in the virtual world.
0.4.4 Answers to Questions in Chapter 4
1. Write a custom behavior application that moves visual objects to the left (and right) when a the left (and
right) arrow keys are pressed. Then use the class in an application similar to SimpleBehaviorApp.java.
Of course, you can use SimpleBehaviorApp.java as a starting point for both the custom behavior class
and the application. What happens as the ColorCube object moves out of the view? How do you fix the
problem?
Answer:
When the cube moves a sufficient distance, the behavior scheduling bounds no longer coincides with the
visual object. Since the bounds object is associated with the behavior, and the behavior is not moving with
the visual object, they will eventually be separated to the point where the behavior is only active when the
cube is not visible. Conversely, the behavior will be inactive when the cube is visible. So, if you add
navigational capabilities to the program, seeing the cube will not necessarily mean you can interact with it.
There is more than one way to change the program so that the position of the cube and the scheduling
bounds of the behavior coincide. One way is to the make the behavior a child of the transform group object
that is moving the visual object. Another way involves using a BoundingLeaf object. See Chapter 3 for
more information on the BoundingLeaf class.
2. In SimpleBehaviorApp, the rotation is computed using a angle variable of type double. The angle
variable is used to set the rotation of a Transform3D object which sets the transform of the
TransformGroup. An alternative would eliminate the angle variable using only a Transform3D object
to control the angle increment. There are two variations on this approach, one would read the current
transform of the TransformGroup and then multiply, another would store the transform in a local
Transform3D object. In either case, the new rotation is found by multiplying the previous Transform3D
with the Transform3D that holds the rotation increment. What problem may occur with this alternative?
What improvement can be made to this approach?
Answer:
Successive rotations (or transformations of any type) can be implemented using successive multiplication
of transforms. The problem lies in the loss of precision through the repeated multiplications. It takes many
iterations, but eventually the error will accumulate and result in strange effects in the renderings.
3. Change the trigger condition in the SimpleBehavior class to new ElapsedFrame(0). Compile and
run the modified program. Notice the result. Change the code to remove the memory burn problem
from the class. Then recompile and run the fixed program.
Answer:
The program will trigger on each frame (and therefore is now an animation application). As a result, a new
object is created on each frame. Since objects are being created at a fairly quick rate and not being reused,
this is a case of memory burn. The rendering will pause when the garbage collector activates to clean up
memory.
4. Change the scheduling bounds for the KeyNavigatorBehavior object to something smaller (e.g., a
bounding sphere with a radius of 10), then run the application again. What happens when you move
beyond the new bounds? Convert the scheduling bounds for KeyNavigatorApp to a universal
application so that you can't get stuck at the edge of the world. See Chapter 3 for more information on
BoudingLeaf nodes.
Getting Started with the Java 3D API C. Solutions to Selected Questions
The Java 3D Tutorial 0-22
Answer:
When the viewer moves beyond the scheduling bounds, the navigation behavior becomes inactive and
therefore can no longer respond to keystrokes (or any other trigger). The viewer becomes stuck and must
exit the program.
5. Use the KeyNavigatorBehavior with a TransformGroup above a visual object in the content branch
graph. What is the effect?
Answer:
The effect is to move the visual object, not the viewer. The action is backward from the normal application
of this behavior.
6. Extend the picking behavior in the MousePickApp by providing a callback. You can start by simply
producing a text string ("picking") to the console. You can also get more ambitious and read the user
data from the target transform group or report the translation and/or rotations of the target transform
group. With the proper capabilities, you can also access the children of the TransformGroup object.
Answer:
See examples/Interaction/PickingCallbackApp.java.
0.4.5 Answers to Questions in Chapter 5
1. The InterpolatorApp example program uses six different interpolator objects. Each of the interpolator
objects refers to the same Alpha object. The result is to coordinate all the interpolators. What would be
the result if each interpolator object had its own Alpha object? How could you change the timing?
Answer:
If each interpolator used a different Alpha object the interpolators would all be synchronized anyway.
Each Alpha object is assigned the same start time when it is created. If you wanted the Alpha objects to be
out of phase, either change the start time or assign a phase delay duration.
2. If the light in InterpolatorApp is changed to Vector3f(-0.7f,-0.7f,0.0f) what happens?
Why?
Answer:
The body of the car disappears; however, the wheels are still visible and are changing colors as before.
Why do the different parts of the car render differently? If you change the background to a different color,
you will see the body of the car is still there but it is solid white. This is the result of complete specular
reflection from the body of the car. The combination of the direction of the light and the normals of the car
body reflect the light source as a mirror does. This is truly a problem for chapter six, but is a potential
head-scratcher for readers of chapter five.
3. Why are there fewer distances than visual objects specified for a DistanceLOD object?
Answer:
By design the threshold to begin to use the first child of the target switch object(s) is zero. This threshold is
not specified by the user. The threshold distances specified by the user are the minimum distances at which
the remaining children are to be used. Therefore, there are one fewer distances specified than there are
children.
4. In MorphApp there are four frames of which two look like duplicates of the other two. Why are four
frames necessary? Asked another way, what would the animation look like with just two frames?
Answer:
Since Morph animates between frames based on vertex ordering, with just two frames the animation would
Getting Started with the Java 3D API C. Solutions to Selected Questions
The Java 3D Tutorial 0-23
just move back and forth between the two frames. Since the 'feet' of the animation never appear in the
same place in one key frame, four frames are necessary. The difference between the frames that appear the
same is the vertex ordering. It would be possible to animate walking with two frames if in one of the
frames one foot is behind the other (from the viewer's point of view). Of course, this would only work with
2D models.
5. In using a morph object, the same number of vertices are used. How can you accommodate geometric
models of differing numbers of vertices?
Answer:
In the geometry with the smaller number of vertices the vertex count must be increased to match that of the
larger geometry. The new vertices can be redundant or internal to a surface.
0.4.6 Answers to Questions in Chapter 6
1. Add a green DirectionalLight pointing up to the LitSphereApp to illustrate additive color mixing
with all three primary colors. Dont forget to add the light to the scene graph and set the influencing
bounds for the new light source object. Which two primary colors make yellow?
Answer:
In the positive color system, green and red combine (add) to yield yellow. This is not the result of mixing
green and red paint, but green and red light. Mixing red and green paint will likely result in some shade of
brown (depending on the characteristics of the paint).
2. To learn more about the interaction between material colors and light colors, create a scene with red,
green, and blue visual objects. Light the objects with one single color light. What did you see? You
may use LitSpereApp.java or MaterialApp.java as a starting point.
Answer:
In monochromatic light (pure red, green, or blue) only visual objects with material color with some of the
color of the light are visible. By contrast, in monochromatic light, visual objects with material color absent
of the color of the light are invisible.
The results you get from your program will depend on your program. If you only set the diffuse color of
the visual objects, then the specular highlight will appear in the color of the light (which by default is
white).
3. Using LightScopeApp.java as a starting point (see Section 6.6.2), change the program to create the
shadow of the lit box through the use of scoping only.
Answer:
An additional group node is necessary. It is placed between the litBoxTG and the litBox object. They the
scope references that new group node. You also need to change the material diffuse color to white.
The image rendered from the scene is different since the shadow is lit by the other lights in the scene.
0.4.7 Answers to Questions in Chapter 7
1. What happens if a texture coordinate assignment is not made for a vertex in some geometry? Is there
an exception? A warning? Does it render? If it renders, what is the result?
Answer:
In the event a texture coordinate assignment is not made for one or more vertices, the texture coordinate is
the default value for texture coordinates (0,0), or (0,0,0) for 3D. There is no exception or warning. The
Getting Started with the Java 3D API C. Solutions to Selected Questions
The Java 3D Tutorial 0-24
resulting render is the same as if the default value for a texture coordinate had been made for the vertex
(vertices).
2. How can a single image of a texture (not repeated) be mapped onto a visual object and have the image
surrounded by a single solid color? Assume the texture image is the typical non-solid-color image.
How could the surrounding color be assigned or modified at runtime?
Answer:
The CLAMP Boundary Mode it used to apply a single image of a texture to a visual object. One way to
have the object appear with a solid color border is to create the texture image with a single texel border
with the desired border color. In REPLACE texture mode the border color will be used everywhere beyond
the texture application. When a linear filter is used and the Boundary Mode is CLAMP, the Boundary
Color (default: black) will be used. In this case you will probably need to set the boundary color to white.
Keep in mind that the entire texture image is still subject to the size constraints.
Another way to apply a single image of a texture with a solid color border is to create the texture image
with a single texel border that is transparent. In DECAL texture mode the visual object will provide the
color beyond the texture image.
Neither of these approaches allows for a changing border color at least not easily changed. To have a
dynamic border color, or just one assigned at runtime, use the same technique as the first solution above:
Boundary Mode CLAMP, and linear texture filters. Make a one texel while border color around the
texture and apply a boundary color. If the boundary color is to change after the visual object is live, make
sure the appropriate capability is set.
3. How can multiple textures be applied to a single visual object? How can you apply different textures
to the opposite sides of the same visual object? How can you apply different textures to the lines and
the surfaces of a polygon?
Answer:
A visual object can have only one texture. So if you want to use more than one texture on what appears as
a single visual object, then it must be created of multiple visual object with the various textures.
4. How would you animate a shadow that moves across a stationary visual object as the shadow moves?
Answer:
A texture can be animated in certain limited ways (stretching, rotating, moving) by changing the texture
transform for the visual object. With the appropriate capability set such that the texture transform can be
changed at runtime, a texture that represents the shadow can be moved, made larger or smaller, or rotated
on a visual object.
5. How would you animate a shadow that moves across a visual object as the object passes through a
stationary shadow?
Answer:
The solution to question four can be used, however this would require coordination of the object's
movement with the movement of the texture. There is (at least) one other way. A TexCoordGeneration
object with EYE_LINEAR generation mode assigns texture coordinates that are stationary in the virtual
space. Using a TexCoordGeneration object configured in this way would make the texture stationary even
as the object moved through the virtual space.
Getting Started with the Java 3D API Glossary
The Java 3D Tutorial 0-25
0.5 Glossary
A
activation volume A volume associated with a ViewPlatform Node. When the activation
volume intersects application regions and scheduling regions, the objects
associated with the intersecting regions affect rendering. The affecte objects
include backgrounds, behaviors, and fog. See also ViewPlatform,
application bounds, and scheduling bounds.
active Said of a behavior object that is able to receive a wakeup stimulus and
therefore execute. A behavior object is active when it's scheduling bounds
intersects a ViewPlatform's activation volume. When a behavior is not
active, Java 3D will ignore the wakeup criteria for that behavior. See also
activation volume and behavior.
aliasing The appearance of jaggies in lines and curves. The result of sampling the a
continuous function. See also jaggies and antialiasing.
alpha In computer graphics, the term alpha normally refers to transparency. In
Java 3D alpha also refers to transparency, but may also refer to the Alpha
class, or an alpha value. This may be a source of confusion for experienced
graphics programmers. See also Alpha class, alpha value, RGBA, and
transparency.
Alpha class An Alpha class object creates a time-varying function of alpha values.
Normally, and Alpha object is used with Interpolator objects to create time-
based animations. See also alpha value, animation and interaction.
alpha value A value in the range 0.0 to 1.0, inclusive. Alpha values are used in various
capacities in Java 3D (e.g., transparency value or Interpolator behavior
objects). Time varying alpha values are produced by Alpha objects. See
also Alpha Class, behavior, and interpolator.
ambient (material) color Part of the material properties of a visual object. The ambient color of a
material and the ambient light in scene produce an ambient reflection.
ambient light A light source present in all places shining in all directions used to model the
complex inter-object reflections (repeated reflection of light from one object
to another) present in the real world. See also ambient color.
ambient reflection The light produced by an ambient light source reflected from a visual object
with material appearance attributes. The result depends on the ambient
color of the object and the color of the ambient light source. See ambient
color, ambient light, and lighting model.
ancestors (of an object) All of the objects in a scene graph that are children of a specific object and
all of the childrens ancestors. See also object, scene graph, and parent-
child relationship.
animation The automatic change of visual content (e.g., changes based on time alone).
In this tutorial, animations are driven by the passage of time, changes of the
Getting Started with the Java 3D API Glossary
The Java 3D Tutorial 0-26
view platform location, and possibly other non-user action influences.
Animation is the subject of Chapter 5. See also interaction.
antialiasing A process of smoothing the drawing of points or lines that would otherwise
appear jagged. See also jaggies, line antialiasing and point antialiasing.
API see Application Programming Interface
Appearance class Instances of Appearance define the appearance of a Shape3D object.
Appearance objects include AppearanceAttribute objects. See also
AppearanceAttributes and Shape3D.
application bounds The region for which something is applied. Backgrounds and Behaviors
have application bounds. For example, when the viewing frustum intersects
the application bounds of a particular background, that background is used
in rendering. See also bounds.
Application Programming (API) General term referring to a collection of classes (or procedures) that
Interface form the programming interface to some computer system. The Java 3D
API classes form the programmers interface to the Java 3D renderer.
Attributes classes Instances of Attributes define specific appearance attributes of a Shape3D
object. There are several Attributes classes. Appearance objects include
Attribute objects. See also Appearance class and Shape3D.
B
base level Level 0 of a texture. Base level is the only level of a texture unless the
Mipmap Mode is set to MULTI_LEVEL. Base level also refers to a single
level texture as opposed to a multiple level texture. In a multiple level
texture base level, level 0, is the largest texture image. See also texture
mapping and multiple levels of texture.
billboard Automatic orientation of a polygon in an orthogonal orientation to the
viewer such that only the front face of the polygon is viewed. Typically the
polygon is textured with an image.
Behavior class A javax.media.j3d class used to specify how some characteristic, such as
location, orientaion, or size, changes at runtime. Behavior classes are used
in creating animations as well as interactive programs. See also behavior,
Interpolator, and Alpha class.
behavior The changing of some characteristic, such as location, orientation, size,
color, or a combination of these, of a visual object at run time. A behavior
is either an animation or an interaction. See also Behavior class.
bounding volume A volume that defines the limits for which something is defined. Bounds are
used with behaviors, lights, sounds, and other features of Java 3D. Bounds
are defined in a program with the Bounds class. When the See also Bounds
class and scheduling region.
Bounds class An abstract class to specify a bounding volume for which something is
defined. Bounds are used with behaviors, backgrounds, sounds, and other
features of Java 3D. Bounds can be specified with a BoundingBox,
BoundingSphere or a BoundingPolytope. See also bounding volume,
polytope, and scheduling region.
Getting Started with the Java 3D API Glossary
The Java 3D Tutorial 0-27
bounds See bounding volume and Bounds class.
BoundingBox class Instances of BoundingBox define bounds as a axis-aligned box. See also
bounding volume.
BoundingSphere class Instances of BoundingSphere define bounds as a sphere. See also bounding
volume.
branch graph That portion of the scene graph rooted in a BranchGroup object. See also:
BranchGroup, scene graph, content branch graph, and view branch graph.
BranchGroup class Instances of BranchGroup are the root of individual scene graph branches,
called branch graphs. A BranchGroup may have many children that are
Group and/or Leaf objects. A BranchGroup is the only object that may be
inserted into a Locale object. See also scene graph, branch graph, and
Locale.
C
capabilities In the Java 3D sense, access to the parameters of a live object are controlled
with capabilities. For example, a transform of a live TransformGroup can
not be changed unless the capability to do so was set for that instance of
TransformGroup before it was made live. See also live and
TransformGroup.
CLAMP One of the Boundary Modes available in texture mapping. Clamps texture
coordinates to be in the range [0, 1]. See also texture mapping.
class The specification of a set of values and a set of operations. A class is
analogous to a type in a procedural language such as C. See also object.
Color* classes A set of classes used to represent a single color value. The classes are
Color3b, Color3f, Color4b, and Color4f.
Color3* classes A set of classes used to represent a single RGB color value. The classes are
Color3b and Color3f. See also Color* and RGB.
Color4* classes A set of classes used to represent a single RGBA color value. The classes
are Color4b and Color4f. See also Color* and RGBA.
compile In the Java 3D sense, compile() is a method of BranchGroup to allow
Java 3D to make run-time performance improvements in the branch graph
rooted on the BranchGroup. See also BranchGroup and branch graph.
concentration A parameter of spot light objects that determines the spread of light from the
light source. See also spot light.
content The visual (including shape and lights) and audio objects of a virtual
universe. See also visual object.
content branch graph The portion of the scene graph that contains the visual objects. See also
content and visual object.
convenience class A class that extends a core class for the purpose of making a core class (or
classes) easier to use. Convenience classes are found in the com.sun.j3d.*
packages.
Getting Started with the Java 3D API Glossary
The Java 3D Tutorial 0-28
crease angle The threshold angle between the surfaces of adjacent triangles in a surface
for which it is taken to be a discontinuous crease. When a crease is detected
by the NormalGenerator it produces multiple normals for vertices.
cull To remove something not valuable or not needed. See also cull face.
cull face The face that is not to be rendered. A cull face is specified to avoid
rendering a face that is not needed, for example, the interior face of an
enclosed surface. Cull faces are specified as either front face or back face.
A cull face is specified to improve rendering performance. See also front
face.
D
DAG See Directed Acyclic Graph
deactivation When a behavior's scheduling region and the ViewPlatform's activation
volume no longer intersect, the behavior is deactivated. Since a behavior
can only be triggered when active, a deactivated behavior object will not do
anything. See also active and behavior.
diffuse reflection The most common reflection of light from visual objects present in the real
world. The diffuse color is the color of an object in typical lighting
conditions. See also lighting model.
directed acyclic graph A data structure composed of elements and directed arcs in which no cycles
are formed. In the Java 3D world, the elements of the DAG are Group and
Leaf objects, and the arcs are the parent/child relationships between Groups
and Leaf objects. In forming the structure without cycles means no element
can be its own parent.
E
emissive (material) color A color specified to make an object self illuminating. The object is not a
light source and does not lit other object, but is visible in the absence of light
sources. See also material properties.
examples.jar The archive of example programs published with this tutorial. See also jar.
exception An expected runtime problem that halts execution when detected. The Java
3D API defines several exceptions.
execution culling Since computational resources are shared for rendering and behavior
execution; some (or all) computational resources are not available for
rendering while behaviors are executed. This could degrade rendering
performance when executing behavior objects. Therefore, Java 3D ignores
behaviors when they are not active to conserve execution resources. This is
termed execution culling since execution of deactivated behavior objects is
culled. See also active and behavior.
eye vector The vector between a vertex (to be shaded) and the viewing position. This
vector is used in calculating the specular reflection of an object. See also
specular reflection, local eye, and infinite eye.
Getting Started with the Java 3D API Glossary
The Java 3D Tutorial 0-29
F
flat shading Shading an object with the colors of each vector without interpolation. See
also shading model.
font The collection of glyphs for the alphabet. A typeface at a specific point size
and attributes (i.e., italics or bold). See also glyph and typeface.
front face The face of a polygon for which the vertices are in counter-clockwise order.
An easy way to remember is to apply the right-hand rule. See also right-
hand rule and cull face.
frustum see view frustum
G
get* or get-method A method of a class that retrieves a field or value from an object. See also
set*
Geometry classes The abstract class that is the super class for all geometric primitive classes
such as GeometryArray, and Text3D.
glyph The image of a character in a font. See also font and typeface.
Gouraud shading Smooth shading of an object through trilinear interpolation of color values
at the object's vertices. See also flat shading, trilinear interpolation.
Group class Group is an abstract class. Instances of subclasses Group are used in
creating scene graphs. A Group is a scene graph object whose primary
function is to be the parent of other scene graph objects (Leaf objects and
other Group objects. See also BranchGroup and TransformGroup.
H
half-space The space on one side of a plane. A plane divides all of space in two halves,
one half on each side of the plane. See also plane.
I
image plate The imaginary rectangle in the virtual universe to which the scene is
projected. See Figure 1-9 for an illustration. See also view frustum.
image observer An object that implements the image observer interface which allows it to
monitor the loading of images from a file or URL.
infinite eye (lighting) Rendering an scene as though it were viewed from a position at infinity.
The actual effect is to have a constant eye vector (0, 0, 1). This reduces
rendering time, but may look 'funny' due to the placement of specular
reflections. Infinite eye lighting is the default. See also lighting model,
specular reflection, eye vector, and local eye (lighting).
influence (of a light) The region (volume) for which the bounding volume of a visual object must
intersect for the visual object to be lit by the light source. See also bounds.
influencing bounds (of a light) See influence (of a light).
instance (of a class) An instance of a class is a specific, individual object constructed of the
named class.
Getting Started with the Java 3D API Glossary
The Java 3D Tutorial 0-30
intensity A single value that represents the perceived brightness of a light source.
Also used as a setting for a texture image that has a single value for each
texel which is taken as the value for R, G, B, and A.
interaction Changing the state of a virtual world in response to user action. This is in
contrast to animation which is defined as a change in the state of the virtual
world not directly caused by user action. Interaction is the subject of
Chapter 4. See also animation.
interface Like an abstract class, an interface defines methods to be implemented by
other classes. No constructor is defined in an interface and all of the
methods defined in an interface are abstract.
interpolator Refers to one of several classes subclassed from the Interpolator class, or an
object of one of these classes. Interpolator objects provide animation in the
Java 3D virtual world by varying some parameter(s) of a target scene graph
object. The changes made by the interpolator are determined by the
parameters of the interpolator and the Alpha object driving the interpolator.
See also Alpha Class, behavior, and target object.
interpolation The computation of a value, or set of values, based on the value of a single
integer. Sometimes the derived value is interpolated between two values, or
two sets of values; other times, the derived value is the result of a formula.
Specifically, there are a set of interpolator classes useful for animation.
See Section 4.1 and Chapter 5 for more details.
J
Java 2D An API for 2D graphics.
jaggies The technical term for the roughness that may appear on points, lines, or
polygons when rendered. The roughness appears when the individual pixels
used stand out. See also antialiasing.
jar 1. An archive file format useful for distributing a collection of files.
2. The utility that creates and reads such archive files (Java ARchive).
K
K Computing The training and consulting company that developed this tutorial document.
See also http://www.kcomputing.com
key frame A term used in traditional and computer animation for a frame of the
animation on which others are based. The process of creating frames in
between the key frames is called "in-betweening". Animations made from
key frames and in-betweening are called key frame animations. A Morph
object can be used to do key frame animations in Java 3D.
L
level of detail (LOD) Level of detail (LOD) refers to an application specific behavior that changes
the representation of a visual object based on its distance (normally) to the
viewer. When the LOD object is close to the viewer, more detailed
representations are used. Less detailed representations are used with more
distance. The goal is to reduce the rendering computation without degrading
rendered imagery. See Section 4.1 and Chapter 5 for more details.
Getting Started with the Java 3D API Glossary
The Java 3D Tutorial 0-31
light vector The vector between a light source and the vertex being shaded. See also
lighting model.
lighting model The calculation of the color (shade) of a specific vertex of a visual object as
the result of influencing light sources and the material properties of the
visual object. The shade is the result of ambient, diffuse, and specular
reflections as well as the emissive color of the material. See also ambient
reflection, diffuse reflection, specular reflection, and material properties.
line antialiasing An appearance attribute that, when enabled, causes the renderer to apply
antialiasing to lines as they are rendered. See also antialiasing and render.
live The term live refers to the state of a SceneGraphObject being associated
with a rendering engine. In other words, a live object is a member of a
branch graph associated with a Locale which is a member of a
VirtualUniverse that has a View attached (through a Locale object) and,
therefore, has the potential to be rendered. Live objects have restricted
capabilities. See also render, SceneGraphObject, branch graph, Locale
class, VirtualUniverse class, scene graph, and capabilities.
loader A Java 3D utility class that creates scene graph elements from a file.
Loaders exist for many common 3D file formats.
local eye (lighting) Rendering an scene as though it were viewed from the local eye position - as
opposed to the default infinite eye. This increases rendering time. Infinite
eye lighting is the default. See also lighting model, specular reflection, eye
vector, and infinite eye (lighting).
Locale class Instances of Locale provide landmarks in the virtual universe. The position
of all visual objects is relative to some Locale object. Locale objects are the
only object VirtualUniverse objects reference. BranchGroup objects are the
only children of a Locale object. See also BranchGroup, VirtualUniverse
class, visual object, and branch graph.
luminance A single value that represents the perceived brightness for a surface. Also
used as a setting for a texture image that has a two values for each texel
where one value is taken as the value for R, G and B and the other value is
used for alpha.
M
magnification filter A filter used in texture mapping when the pixel size is larger than the texel
size. See also texture mapping and texel.
material properties The specification of the ambient, diffuse, specular, and emissive colors, and
concentration of a material used in calculating the shade of an object. The
first three colors are used in calculating the appropriate reflection. See also
ambient reflection, diffuse reflection, specular reflection, lighting model,
and shade.
memory burn The rate of memory allocation and garbage collection as an application
runs. This is typically due to unnecessarily creating and destroying objects.
Memory burn can adversely affect rendering performance in some runtime
environments. Avoid memory burn in behaviors.
Getting Started with the Java 3D API Glossary
The Java 3D Tutorial 0-32
minification filter A filter used in texture mapping when the pixel size is smaller than the texel
size. See also texture mapping and texel.
MIP Map MIP (multum in parvo Latin for many things in a small place) Map 1.
Refers to a specific storage technique for storing a series of images for multi
level texturing, where each successive image is one quarter the size of the
next ( the size in each dimension) until the size of the smallest image is 1
texel by 1 texel [See Williams, SIGGRAPH 1983].
2. The common use of the term means "multi level texturing". See Chapter
7. See also texture mapping, multiple levels of texture, and texel.
multi level texturing See multiple levels of texture.
multiple levels of texture Having a series of texture images at various resolutions available so that the
rendering system can select the texture map of a size that is the closest
match to the visual object being rendered. See Chapter 7. See also texture
mapping and MIPmap.
N
normal A vector that defines the surface orientation. In Java 3D normals are
associated with coordinate points in geometry. See also Geometry.
normal vector See normal.
O
object An instantiation of a class. See also class and visual object.
object of change The scene graph object that is changed by a behavior and through which the
behavior affects the virtual world. For example, a TransformGroup object
is often the object of change for interactive behaviors. See Section 4.2 for
more information.
P
pick To select an object with the mouse. See also picking.
picking To select a visual object for interaction with the mouse. Picking is
implemented in Java 3D through behaviors. See Chapter 4 for more
information on Behaviors, Picking, and example programs utilizing picking
classes. See also behavior.
pick ray A pick ray is a ray whose end point is the mouse location and direction is
parallel to the projection (parallel with projectors). In many picking
applications, the pick ray is used in picking an object for interaction. Also,
PickRay is a subclass of PickShape. See the appropriate reference
block or API reference for the class. See also picking.
pixel An individual picture element of the display. Each pixel is addressable by
an [x, y] coordinate and assigned a single color. In Java 3D, programs do
not typically address individual pixels, instead 3D elements are rasterized.
See also rasterize.
plane A flat surface extending infinitely in all directions. The orientation of a
plane is normally expressed as a surface normal. A plane can be uniquely
defined by a single point and a normal vector.
Getting Started with the Java 3D API Glossary
The Java 3D Tutorial 0-33
plane equation A plane is uniquely specified by a 4-tuple. The first three values represent
the surface normal vector for the plane. The fourth value specifies the
distance from the origin to the plane along a vector parallel to the plane's
surface normal vector.
Point* classes Point* refers to one, or all, of a number of classes used to represent points
in Java 3D. Consult a reference for Point2f, Point3f, Point3d, classes.
point antialiasing An appearance attribute that, when enabled, causes the renderer to apply
antialiasing to points as they are rendered, causing the points to look less
jagged. See also antialiasing, render, and jaggies.
polytope A bounding volume defined by a closed intersection of half-spaces.
processStimulus A method of Behavior. The processStimulus method is called by Java 3D
when the appropriate trigger condition has occurred. It is through this
method that the behavior object responds to the trigger. See Chapter 4 for
more information. See also behavior and wakeup condition.
project To express the world coordinate geometry of 3D objects in 2D image plate
space.
projector The lines that correlate the vertices of a 3D object in world coordinate space
with the pixels in image plate space. A straight line drawn between a 3D
vertex and the viewpoint (viewer's eye) is a projector and determines the
pixel(s) the vertex will rasterize to.
Q
quad Short for quadrilateral. A four sided polygon.
quaternion A quaternion is defined using four floating point values |x y z w|. A
quaternion specifies rotation in four dimensions.
R
raster The per-pixel memory of the display hardware.
rasterize To convert visual objects and their components to their projected images.
The term comes from the use of a raster display device on virtually all
common computers.
ray tracing Applications which render scenes by modeling individual rays of light.
These applications can model inter-object effects such as shadows but are
not fast enough for real time rendering.
render To produce the image represented by the scene graph.
renderer Software to produce the image from a scene graph.
RGB Red, Green, and Blue, the three components used to represent color.
RGBA Red, Green, Blue, and Alpha, the three components used to represent color
with a transparency value.
Getting Started with the Java 3D API Glossary
The Java 3D Tutorial 0-34
+
1
2 0
right-hand rule "Right-hand rule" refers to the correlation between the
direction the fingers curl and the direction the thumb points
on your right hand. The right-hand rule applies in
determining the front face of a polygon, when computing
a cross product of vectors, and when figuring out
which way to turn right-handed nuts, bolts, and screws. The figure at the
right shows the fingers of the right hand curling in the order in which the
vertex coordinates were defined for a triangle. The thumb, pointing up (out
of the page), indicates we are seeing the front face of the triangle. See also
front face and culling.
S
scale To change the shape of a visual object by transforming each of the vertices
of the object. The shape of the visual object can be preserved or distorted
depending on the scale transform. See also transform.
scanline A single row of pixels of the output device.
scanline order The ordering of pixels of a window taken left to right and top to bottom
like the order of characters are read (in English). This order is normally
used in rendering pixels.
scene graph The Java 3D data structure that specifies the visual objects and viewing
parameters in a virtual universe.
scene graph path The path from a locale object, or an interior node, to a leaf of the scene
graph. SceneGraphPath is a class used in picking. See Chapter 4 for
more information on the class.
scheduling bounds A region defined for a behavior. The activation volume of a view must
intersect the scheduling bounds of a behavior for the behavior to be active.
A behavior must be active to be able to execute in response to a stimulus.
See also active, activation volume, and behavior.
scheduling bounding leaf An alternative to a scheduling bounds. See also BoundingLeaf and
scheduling bounds.
scheduling region See scheduling bounds.
scope (of a light) The portion of a scene graph for which a light's influence is considered. By
default, the scope of a light is the scene graph branch it is a member of.
Sub-graphs of the scene graph can be specified as the scope of a light. This
does not replace the specification of a lights region of influence, but is
complementary to the influence of a light. See also influence (of a light).
sensor The abstract concept of an input device such as joy-stick, tracker, or data
glove.
set* or set-method A method of a class that sets a field or value in an object. See also get*
shade n. The color of a vertex or pixel as a result of the application of the lighting
model (for a vertex) or the shade model (for pixel).
v. To calculate the color of a vertex or pixel by the application of the
lighting model (for a vertex) or the shade model (for pixel).
Getting Started with the Java 3D API Glossary
The Java 3D Tutorial 0-35
shade model The calculation of each pixel's shade value from the shade of each
neighboring vertex shade. See also shade, Gouraud shading and flat
shading.
shadow polygon A polygon used to create a shadow in a scene. See section 6.7.3
shininess The specification of how shiny a material surface is. This value (in the
range 1.0 to 128.0) is used in calculating the specular reflection of a light
from a visual object. The higher the value the more concentrated the
specular reflection is. See also specular reflection and material properties.
specular reflection The highlight reflection of light from a shiny visual object. In the real world
presence of a specular reflection depends heavily on how smooth the surface
is. In Java 3D this is modeled as a specular material color and a
concentration value. See also material properties, specular color, and
concentration.
SpotLight class A light source class that has a position, direction, spread angle and
concentration values. See Chapter 6 for more information. See also
concentration.
stitching When the same geometry is rendered as a wire frame and as filled polygons
(of different color), by default the depth of the pixels rendered for each will
not correspond and so the wire frame will appear to move in and out of the
surface and appear as a thread though a cloth surface. See Section 2.6.3.
PolygonAttributes in Module 1 for additional information.
stripification Organization of triangles into triangle strips for rendering efficiency.
surface normal See normal.
T
texel A TEXture ELement. A pixel of a texture image. See texture mapping.
texture 1. n. The image used in texture mapping a visual object. 2. v. To apply an
image to a visual object through texture mapping. See also texture
mapping.
texture mapping The application of a texture image to a visual object based on the
assignment of texture coordinate values to geometric vertices and texture
mapping filters. See also texture, minification filter, and magnification
filter.
three space Three dimensional space.
transform The mathematical operation performed on a vertex, or collection of vertices,
to translate, rotate, or scale the vertices. Transformations are represented as
4 x 4 matrices and stored in TransformGroup objects.
translate Move a vertex or vertices.
TransformGroup class A subclass of Group that also applies a transformation to its child nodes.
See also transformation.
target object The scene graph object changed by a behavior or interpolator.
triangulation The subdivision of a polygon into triangles.
Getting Started with the Java 3D API Glossary
The Java 3D Tutorial 0-36
trilinear interpolation The use of three linear interpolations to arrive at a value. This technique is
used to calculate a shade value for a pixel from the shade values of vertices
in Gouraud shading. See also Gouraud shading and flat shading.
Tuple* classes A set of classes defined in the javax.vecmath package used to
represent tuples. The seven individual Tuple classes are Tuple2f, Tuple3b,
Tuple3d, Tuple3f, Tuple4b, Tuple4f, and Tuple4d. These classes are the
superclasses of Color*, Point* and Vector* classes (among others).
typeface The style of printing text. For example Times Roman, Helvetica, and
Courier are all typefaces. By contrast, a font is a typeface with other
specific attributes. For example, "10 point, italic, Times Roman" is a font.
See also font.
U
utility class A class in the com.sun.j3d.utils package, that builds upon the
core classes to enhance programming capabilities.
V
vecmath An extension package that defines classes for computing vector math.
Among these are the Tuple* classes.
View class The View object is the central object for coordinating all aspects of a view
including which canvas(es). Java 3D supports multiple simultaneous views.
view branch graph The portion of the scene graph containing a View object. The parameters of
the viewing environment (e.g., stereo) and physical parameters (e.g.,
physical position of the viewer) are specified in the view branch graph.
view frustum A truncated pyramid-shaped viewing volume that defines how much of the
virtual universe the viewer sees. Visual objects not within the view frustum
are not visible. Objects that intersect the boundaries of the viewing frustum
are clipped. See Figure 1-9 for an illustration. See also clip, viewer, and
visual object.
viewer The (primary) person viewing the display device Java 3D is rendering to. It
is for this person the PhysicalBody calibration parameters are set.
virtual universe The conceptual space in which the visual objects 'exist'. A virtual universe
may contain multiple virtual worlds as defined by Locale objects.
VirtualUniverse class The core class for Java 3D. An instance of VirtualUniverse must be the
root of the scene graph.
virtual world The conceptual space in which the visual objects 'exist' as defined by a
single Locale object. A virtual world is contained by a virtual universe.
visual object The term visual object is used in places where object would make sense
in English but not in the Object Oriented sense. A visual object may or may
not be visible in a view depending on many factors. Visual object most
often refers to a Shape3D object. (see section 1.2) See also content.
Getting Started with the Java 3D API Glossary
The Java 3D Tutorial 0-37
W
wakeup condition The combination of wakeup criterion that specifies the trigger condition for
a behavior object. Java 3D calls the processStimulus method of the
behavior object in response to the occurrence of the wakeup condition for an
active behavior object. WakeupCondition is a class presented in Chapter 4.
See also behavior, processStimulus, and wakeup criterion.
wakeup criterion Combinations of wakeup criterion objects form a wakeup condition for a
behavior object. Some possible wakeup criterion include AWTEvents,
collisions, behavior activation, passage of time, and a specified number of
frames have been drawn. WakeupCriterion is a class presented in
Chapter 4. See also wakeup condition.
WRAP One of the Boundary Modes available in texture mapping. Repeats the
texture by wrapping texture coordinates that are outside the range [0,1].
See texture mapping.
X
Y
yo-yo A toy.
Z
z-buffer A data structure internal to the renderer to determine the relative depth
(distance from image plate) of visual objects on a per pixel basis. Only the
visual object closest to the image plate is visible.
tutorial v1.5 (Java 3D API v1.1.2)
Getting Started with
the Java 3D
API
Chapter 1
Dennis J Bouvier
K Computing
Getting Started with Java 3D
1999 Sun Microsystems, Inc.
2550 Garcia Avenue, Mountain View, California 94043-1100 U.S.A
All Rights Reserved.
The information contained in this document is subject to change without notice.
SUN MICROSYSTEMS PROVIDES THIS MATERIAL "AS IS" AND MAKES NO WARRANTY OF ANY
KIND, EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS SHALL
NOT BE LIABLE FOR ERRORS CONTAINED HEREIN OR FOR INCIDENTAL OR CONSEQUENTIAL
DAMAGES (INCLUDING LOST PROFITS IN CONNECTION WITH THE FURNISHING, PERFORMANCE
OR USE OF THIS MATERIAL, WHETHER BASED ON WARRANTY, CONTRACT, OR OTHER LEGAL
THEORY).
THIS DOCUMENT COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS.
CHANGES ARE PERIODICALLY MADE TO THE INFORMATION HEREIN; THESE CHANGES WILL BE
INCORPORATED IN NEW EDITIONS OF THE PUBLICATION. SUN MICROSYSTEMS, INC. MAY MAKE
IMPROVEMENTS AND/OR CHANGES IN THE PRODUCT(S) AND/OR PROGRAM(S) DESCRIBED IN THIS
PUBLICATION AT ANY TIME.
Some states do not allow the exclusion of implied warranties or the limitations or exclusion of liability for
incidental or consequential damages, so the above limitations and exclusion may not apply to you. This warranty
gives you specific legal rights, and you also may have other rights which vary from state to state.
Permission to use, copy, modify, and distribute this documentation for NON-COMMERCIAL purposes and
without fee is hereby granted provided that this copyright notice appears in all copies.
This documentation was prepared for Sun Microsystems by K Computing (530 Showers Drive, Suite 7-225,
Mountain View, CA 94040, 770-982-7881, www.kcomputing.com). For further information about course
development or course delivery, please contact either Sun Microsystems or K Computing.
Java, JavaScript, Java 3D, HotJava, Sun, Sun Microsystems, and the Sun logo are trademarks or registered
trademarks of Sun Microsystems, Inc. All other product names mentioned herein are the trademarks of their
respective owners.
Getting Started with Java 3D
The Java 3D Tutorial 1-i
Table of Contents
Chapter 1:
Getting Started......................................................................................................................................1-1
1.1 What is Java 3D........................................................................................................................1-1
1.2 The Java 3D API.......................................................................................................................1-2
1.3 Building a Scene Graph .............................................................................................................1-2
1.3.1 High Level Java 3D API Class Hierarchy...........................................................................1-7
1.4 Recipe for Writing Java 3D Programs........................................................................................1-8
1.4.1 A Simple Recipe for Writing Java 3D Programs .................................................................1-9
1.5 Some Java 3D Terminology.....................................................................................................1-12
1.6 Simple Recipe Example: HelloJava3Da....................................................................................1-13
1.6.1 Java 3D Classes Used in HelloJava3Da............................................................................1-16
1.7 Rotating the Cube....................................................................................................................1-19
1.7.1 Combination of Transformations Example: HelloJava3Db................................................1-20
1.8 Capabilities and Performance...................................................................................................1-22
1.8.1 Compiling Contents..........................................................................................................1-23
1.8.2 Capabilities......................................................................................................................1-24
1.9 Adding Animation Behavior.....................................................................................................1-25
1.9.1 Specifying Animation Behavior ........................................................................................1-26
1.9.2 Time Varying Functions: Mapping a Behavior to Time.....................................................1-27
1.9.3 Scheduling Region ...........................................................................................................1-27
1.9.4 Behavior Example: HelloJava3Dc ....................................................................................1-28
1.9.5 Transformation and Behavior Combination Example: HelloJava3Dd.................................1-30
1.10 Chapter Summary....................................................................................................................1-33
1.11 Self Test..................................................................................................................................1-33
Getting Started with Java 3D
The Java 3D Tutorial 1-ii
Figures
Figure 1-1 Symbols Representing Objects in Scene Graphs....................................................................1-4
Figure 1-2 First Scene Graph Example..................................................................................................1-5
Figure 1-3 Example of an Illegal Scene Graph (not a DAG)...................................................................1-6
Figure 1-4 Fix for Illegal Scene Graph of Figure 1-3..............................................................................1-6
Figure 1-5 An Overview of the Java 3D API Class Hierarchy ................................................................1-8
Figure 1-6 Recipe for Writing Java 3D Programs .................................................................................1-9
Figure 1-7 A SimpleUniverse Object Provides a Minimal Virtual Universe...........................................1-10
Figure 1-8 Simple Recipe for Writing Java 3D Programs.....................................................................1-10
Figure 1-9 Conceptual Drawing of Image Plate and Eye Position in a Virtual Universe.........................1-11
Figure 1-10 Conceptual Renderer Process............................................................................................1-13
Figure 1-11 Scene Graph for HelloJava3Da Example ..........................................................................1-16
Figure 1-12 Image Produced by HelloJava3Da ....................................................................................1-16
Figure 1-13 Scene Graph for Content Branch Graph Created in Code Fragment 1-5.............................1-20
Figure 1-14 Scene Graph for HelloJava3Db Example ..........................................................................1-22
Figure 1-15 Image of the Rotated ColorCube Rendered by HelloJava3Db ............................................1-22
Figure 1-16 Conceptual Example of the Result of Compiling a Scene Graph........................................1-23
Figure 1-17 Recipe for Adding Behaviors to a Java 3D Visual Objects.................................................1-26
Figure 1-18 Scene Graph for HelloJava3Dc Example ..........................................................................1-30
Figure 1-19 An Image of the ColorCube in Rotation as Rendered by HelloJava3Dc..............................1-30
Figure 1-20 Scene Graph for HelloJava3Dd Example ..........................................................................1-32
Figure 1-21 An Image of the ColorCube in Rotation as Rendered by HelloJava3Dd..............................1-32
Getting Started with Java 3D
The Java 3D Tutorial 1-iii
Code Fragments
Code Fragment 1-1 Class HelloJava3Da..............................................................................................1-14
Code Fragment 1-2 Method createSceneGraph for Class HelloJava3Da ...............................................1-14
Code Fragment 1-3 Main() Method of HelloJava3Da Invokes MainFrame............................................1-15
Code Fragment 1-4 Import Statements for HelloJava3Da.java..............................................................1-15
Code Fragment 1-5 One Rotation in the Content Branch Graph............................................................1-20
Code Fragment 1-6 Two Rotation Transformations in HelloJava3Db...................................................1-21
Code Fragment 1-7 createSceneGraph method with RotationInterpolator Behavior...............................1-29
Code Fragment 1-8 Content Branch for Rotated Spinning ColorCube of HelloJava3Dd........................1-31
Getting Started with Java 3D
The Java 3D Tutorial 1-iv
Reference Blocks
SimpleUniverse Constructors ..............................................................................................................1-11
ViewingPlatform setNominalViewingTransform() Method..................................................1-12
SimpleUniverse Methods (partial list)..................................................................................................1-12
BranchGroup compile() Method....................................................................................................1-13
SceneGraphObject Methods (partial list) .............................................................................................1-13
MainFrame Constructor (partial list) ...................................................................................................1-15
BranchGroup Default Constructor.......................................................................................................1-17
Canvas3D Constructor........................................................................................................................1-17
Transform3D Default Constructor.......................................................................................................1-17
Transform3D Methods (partial list) .....................................................................................................1-18
TransformGroup Constructors ............................................................................................................1-18
TransformGroup setTransform() Method...................................................................................1-18
Vector3f Constructors.........................................................................................................................1-19
ColorCube Constructors......................................................................................................................1-19
SceneGraphObject Methods (partial list) .............................................................................................1-24
TransformGroup Capabilities (partial list) ...........................................................................................1-24
Group Capabilities (partial list) ...........................................................................................................1-25
RotationInterpolator Constructor (partial list) ......................................................................................1-26
Alpha Constructor...............................................................................................................................1-27
Behavior setSchedulingBounds method................................................................................................1-28
Bounding Sphere Constructors (partial list) .........................................................................................1-28
Preface to Chapter 1
This document is the first part of a tutorial on using the Java 3D API. Additional chapters and the full
preface to this material is presented in the Module 0 document available at:
http://java.sun.com/products/javamedia/3d/collateral
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-1
1
Getting Started
T(dx, dy, dz) =
1 0 0 dx
0 1 0 dy
0 0 1 dz
0 0 0 1
Chapter Objectives
After reading this chapter, you will:
Be able to explain in general terms what Java 3D is
Be able to describe the basic structure of Java 3D programs
Recognize many classes from the Java 3D API
Be able to write some simple animated Java 3D programs
he Java 3D API is an interface for writing programs to display and interact with three-dimensional
graphics. Java 3D is a standard extension to the Java 2 JDK. The API provides a collection of high-level
constructs for creating and manipulating 3D geometry and structures for rendering that geometry. Java 3D
provides the functions for creation of imagery, visualizations, animations, and interactive 3D graphics
application programs.
1.1 What is the Java 3D API?
The Java 3D API is a hierarchy of Java classes which serve as the interface to a sophisticated three-
dimensional graphics rendering and sound rendering system. The programmer works with high-level
constructs for creating and manipulating 3D geometric objects. These geometric objects reside in a virtual
universe, which is then rendered. The API is designed with the flexibility to create precise virtual universes
of a wide variety of sizes, from astronomical to subatomic.
Despite all this functionality, the API is still straightforward to use. The details of rendering are handled
automatically. By taking advantage of Java threads, the Java 3D renderer is capable of rendering in
parallel. The renderer can also automatically optimize for improved rendering performance.
A Java 3D program creates instances of Java 3D objects and places them into a scene graph data structure.
The scene graph is 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.
CHAPTER
T
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-2
Java 3D programs can be written to run as stand alone applications, as applets in browsers which have
been extended to support Java 3D, or both
1
.
1
Browser support for Java 3D is available through the Java Plugin, which can be downloaded from java.sun.com.
All of the example programs in this tutorial are written as applications.
1.2 The Java 3D API
Every Java 3D program is at least partially assembled from objects from the Java 3D class hierarchy. This
collection of objects describes a virtual universe, which is to be rendered. The API defines over 100
classes presented in the javax.media.j3d package. These classes are commonly referred to as the
Java 3D core classes.
There are hundreds of fields and methods in the classes of the Java 3D API. However, a simple virtual
universe that includes animation can be built with only a few classes. This chapter describes a minimal set
of objects and their interactions to render a simple virtual universe.
This chapter includes the development of one simple but complete Java 3D program called HelloJava3D,
which displays a rotating cube. The example program is developed incrementally, and presented in
multiple versions, to demonstrate each part of the Java 3D programming process. All of the programs used
in this tutorial are available electronically. See the "Getting This Tutorial" section in the Preface for more
information.
In addition to the Java 3D core package, other packages are used in writing Java 3D programs. One such
package is the com.sun.j3d.utils package that is commonly referred to as the Java 3D utility
classes. The core class package includes only the lowest-level classes necessary in Java 3D programming.
The utility classes are convenient and powerful additions to the core.
The utility classes fall into four major categories: content loaders, scene graph construction aids, geometry
classes, and convenience utilities. Future functionality, such as nurbs, likely would be added as utility
classes, not in the Java 3D core package. Some utility classes may be moved to the core package in future
versions of the Java 3D API.
Using utility classes significantly reduces the number of lines of code in a Java 3D program. In addition to
the Java 3D core and utility class packages, every Java 3D program uses classes from the java.awt
package and javax.vecmath package. The java.awt package defines the Abstract Windowing
Toolkit (AWT). AWT classes create a window to display the rendering. The javax.vecmath package
defines vector math classes for points, vectors, matrices, and other mathematical objects.
In the rest of the text, the term visual object is used to refer to an object in the scene graph (e.g., a cube or
a sphere). The term object is used only to refer to an instance of a class. The term content is used to refer
to visual objects in a scene graph as a whole.
1.3 Building a Scene Graph
A Java 3D virtual universe is created from a scene graph. A scene graph is created using instances of Java
3D classes. The scene graph is assembled from objects to define the geometry, sound, lights, location,
orientation, and appearance of visual and audio objects.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-3
A common definition of a graph is a data structure composed of nodes and arcs. A node is a data element,
and arc is a relationship between data elements. The nodes in the scene graph are the instances of Java 3D
classes. The arcs represent the two kinds of relationships between the Java 3D instances.
The most common relationship is a parent-child relationship. A group node can have any number of
children but only one parent. A leaf node can have one parent and no children. The other relationship is a
reference. A reference associates a NodeComponent object with a scene graph Node. NodeComponent
objects define the geometry and appearance attributes used to render the visual objects.
A Java 3D scene graphs is constructed of Node objects in parent-child relationships forming a tree
structure. In a tree structure, one node is the root. Other nodes are accessible following arcs from the root.
The arcs of a tree form no cycles. A scene graph is formed from the trees rooted at the Locale objects.
The NodeComponents and reference arcs are not part of the scene graph tree.
Only one path exists from the root of a tree to each of the leaves; therefore, there is only one path from the
root of a scene graph to each leaf node. The path from the root of a scene graph to a specific leaf node is
the leaf nodes scene graph path. Since a scene graph path leads to exactly one leaf, there is one scene
graph path for each leaf in the scene graph.
Each scene graph path in a Java 3D scene graph completely specifies the state information of its leaf. State
information includes the location, orientation, and size of a visual object. Consequently, the visual
attributes of each visual object depend only on its scene graph path. The Java 3D renderer takes advantage
of this fact and renders the leaves in the order it determines to be most efficient. The Java 3D programmer
normally does not have control over the rendering order of objects
2
.
Graphic representations of a scene graph can serve as design tool and/or documentation for Java 3D
programs. Scene graphs are drawn using standard graphic symbols as shown in Figure 1-1. Java 3D
programs may have many more objects than those of the scene graph.
To design a Java 3D virtual universe a scene graph is drawn using the standard set of symbols. After the
design is complete, that scene graph drawing is the specification for the program. After the program is
complete, the same scene graph is a concise representation of the program (assuming the specification was
followed). A scene graph drawn from an existing program documents the scene graph the program creates.
2
The only control a Java 3D programmer has over the rendering order is with the OrderedGroup class node. This
class is not covered in this tutorial. See The Java 3D API Specification for details.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-4
VirtualUniverse
Locale
Group
Leaf
NodeComponent
other objects
parent-child link
reference
Nodes and NodeComponents (objects) Arcs (object relationships)
Figure 1-1 Symbols Representing Objects in Scene Graphs
Each of the symbols shown on the left-hand side of Figure 1-1 represents a single object when used in a
scene graph. The first two symbols represent objects of specific classes: VirtualUniverse and Locale. The
next three symbols on the left represent objects of the Group, Leaf, and NodeComponent classes. These
three symbols are often annotated to indicate the subclass of the specific object. The last symbol on the left
is used to represent any other class of object.
The solid arrow symbol represents a parent-child relationship between two objects. The dashed arrow is a
reference to another object. Referenced objects can be shared among different branches of a scene graph.
An example of a simple scene graph is shown in Figure 1-2.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-5
BranchGroup Nodes
VirtualUniverse
BG
TG
TransformGroup Node
View Platform
BG
Appearance Geometry
S
Locale
View Canvas3D Screen3D
Physical Body Physical Environment
Shape3D node
Node Components
Figure 1-2 First Scene Graph Example
It is possible to create an illegal scene graph. An example illegal scene graph is shown in Figure 1-3. The
scene graph depicted in Figure 1-3 is illegal because it violates the properties for a DAG. The problem lies
only with the two TransformGroup objects having the same Shape3D leaf object as children. Remember a
Leaf object may have only one parent. In other words, there can only be one path from a Locale object to a
leaf (or one path from a leaf to a Locale).
You may think the structure shown in Figure 1-3 defines three visual objects in a virtual universe. It
appears as though the scene graph defines two visual objects through re-use of the visual (Shape3D) object
on the right-hand side of the figure. Conceptually, each of the TransformGroup objects parenting the
shared instance of Shape3D could place an image of the visual object in different locations. However, it is
an illegal scene graph since the parent-child arcs do not form a tree. In this example, the result is that the
Shape3D object has more than one parent.
The discussion of the tree and DAG structures are correct. However, the Java 3D runtime system reports
the mistake in terms of child-parent relationships. One result of the tree structure limitation is that each
Shape3D object is restricted to one parent. For the example scene graph of Figure 1-3, a 'multiple parent'
exception is reported at runtime. Figure 1-4, with one parent for each Shape3D object, shows one possible
fix for this scene graph.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-6
BG
TG
BG
Appearance Geometry
S TG
Appearance Geometry
S
Figure 1-3 Example of an Illegal Scene Graph
A Java 3D program that defines an illegal scene graph may compile, but not render. When a Java 3D
program that defines an illegal scene graph is run, the Java 3D system detects the problem. When the
problem is detected, the Java 3D system will report an exception. The program may still be running and
consequently, needs to be stopped. However, no image will be rendered.
BG
TG
BG
Appearance Geometry
S
TG
Appearance Geometry
S
Appearance Geometry
S
Figure 1-4 One Possible Fix for Illegal Scene Graph of Figure 1-3
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-7
Each scene graph has a single VirtualUniverse. The VirtualUniverse object has a list of Locale objects. A
Locale object provides a reference point in the virtual universe. Think of a Locale object as being a
landmark used to determine the location of visual objects in the virtual universe.
It is technically possible for a Java 3D program to have more than one VirtualUniverse object, thus
defining more than one virtual universe. However, there is no inherent way to communicate among virtual
universes. Further, a scene graph object can not exist in multiple virtual universes simultaneously. It is
highly recommended to use one and only one instance of VirtualUniverse in each Java 3D program.
While a VirtualUniverse object may reference many Locale objects, most Java 3D programs have only one
Locale object. Each Locale object may serve as the root of multiple subgraphs of the scene graph. Refer
to Figure 1-2 for an example scene graph and note the two subgraph branches from the Locale object in the
figure.
A BranchGroup object is the root of a subgraph, or branch graph. There are two different categories of
scene subgraph: the view branch graph and the content branch graph. The content branch graph specifies
the contents of the virtual universe - geometry, appearance, behavior, location, sound, and lights. The view
branch graph specifies the viewing parameters such as the viewing location and direction. Together, the
two branches specify much of the work the renderer has to do.
1.3.1 High Level Java 3D API Class Hierarchy
An overview of the first three levels of the Java 3D API hierarchy appears in Figure 1-5. The
VirtualUniverse, Locale, Group, and Leaf classes appear in this portion of the hierarchy. Other than the
VirtualUniverse and Locale objects, the rest of a scene graph is composed of SceneGraphObject objects.
SceneGraphObject is the superclass for nearly every Core and Utility Java 3D class.
SceneGraphObject has two subclasses: Node and NodeComponent. The subclasses of Node provide most
of the objects in the scene graph. A Node object is either a Group node or a Leaf node object. Group and
Leaf are superclasses to a number of subclasses. Here is a quick look at the Node class, its two subclasses,
and the NodeComponent class. After this background material is covered, the construction of Java 3D
programs is explained.
Node Class
The Node class is an abstract superclass of Group and Leaf classes. The Node class defines some
important common methods for its subclasses. Information on specific methods is presented in later
sections after more background material is covered. The subclasses of Node compose scene graphs.
Group Class
The Group class is the superclass used in specifying the location and orientation of visual objects in the
virtual universe. Two of the subclasses of Group are BranchGroup and TransformGroup. In the graphical
representation of the scene graph, the Group symbols (circles) are often annotated with BG for
BranchGroups, TG for TransformGroups, etc. Figure 1-2 shows an example of this.
Leaf Class
The Leaf class is the superclass used in specifying the shape, sound, and behavior of visual objects in the
virtual universe. Some of the subclasses of Leaf are Shape3D, Light, Behavior, and Sound. These objects
can have no children but may reference NodeComponents.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-8
NodeComponent Class
The NodeComponent class is the superclass used in specifying 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.
VirtualUniverse
Locale
View
PhysicalBody
PhysicalUniverse
Canvas3D (extends awt.canvas)
ScreenGraphObject
Node
Group
Leaf
NodeComponent
Transform3D
Screen3D
javax.media.j3d
Alpha
Figure 1-5 An Overview of the Java 3D API Class Hierarchy
1.4 Recipe for Writing Java 3D Programs
The subclasses of SceneGraphObject are the building blocks that are assembled into scene graphs. The
basic outline of Java 3D program development consists of seven steps (collectively referred to as a recipe
here and in The Java 3D API Specification) presented in Figure 1-6. This recipe can be used to assemble
many useful Java 3D programs.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-9
1. Create a Canvas3D object
2. Create a VirtualUniverse object
3. Create a Locale object, attaching it to the VirtualUniverse object
4. Construct a view branch graph
a. Create a View object
b. Create a ViewPlatform object
c. Create a PhysicalBody object
d. Create a PhysicalEnvironment object
e. Attach ViewPlatform, PhysicalBody, PhysicalEnvironment, and Canvas3D objects to View
object
5. Construct content branch graph(s)
6. Compile branch graph(s)
7. Insert subgraphs into the Locale
Figure 1-6 Recipe for Writing Java 3D Programs
This recipe ignores some detail but illustrates the fundamental concept of all Java 3D programming:
creating each branch graph of the scene graph is the majority of the programming. Rather than expand on
this recipe, the next section explains an easier way to construct a very similar scene graph with less
programming.
1.4.1 A Simple Recipe for Writing Java 3D Programs
Java 3D programs written using the basic recipe have view branch graphs with identical structure. The
regularity of view branch graph structure is also found in the SimpleUniverse Utility class. Instances of
SimpleUniverse perform steps 2, 3, and 4 from the basic recipe. Using the SimpleUniverse class in Java
3D programming significantly reduces the time and effort needed to create the view branch graph.
Consequently, the programmer has more time to concentrate on the content. This is what writing a Java 3D
program is really about.
The SimpleUniverse is a good starting point for Java 3D programming because it allows the programmer to
ignore the view branch graph. However, using the SimpleUniverse does not allow having multiple views of
the virtual universe.
The SimpleUniverse class is used in all the programming examples in this tutorial. Programmers who need
more information on View, ViewPlatform, PhysicalBody, and PhysicalEnvironment classes are referred to
other references. See Appendix B for a list of references.
SimpleUniverse Class
The SimpleUniverse object constructor creates a scene graph including VirtualUniverse and Locale objects,
and a complete view branch graph. The view branch graph created by SimpleUniverse uses instances of
ViewingPlatform and Viewer convenience classes in place of the core classes used to create the view
branch graph. Note the SimpleUniverse only indirectly uses the View and ViewPlatform objects of the
Java 3D core. The SimpleUniverse object supplies the functionality of all of the objects inside the large
box in Figure 1-7.
The com.sun.j3d.utils.universe package contains the SimpleUniverse, ViewingPlatform, and
Viewer convenience utility classes.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-10
BranchGroup
VirtualUniverse
BG
TG
TransformGroup
View Platform
BG
Appearance Geometry
S
Locale
View Canvas3D Screen3D
Physical Body Physical Environment
Figure 1-7 A SimpleUniverse Object Provides a Minimal Virtual Universe, Indicated by the Dashed
Line.
Using a SimpleUniverse object makes the basic recipe even easier. Figure 1-8 presents the simple recipe,
which is the basic recipe modified to use a SimpleUniverse object. Steps 2, 3, and 4 of the basic recipe are
replaced by step 2 of the simple recipe.
1. Create a Canvas3D Object
2. Create a SimpleUniverse object which references the earlier Canvas3D object
a. Customize the SimpleUniverse object
3. Construct content branch
4. Compile content branch graph
5. Insert content branch graph into the Locale of the SimpleUniverse
Figure 1-8 Simple Recipe for Writing Java 3D Programs using SimpleUniverse.
The gray box on the next page is the first instance of a reference block in this tutorial. A reference block
lists constructors, methods, or fields of a class. Reference blocks are designed to allow the tutorial reader
to learn basic Java 3D API programming without having another reference at hand. The reference blocks
in this tutorial do not cover every constructor or method of a class. For that matter, there are many Java
3D API classes without reference block in this tutorial. Therefore, this tutorial document does not replace
The Java 3D API Specification. However, for the constructors, methods, or fields listed; the reference
blocks in this tutorial typically give more detailed information than The Java 3D API Specification.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-11
SimpleUniverse Constructors
Package: com.sun.j3d.utils.universe
This class sets up a minimal user environment to quickly and easily get a Java 3D program up and running.
This utility class creates all the necessary objects for a view branch graph. Specifically, this class creates
Locale, VirtualUniverse, ViewingPlatform, and Viewer objects (all with their default values). The objects
have the appropriate relationships to form the view branch graph.
SimpleUniverse provides all functionality necessary for many basic Java 3D applications. Viewer and
ViewingPlatform are convenience utility classes. These classes use the View and ViewPlatform core
classes.
SimpleUniverse()
Constructs a simple virtual universe.
SimpleUniverse(Canvas3D canvas3D)
Construct as simple universe with a reference to the named Canvas3D object.
The SimpleUniverse object creates a complete view branch graph for a virtual universe. The view branch
graph includes an image plate. An image plate is the conceptual rectangle where the content is projected to
form the rendered image. The Canvas3D object, which provides an image in a window on your computer
display, can be thought of as the image plate.
Figure 1-9, shows the relationship between the image plate, the eye position, and the virtual universe. The
eye position is behind the image plate. The visual objects in front of the image plate are rendered to the
image plate. Rendering can be thought of as projecting the visual objects to the image plate. This idea is
illustrated with the four projectors in the image (dashed lines).
image plate
projectors
eye position
visual
object
Figure 1-9 Conceptual Drawing of Image Plate and Eye Position in a Virtual Universe.
By default, the image plate is centered at the origin in the SimpleUniverse. The default orientation is to
look down the z-axis. From this position, the x-axis is a horizontal line through the image plate, with
positive values to the right. The y-axis is a vertical line through the center of the image plate, with positive
values up. Consequently, the point (0,0,0) is in the center of the image plate.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-12
The typical Java 3D program moves the view back (positive z) to make objects located at, or near, the
origin within the view. The SimpleUniverse class has a member object of ViewingPlatform class. The
ViewingPlatform class has the method setNominalViewingTransform which sets the eye position to be
centered at (0, 0, 2.41) looking in the negative z direction toward the origin.
ViewingPlatform setNominalViewingTransform() Method
Package: com.sun.j3d.utils.universe
The ViewingPlatform class is used to set up the view branch graph of a Java 3D scene graph in a
SimpleUniverse object. This method is normally used in conjunction with the getViewingPlatform method
of the SimpleUniverse class.
void setNominalViewingTransform()
Sets the nominal viewing distance to approximately 2.41 meters in the view transform of a SimpleUniverse.
At this viewing distance and the default field of view, objects of height and width of 2 meters generally fit
on the image plate.
After creating Canvas3D and Simple Universe objects, the next step is the creation of the content branch
graph. The regularity of structure found in the view branch graph (that leads to using the SimpleUniverse
class) does not exist for the content branch graph. The content branch graph varies from program to
program making it impossible to give details for construction in a recipe. It also means that there is no
simple content class for any universe you may want to assemble.
Creating a content branch graph is the subject of Sections 1.6, 1.7, and 1.9. Compiling the content branch
graph is discussed in Section 1.8. If you cannot wait to see some code, see Code Fragment 1-1 for an
example of using the SimpleUniverse class.
After creating the content branch graph, it is inserted into the universe using the addBranchGraph method
of SimpleUniverse. The addBranchGraph method takes an instance of BranchGroup as the only parameter.
This BranchGroup is added as a child of the Locale object created by the SimpleUniverse.
SimpleUniverse Methods (partial list)
Package: com.sun.j3d.utils.universe
void addBranchGraph(BranchGroup bg)
Used to add Nodes to the Locale object of the scene graph created by the SimpleUniverse. This is used to
add a content branch graph to the virtual universe.
ViewingPlatform getViewingPlatform()
Used to retrieve the ViewingPlatform object the SimpleUniverse instantiated. This method is used with the
setNominalViewingTransform() method of ViewingPlatform to adjust the location of the view position.
1.5 Some Java 3D Terminology
Before moving on to the topic of creating the content branch graph, two Java 3D terms are defined. The
terms live and compiled are defined in this section.
Inserting a branch graph into a Locale makes it live, and consequently, each of the objects in that branch
graph become live. There are some consequences when an object becomes live. Live objects 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. Capabilities are explained in Section 1.8.2.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-13
BranchGroup objects can be compiled. Compiling a BranchGroup converts the BranchGroup object and
all of its ancestors to a more efficient form for the renderer. Compiling BranchGroup objects is
recommended as the last step before making it live. It is best to only compile the BranchGroup objects
inserted into Locales. Compilation is further discussed in sections 1.8 and 1.8.1.
BranchGroup compile() Method
void compile()
Compiles the source BranchGroup associated with this object by creating and caching a compiled scene
graph.
Concepts of compiled and live are implemented in the SceneGraphObject class. The two methods of the
SceneGraphObject class that relate to these concepts are shown in the SceneGraphObject methods
reference box below.
SceneGraphObject Methods (partial list)
SceneGraphObject is the superclass of nearly every class used to create a scene graph including Group,
Leaf, and NodeComponent. The SceneGraphObject provides a number of common methods and fields for
its subclasses; two of which are presented here. The methods of SceneGraphObject associated with
compile are covered in Section 1.8 Performance Basics.
boolean isCompiled()
Returns a flag indicating whether the node is part of a scene graph that has been compiled.
boolean isLive()
Returns a flag indicating whether the node is part of a live scene graph.
Note there is no start the renderer step in either the basic or simple recipes. The Java 3D renderer starts
running in an infinite loop when a branch graph containing an instance of View becomes live in a virtual
universe. Once started, the Java 3D renderer conceptually performs the operations shown in Figure 1-10.
while(true) {
Process input
If (request to exit) break
Perform Behaviors
Traverse the scene graph
and render visual objects
}
Cleanup and exit
Figure 1-10 Conceptual Renderer Process
The previous sections explained the construction of a simple virtual universe without a content branch
graph. Creating the content branch graph is the subject of the next few sections. Creating content is
discussed through the presentation of example programs.
1.6 Simple Recipe Example: HelloJava3Da
The typical Java 3D program begins by defining a new class to extend the Applet class. In the
HelloJava3Da.java example found in the examples/HelloJava3D directory,
HelloJava3Da is a class defined to extend the Applet class. Java 3D programs could be written as
applications, but using Applet class gives an easy way to produce a windowed application.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-14
The main class of a Java 3D program typically defines a method to construct the content branch graph. In
the HelloJava3Da example such a method is defined and it is called createSceneGraph().
All steps of the simple recipe are implemented in the constructor of the HelloJava3Da class. Step 1, create
a Canvas3D object, is completed on line 4. Step 2, create a SimpleUniverse object, is done on line 11.
Step 2a, customize the SimpleUniverse object, is accomplished on line 15. Step 3, construct content
branch, is accomplished by a call to the createSceneGraph() method. Step 4, compile content branch
graph, is done on line 8. Finally, step 5, insert content branch graph into the Locale of the SimpleUniverse,
is completed on line 16.
1. public class HelloJava3Da extends Applet {
2. public HelloJava3Da() {
3. setLayout(new BorderLayout());
4. Canvas3D canvas3D = new Canvas3D(null);
5. add("Center", canvas3D);
6.
7. BranchGroup scene = createSceneGraph();
8. scene.compile();
9.
10. // SimpleUniverse is a Convenience Utility class
11. SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
12.
13. // This moves the ViewPlatform back a bit so the
14. // objects in the scene can be viewed.
15. simpleU.getViewingPlatform().setNominalViewingTransform();
16.
17. simpleU.addBranchGraph(scene);
18. } // end of HelloJava3Da (constructor)
Code Fragment 1-1 Class HelloJava3Da
Step 3 of the simple recipe is to create the content branch graph. A content branch graph is created in
Code Fragment 1-2. It is probably the simplest content branch graph possible. The content branch created
in Code Fragment 1-2 contains one static graphical object, a ColorCube. The ColorCube is located at the
origin of the virtual world coordinate system. With the given location and orientation of the viewing
direction and the cube, the cube appears as a rectangle when rendered. The image is shown after all of the
code for the program is presented, in Figure 1-12.
1. public BranchGroup createSceneGraph() {
2. // Create the root of the branch graph
3. BranchGroup objRoot = new BranchGroup();
4.
5. // Create a simple shape leaf node, add it to the scene graph.
6. // ColorCube is a Convenience Utility class
7. objRoot.addChild(new ColorCube(0.4));
8.
9. return objRoot;
10. } // end of createSceneGraph method of HelloJava3Da
11. } // end of class HelloJava3Da
Code Fragment 1-2 Method createSceneGraph for Class HelloJava3Da
The class HelloJava3Da is derived from Applet but the program is runnable as an application with the use
of the MainFrame class. The Applet class is used as a base class to make it easy to write a Java 3D
program that runs in a window. MainFrame provides an AWT frame (window) for an applet allowing the
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-15
applet to run as an application. The window size of the resulting application is specified in the construction
of the MainFrame class. Code Fragment 1-3 shows the use of MainFrame in HelloJava3Da.java.
MainFrame Constructor (partial list)
package: com.sun.j3d.utils.applet
MainFrame makes an applet into an application. A class derived from applet may have a main() method
which calls the MainFrame constructor. MainFrame extends java.awt.Frame and implements
java.lang.Runnable, java.applet.AppletStub, and
java.applet.AppletContext. The MainFrame class is Copyright 1996-1998 by Jef Poskanzer
email: [email protected] http://www.acme.com/java/
MainFrame(java.applet.Applet applet, int width, int height)
Creates a MainFrame object that runs an applet as an application.
Parameters:
applet the constructor of a class derived from applet. MainFrame provides an AWT frame for this
applet.
width the width of the window frame in pixels
height the height of the window frame in pixels
1. // The following allows this to be run as an application
2. // as well as an applet
3.
4. public static void main(String[] args) {
5. Frame frame = new MainFrame(new HelloJava3Da(), 256, 256);
6. } // end of main (method of HelloJava3Da)
Code Fragment 1-3 Main() Method of HelloJava3Da Invokes MainFrame
The three preceding code fragments (1-1, 1-2, and 1-3) form a complete Java 3D program when the proper
import statements are used. The following import statements are necessary to compile the class
HelloJava3Da. The most commonly used classes in Java 3D programming are found in the
javax.media.j3d, or javax.vecmath packages. In this example, only the ColorCube Utility
class is found in the com.sun.j3d.utils.geometry package. Consequently, most Java 3D
programs have the import statements shown in Code Fragment 1-4 with the exception of the import for
ColorCube.
1. import java.applet.Applet;
2. import java.awt.BorderLayout;
3. import java.awt.Frame;
4. import java.awt.event.*;
5. import com.sun.j3d.utils.applet.MainFrame;
6. import com.sun.j3d.utils.universe.*;
7. import com.sun.j3d.utils.geometry.ColorCube;
8. import javax.media.j3d.*;
9. import javax.vecmath.*;
Code Fragment 1-4 Import Statements for HelloJava3Da.java
In the HelloJava3Da.java example program, a single graphic object was placed in a single locale.
The resulting scene graph is shown in Figure 1-11.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-16
VirtualUniverse
BG
Locale
ColorCube
View branch
graph
objects created by
SimpleUniverse
Figure 1-11 Scene Graph for HelloJava3Da Example
The four preceding code fragments (1-1, 1-2, 1-3, and 1-4) form the complete HelloJava3Da.java
example program. The complete program is found in the examples/HelloJava3D directory of the
distribution. Compile the code by issuing the command: javac HelloJava3Da.java. Run the
program with the command: java HelloJava3Da. The image produced by HelloJava3Da is shown in
Figure 1-12.
Figure 1-12 Image Produced by HelloJava3Da
While not every line of code of the HelloJava3Da example is explained, the basic ideas of assembling a
Java 3D program should be clear having read the example. The following section fills in some of the gaps
by presenting the classes used in the program.
1.6.1 Java 3D Classes Used in HelloJava3Da
To add to the understanding of the Java 3D API and the HelloJava3Da example a synopsis of each of
the Java 3D API classes used in the HelloJava3Da example program are presented here.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-17
BranchGroup Class
Objects of this type are used to form scene graphs. Instances of BranchGroup are the root of subgraphs.
BranchGroup objects are the only objects allowed to be children of Locale objects. BranchGroup objects
can have multiple children. The children of a BranchGroup object can be other Group or Leaf objects.
BranchGroup Default Constructor
BranchGroup()
Instances of BranchGroup serve as roots of scene graph branches; BranchGroup objects are the only
objects that can be inserted into a Locale's set of objects.
Canvas3D Class
The Canvas3D class is derived from the Canvas class of the Abstract Windowing Toolkit (AWT). At least
one Canvas3D object must be referenced in the viewing branch graph of the scene graph
3
. For more
information on the Canvas class, consult a reference on the AWT. A list of references appears in Appendix
B.
Canvas3D Constructor
Canvas3D(GraphicsConfiguration graphicsconfiguration)
Constructs and initializes a new Canvas3D object that Java 3D can render given a valid
GraphicsConfiguration object. It is an extension of the AWT Canvas class. For more information on the
GraphicsConfiguration object see the Java 2D specification, which is part of the AWT in JDK 1.2.
Transform3D Class
Transform3D objects represent transformations of 3D geometry such as translation and rotation. These
objects are typically only used in the creation of a TransformGroup object. First, the Transform3D object
is constructed, possibly from a combination of Transform3D objects. Then the TransformGroup object is
constructed using the Transform3D object.
Transform3D Default Constructor
A generalized transform object is represented internally as a 4x4 double precision floating-point matrix.
The mathematical representation is row major. A Transform3D object is not used in a scene graph. It is
used to specify the transformation of a TransformGroup object.
Transform3D()
Constructs a Transform3D object that represents the identity matrix (no transformation).
A Transform3D object can represent translation, rotation, scaling, or a combination of these. When
specifying a rotation, the angle is expressed in radians. One full rotation is 2 PI radians. One way to
specify angles is to use the constant Math.PI. Another way is to specify values directly. Some
approximations are: 45 degrees is 0.785, 90 degrees is 1.57, and 180 degrees is 3.14.
3
It is possible to have more than one. To keep things simple, using the SimpleUniverse, there will be only one
instance of Canvas3D in the programs presented.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-18
Transform3D Methods (partial list)
Transform3D objects represent geometric transformations such as rotation, translation, and scaling.
Transform3D is one of the few classes not directly used in any scene graph. The transformations
represented by a Transform3D object are used to create TransformGroup objects that are used in scene
graphs.
void rotX(double angle)
Sets the value of this transform to a counter clockwise rotation about the x-axis. The angle is specified in
radians.
void rotY(double angle)
Sets the value of this transform to a counter clockwise rotation about the y-axis. The angle is specified in
radians.
void rotZ(double angle)
Sets the value of this transform to a counter clockwise rotation about the z-axis. The angle is specified in
radians.
void set(Vector3f translate)
Sets the translational value of this matrix to the Vector3f parameter values, and sets the other components
of the matrix as if this transform were an identity matrix.
TransformGroup Class
As a subclass of the Group class, instances of TransformGroup are used in the creation of scene graphs
and have a collection of child node objects. TransformGroup objects hold geometric transformations such
as translation and rotation. The transformation is typically created in a Transform3D object, which is not a
scene graph object.
TransformGroup Constructors
TransformGroup objects are holders of transformations in the scene graph.
TransformGroup()
Constructs and initializes a TransformGroup using an identity transform.
TransformGroup(Transform3D t1)
Constructs and initializes a TransformGroup from the Transform3D object passed.
Parameters:
t1 - the transform3D object
The transform held in a Transform3D object is copied to a TransformGroup object either when the
TransformGroup object is created, or by using the setTransform() method.
TransformGroup setTransform() Method
void setTransform(Transform3D t1)
Sets the transform component of this TransformGroup to the value of the passed transform.
Parameters:
t1 - the transform to be copied.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-19
Vector3f Class
Vector3f is a math class found in the javax.vecmath package for specifying a vector using three
floating-point values. Vector objects are often used to specify translations of geometry. Vector3f objects
are not used directly in the construction of a scene graph. They are used to specify translation, surface
normals, or other things.
Vector3f Constructors
A 3-element vector that is represented by single precision floating point x, y, and z coordinates.
Vector3f()
Constructs and initializes a Vector3f to (0,0,0).
Vector3f(float x, float y, float z)
Constructs and initializes a Vector3f from the specified x, y, z coordinates.
ColorCube
ColorCube is a utility class found in the com.sun.j3d.utils.geometry package that defines the
geometry and colors of a cube centered at the origin with different colors on each face. The default
ColorCube object is in a cube that is 2 meters high, wide and deep. If a non-rotated cube is placed at the
origin (as in HelloJava3Da), the red face will be visual from the nominal viewing location. Other colors are
blue, magenta, yellow, green, and cyan.
ColorCube Constructors
Package: com.sun.j3d.utils.geometry
A ColorCube is a simple color-per-vertex cube visual object with a different color for each face.
ColorCube extends the Shape3D class; therefore, it is a Leaf node. ColorCube is easy to use when putting
together a virtual universe.
ColorCube()
Constructs a color cube of default size. By default, a corner is located 1 meter along each of the axis from
the origin, resulting in a cube that is centered at the origin and is 2 meters high, wide and deep.
ColorCube(double scale)
Constructs a color cube scaled by the value specified. The default size is 2 meters on an edge. The
resulting ColorCube has corners at (scale, scale, scale) and (-scale, -scale, -scale).
1.7 Rotating the Cube
A simple rotation of the cube can be made to show more than one face of the cube. The first step is to
create the desired transformation using a Transform3D object.
The Code Fragment 1-5 incorporates a TransformGroup object in the scene graph to rotate the cube about
the x-axis. The rotation transformation is first created using the Transform3D object rotate. The
Transform3D object is created on line 6. The rotation is specified using the rotX() method on line 8. The
TransformGroup object is then created holding the rotation transform on line 10.
Two parameters specify the rotation: the axis of revolution, and the angle of rotation. The axis is chosen
by selecting the proper method. The angle of rotation is the value that is the argument to the method.
Since the angle of rotation is specified in radians, the value /4 is 1/8 of a full rotation, or 45 degrees.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-20
After creating the Transform3D object, rotate, it is used in the creation of a TransformGroup object
objRotate (line 10). The Transform3D object is used in the scene graph. The objRotate object then makes
the ColorCube object its child (line 11). In turn, the objRoot object makes objRotate its child (line 12).
The Transform3D methods rotX(), rotY, and rotZ() are listed in a reference block in the previous section.
1. public BranchGroup createSceneGraph() {
2. // Create the root of the branch graph
3. BranchGroup objRoot = new BranchGroup();
4.
5. // rotate object has composite transformation matrix
6. Transform3D rotate = new Transform3D();
7.
8. rotate.rotX(Math.PI/4.0d);
9.
10. TransformGroup objRotate = new TransformGroup(rotate);
11. objRotate.addChild(new ColorCube(0.4));
12. objRoot.addChild(objRotate);
13. return objRoot;
14. } // end of createSceneGraph method
Code Fragment 1-5 One Rotation in the Content Branch Graph
The content branch graph now includes a TransformGroup object in the scene graph path to the ColorCube
object. Each of the objects in the scene graph path is necessary. The BranchGroup object is the only
object that can be a child of a Locale. The TransformGroup object is the only object that can change the
location, orientation, or size of a visual object. In this case, the TransformGroup object changes the
orientation. Of course, the ColorCube object is necessary to supply the visual object.
The content branch graph produced by Code Fragment 1-5 is shown in Figure 1-13.
BG
ColorCube
TG
Figure 1-13 Scene Graph for Content Branch Graph Created in Code Fragment 1-5
Code Fragment 1-5 is not used in a program in the example subdirectory. It is only presented as a stepping
stone to bigger and more interesting programs. The bigger problem, presented next, is combining two
transformations in one TransformGroup object.
1.7.1 Combination of Transformations Example: HelloJava3Db
Quite often a visual object is translated and rotated, or rotated about two axes. In either case, two different
transformations are specified for a single visual object. The two transformations can be combined into one
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-21
transformation matrix and held by a single TransformGroup object. An example of this is shown in Code
Fragment 1-6.
Two rotations are combined in the example program HelloJava3Db. Making two simultaneous
rotations requires combining two rotation Transform3D objects. The example rotates the cube around both
the x and y-axes. Two Transform3D objects, one for each rotation, are created (lines 6 and 7). The
individual rotations are specified for the two TransformGroup objects (lines 9 and 10). Then the rotations
are combined by multiplying the Transform3D objects (line 11). The combination of the two transforms is
then loaded into the TransformGroup object (line 12).
1. public BranchGroup createSceneGraph() {
2. // Create the root of the branch graph
3. BranchGroup objRoot = new BranchGroup();
4.
5. // rotate object has composite transformation matrix
6. Transform3D rotate = new Transform3D();
7. Transform3D tempRotate = new Transform3D();
8.
9. rotate.rotX(Math.PI/4.0d);
10. tempRotate.rotY(Math.PI/5.0d);
11. rotate.mul(tempRotate);
12. TransformGroup objRotate = new TransformGroup(rotate);
13.
14. objRotate.addChild(new ColorCube(0.4));
15. objRoot.addChild(objRotate);
16. return objRoot;
Code Fragment 1-6 Two Rotation Transformations in HelloJava3Db
Either Code Fragment 1-5 or Code Fragment 1-6 could replace Code Fragment 1-2 in HelloJava3Da to
create a new program. Code Fragment 1-6 is used in HelloJava3Db.java. The complete example
program, with the combined rotations, appears in examples/HelloJava3D/ in file
HelloJava3Db.java. This program is run as an application as HelloJava3Da was.
The scene graph created in HelloJava3Db.java is shown in Figure 1-14. The view branch graph is
the same one produced in HelloJava3Da, which is constructed by SimpleUniverse and represented by the
large star. The content branch graph now includes a TransformGroup in the scene graph path to the
ColorCube object.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-22
BG
ColorCube
TG
View branch
graph
Figure 1-14 Scene Graph for HelloJava3Db Example
The image in Figure 1-15 shows the rotated ColorCube from HelloJava3Db.
Figure 1-15 Image of the Rotated ColorCube Rendered by HelloJava3Db
1.8 Capabilities and Performance
The scene graph constructed by a Java 3D program could be used directly for rendering. However, the
representation is not very efficient. The flexibility built in to each scene graph object (which has not been
discussed in this tutorial) makes it a sub-optimal representation of the virtual universe. A more efficient
representation of the virtual universe is used to improve rendering performance.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-23
Java 3D has an internal representation for a virtual universe and methods for making the conversion. There
are two ways to have the Java 3D system make the conversion to the internal representation. One way is to
compile each branch graph. The other way is to insert the branch graph into a virtual universe to make it
live. Compiling a branch graph is the subject of the next section. The effects of the conversion to the
internal representation are discussed in Section 1.8.2.
1.8.1 Compiling Contents
The BranchGroup object has a compile method. Invoking this method converts the entire branch graph
below the branch group to the Java 3D internal representation of the branch graph. In addition to the
conversion, the internal representation may be optimized in one or more ways.
The possible optimizations are not specified by the Java 3D API. However, efficiencies can be gained in a
number of ways. One of the possible optimizations is to combine TransformGroups along scene graph
paths. For example, if a scene graph has two TransformGroup objects in a parent-child relationship they
can be represented by one TransformGroup object. Another possibility is to combine Shape3D objects
which have a static physical relationship. These types of optimizations are made possible when the
capabilities are not set. Other optimizations are possible as well.
Figure 1-16 presents a conceptual representation of the conversion to a more efficient representation. The
scene graph on the left-hand side of the Figure is compiled and transformed into the internal representation
shown on the right-hand side of the Figure. The Figure only represents the concept of the internal
representation, not how Java 3D actually performs.
BG
ColorCube
TG
TG
View branch
graph
compile
BG
ColorCube
TG
View branch
graph
Figure 1-16 Conceptual Example of the Result of Compiling a Scene Graph
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-24
1.8.2 Capabilities
Once a branch graph is made live or compiled the Java 3D rendering system converts the branch graph to a
more efficient internal representation. The most important effect of converting the scene graph to the
internal representation is to improve rendering performance.
Making the transformation to the internal representation has other effects as well. One effect is to fix the
value of transformations and other objects in the scene graph. Unless specifically provided for in the
program, the program no longer has the capability to change the values of the scene graph objects after
they are live.
There are cases when a program still needs the capability to change values in a scene graph object after it
becomes live. For example, changing the value of a TransformGroup object creates animations. For this
to happen, the transform must be able to change after it is live. The list of parameters than can be
accessed, and in which way, is called the capabilities of the object.
Each SceneGraphObject has a set of capability bits. The values of these bits determine what capabilities
exist for the object after it is compiled or becomes live. The set of capabilities varies by class.
SceneGraphObject Methods (partial list)
SceneGraphObject is the superclass of nearly every class used to create a scene graph including Group,
Leaf, and NodeComponent. Section 1.5 presents some other SceneGraphObject methods.
void clearCapability(int bit)
Clear the specified capability bit.
boolean getCapability(int bit)
Retrieves the specified capability bit.
void setCapability(int bit)
Sets the specified capability bit.
As an example, to be able to read the value of the transform represented by a TransformGroup object, that
capability must be set before it is either compiled or becomes live. Similarly, to be able to change the value
of the transform in a TransformGroup object, its transform write capability must be set before it becomes
live, or is compiled. The following reference block shows the capabilities of the non-inherited
TransformGroup class. Attempting to make a change in a live or compiled object for which the proper
capability is not set results in an exception.
In the next section, animations are created using a time varying rotation transformation. For this to be
possible, the TransformGroup object must have its ALLOW_TRANSFORM_WRITE capability set before
it either is compiled or becomes live.
TransformGroup Capabilities (partial list)
The two capabilities listed here are the only ones defined by TransformGroup. TransformGroup inherits a
number of capability bits from its ancestor classes: Group and Node. Capability settings are set, reset, or
retrieved using methods defined in SceneGraphObject.
ALLOW_TRANSFORM_READ
Specifies the TransformGroup node allows access to the transform information of its object.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-25
ALLOW_TRANSFORM_WRITE
Specifies the TransformGroup node allows writing the transform information of its object.
Capabilities control access to other aspects of a TransformGroup object as well. TransformGroup object
inherits capability settings from its ancestor classes: Group and Node. Some of the capabilities of Group
are shown in the following reference block.
Group Capabilities (partial list)
TransformGroup inherits a number of capability bits from its ancestor classes
ALLOW_CHILDREN_EXTEND
Setting this capability allows children to be added to the Group node after it is compiled, or made live.
ALLOW_CHILDREN_READ
Setting this capability allows the references to the children of the Group node to be read after it is compiled,
or made live.
ALLOW_CHILDREN_WRITE
Setting this capability allows the references to the children of the Group node to be written (changed) after
it is compiled, or made live.
1.9 Adding Animation Behavior
In Java 3D, Behavior is a class for specifying animations of or interaction with visual objects. The
behavior can change virtually any attribute of a visual object. A programmer can use a number of pre-
defined behaviors or specify a custom behavior. Once a behavior is specified for a visual object, the Java
3D system updates the position, orientation, color, or other attributes, of the visual object automatically.
The distinction between animation and interaction is whether the behavior is activated in response to the
passing of time or in response to user activities, respectively.
Each visual object in the virtual universe can have its own predefined behavior. In fact, a visual object
may have multiple behaviors. To specify a behavior for a visual object, the programmer creates the objects
that specify the behavior, adds the visual object to the scene graph, and makes the appropriate references
among scene graph objects and the behavior objects.
In a virtual universe with many behaviors, a significant amount of computing power could be required just
for computing the behaviors. Since both the renderer and behaviors use the same processor(s), it is
possible the computational power requirement for behaviors could degrade rendering performance
4
.
Java 3D allows the programmer to manage this problem by specifying a spatial boundary for a behavior to
take place. This boundary is called a scheduling region. A behavior is not active unless the
ViewPlatforms activation volume intersects a Behavior objects scheduling region. In other words, if
there is no one in the forest to see the tree falling, it does not fall. The scheduling region feature makes
Java 3D more efficient in handling a virtual universe with many behaviors.
An Interpolator is one of a number of predefined behavior classes in the core Java 3D package created
which are subclasses of Behavior. Based on a time function, the Interpolator object manipulates the
4
Special graphics processors may be involved in the rendering process depending on the hardware environment
and the implementation of Java 3D. Even so, it is still possible to have too many behaviors in a virtual universe to
render quickly.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-26
parameters of a scene graph object. For example, for the RotationInterpolator, manipulates the rotation
specified by a TransformGroup to affect the rotation of the visual objects which are ancestors of the
TransformGroup.
Figure 1-17 enumerates the steps involved in specifying an animation with an interpolator object. The five
steps of Figure 1-17 form a recipe for creating an interpolation animation behavior.
1. Create a target TransformGroup
Set the ALLOW_TRANSFORM_WRITE capability
2. Create an Alpha
5
object
Specify the time parameters for the alpha
3. Create the interpolator object
Have it reference the Alpha and TransformGroup objects
Customize the behavior parameters
4. Specify a scheduling region
Set the scheduling region for the behavior
5. Make the behavior a child of the TransformGroup
Figure 1-17 Recipe for Adding Behaviors to a Java 3D Visual Objects
1.9.1 Specifying Animation Behavior
A behavior action can be a change in location (PositionInterpolator), orientation (RotationInterpolator),
size (ScaleInterpolator), color (ColorInterpolator), or transparency (TransparencyInterpolator) of a visual
object. As mentioned before, Interpolators are predefined behavior classes. All of the mentioned behaviors
are possible without using an interpolator; however, interpolators make creating a behavior much easier.
Interpolators classes exist to provide other actions, including combinations of these actions. The details of
these classes are presented in Section 5.2 and can be found in the API specification. The
RotationInterpolator class is used in an example below.
RotationInterpolator Class
This class is used to specify a rotation behavior of a visual object or a group of visual objects. A
RotationIterpolator object changes a TransformGroup object to a specific rotation in response to the value
of an Alpha object. Since the value of an Alpha object changes over time, the rotation changes as well. A
RotationInterpolator object is flexible in specification of what axis of rotation, starting angle, and ending
angle.
For simple constant rotations, the RotationInterpolator object has the following constructor that can be
used:
RotationInterpolator Constructor (partial list)
This class defines a behavior that modifies the rotational component of its target TransformGroup by
linearly interpolating between a pair of specified angles (using the value generated by the specified Alpha
object). The interpolated angle is used to generate a rotation transform.
5
Alpha is a class in Java 3D for creating time varying functions. See section 1.9.2 and/or the glossary for more
information.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-27
RotationInterpolator(Alpha alpha, TransformGroup target)
This constructor uses default values for some parameters of the interpolator to construct a full rotation
about the y-axis using the specified interpolator target TransformGroup.
parameters:
alpha the time varying function to reference.
target the TransformGroup object to modify.
The target TransformGroup object of an interpolator must have write capability. Information on
capabilities is presented in Section 1.8.
1.9.2 Time Varying Functions: Mapping a Behavior to Time
Mapping an action to time is done using an Alpha object. The specification of the alpha object can be
complex. Some basic information on the Alpha class is presented here.
Alpha Class
Alpha class objects are used to create a time varying function. The Alpha class produces a value between
zero and one, inclusive. The value it produces is dependent on the time and the parameters of the Alpha
object. Alpha objects are commonly used with an Interpolator behavior object to provide animations of
visual objects.
There are ten parameters to Alpha, giving the programmer tremendous flexibility. Without getting into the
details of each parameter, know that an instance of Alpha can easily be combined with a behavior to
provide simple rotations, pendulum swings, and one-time events such as door openings, or rocket launches.
Alpha Constructor
The alpha class provides objects for converting time into an alpha value (a value in the range 0 to 1). The
Alpha object is effectively a function of time that generates alpha values in the range zero to one, inclusive.
A use of the Alpha object is to provide values for Interpolator behaviors. The function f(t) and the
characteristics of the Alpha object are determined by user-definable parameters:
Alpha()
Continuous looping with a period of one second.
Alpha(int loopCount, long increasingAlphaDuration)
This constructor takes only the loopCount and increasingAlphaDuration as parameters and assigns the
default values to all of the other parameters. The resulting Alpha object produces values starting at zero
increasing to one. This repeats the number of times specified by loopCount. If loopCount is 1, the alpha
object repeats indefinitely. The time it takes to get from zero to one is specified in the second parameter
using a scale of milliseconds.
Parameters:
loopCount - number of times to run this alpha object; a value of -1 specifies that the alpha loops
indefinitely.
increasingAlphaDuration - time in milliseconds during which alpha goes from zero to one
1.9.3 Scheduling Region
As mentioned in section 1.9, each behavior has scheduling bounds. The scheduling bounds for a behavior
are set using the setSchedulingBounds method of the Behavior class.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-28
There are a number of ways to specify a scheduling region, the simplest of which is to create a
BoundingSphere object. Other options include bounding box and a bounding polytope. The
BoundingSphere class is discussed below. For information on BoundingBox and BoundingPolytope, the
reader is referred to the API specification.
Behavior setSchedulingBounds method
void setSchedulingBounds(Bounds region)
Set the Behavior's scheduling region to the specified bounds.
Parameters:
region - the bounds that contains the Behavior's scheduling region.
BoundingSphere Class
Specifying a bounding sphere is accomplished by specifying a center point and a radius for the sphere. The
normal use of the bounding sphere is to use the center at (0, 0, 0). The radius is then selected large enough
such that the sphere contains the visual object, including all possible locations for the object.
Bounding Sphere Constructors (partial list)
This class defines a spherical bounding region that is defined by a center point and a radius.
BoundingSphere()
This constructor creates a bounding sphere centered at the origin (0, 0, 0) with a radius of 1.
BoundingSphere(Point3d center, double radius)
Constructs and initializes a BoundingSphere using the specified center point and radius.
1.9.4 Behavior Example: HelloJava3Dc
Code Fragment 1-7 shows a complete example of using one of the interpolator classes to create an
animation. The animation created in this code is a continuous rotation with a total rotation time of four
seconds. Code Fragment 1-7 correlates with the interpolation animation recipe given in Figure 1-17.
Step 1 of the recipe is to create a TransformGroup object to modify at runtime. The target
TransformGroup object of an interpolator must have write capability set. The TransformGroup object
named objSpin is created on line 7. The capability of objSpin is set on line 8 of Code Fragment 1-7.
Step 2 is to create an alpha object to drive the interpolator. In the simple example shown in Code Fragment
1-7 the Alpha object, rotationAlpha, is used to specify a continuous rotation. The two parameters specified
on line 16 of Code Fragment 1-7 are the number of loop iterations and the time for one cycle. The value
-1 for the loop count specifies continuous looping. The time is specified in milliseconds. The value 4000
used in the program is 4000 milliseconds which is 4 seconds. Therefore, the behavior is to rotate once
every four seconds.
Step 3 of the recipe is to create the interpolator object. The RotationInterpolator object rotate is created on
lines 21 and 22. The interpolator must have references to the target transform and alpha objects. This is
accomplished in the constructor. In this example, the RotationInterpolators default behavior is used. The
default behavior of the RotationInterpolator is to make a full rotation about the y-axis.
Step 4 is to specify a scheduling region. In Code Fragment 1-7, a BoundingSphere object is used with its
default values. The BoundingSphere object is created on line 25. The sphere is set as the bounds for the
behavior on line 26.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-29
The final step, step 5, makes the behavior a child of the TransformGroup. This is accomplished on line 27.
1. public BranchGroup createSceneGraph() {
2. // Create the root of the branch graph
3. BranchGroup objRoot = new BranchGroup();
4.
5. // Create the transform group node and initialize it to the
6. // identity. Add it to the root of the subgraph.
7. TransformGroup objSpin = new TransformGroup();
8. objSpin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
9. objRoot.addChild(objSpin);
10.
11. // Create a simple shape leaf node, add it to the scene graph.
12. // ColorCube is a Convenience Utility class
13. objSpin.addChild(new ColorCube(0.4));
14.
15. // create time varying function to drive the animation
16. Alpha rotationAlpha = new Alpha(-1, 4000);
17.
18. // Create a new Behavior object that performs the desired
19. // operation on the specified transform object and add it into
20. // the scene graph.
21. RotationInterpolator rotator =
22. new RotationInterpolator(rotationAlpha, objSpin);
23.
24. // a bounding sphere specifies a region a behavior is active
25. BoundingSphere bounds = new BoundingSphere();
26. rotator.setSchedulingBounds(bounds);
27. objSpin.addChild(rotator);
28.
29. return objRoot;
30. } // end of createSceneGraph method
Code Fragment 1-7 createSceneGraph method with RotationInterpolator Behavior
Code Fragment 1-7 is used with some previous code fragments to form the example program
HelloJava3Dc. HelloJava3Dc.java can be found in the examples/HelloJava3D/
directory and can be run as an application. The running application renders the ColorCube with the
behavior of rotating once every four seconds.
The HelloJava3Dc creates the scene graph shown in Figure 1-18. The rotation object is both a child of the
TransformGroup objSpin and has a reference to it. While this relationship appears to violate the no-cycles
restriction of the scene graph, it does not. Recall that reference arcs (dashed arrows) are not part of the
scene graph. The dashed line from the Behavior to the TransformGroup is that reference.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-30
BG
ColorCube
TG
B
View branch
graph
Figure 1-18 Scene Graph for HelloJava3Dc Example
The image in Figure 1-19 shows one frame of the spinning ColorCube from HelloJava3Dc.
Figure 1-19 An Image of the ColorCube in Rotation as Rendered by HelloJava3Dc
1.9.5 Transformation and Behavior Combination Example: HelloJava3Dd
Of course, you can combine behaviors with the rotation transforms of the previous examples. In
HelloJava3Dd.java this is done. In the content branch graph, there are objects named objRotate
and objSpin, which distinguish between the static rotation and the continuous spin (rotation behavior) of
the cube object respectively. The code is shown in Code Fragment 1-8. The resulting scene graph is in
Figure 1-20.
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-31
1. public BranchGroup createSceneGraph() {
2. // Create the root of the branch graph
3. BranchGroup objRoot = new BranchGroup();
4.
5. // rotate object has composite transformation matrix
6. Transform3D rotate = new Transform3D();
7. Transform3D tempRotate = new Transform3D();
8.
9. rotate.rotX(Math.PI/4.0d);
10. tempRotate.rotY(Math.PI/5.0d);
11. rotate.mul(tempRotate);
12.
13. TransformGroup objRotate = new TransformGroup(rotate);
14.
15. // Create the transform group node and initialize it to the
16. // identity. Enable the TRANSFORM_WRITE capability so that
17. // our behavior code can modify it at runtime. Add it to the
18. // root of the subgraph.
19. TransformGroup objSpin = new TransformGroup();
20. objSpin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
21.
22. objRoot.addChild(objRotate);
23. objRotate.addChild(objSpin);
24.
25. // Create a simple shape leaf node, add it to the scene graph.
26. // ColorCube is a Convenience Utility class
27. objSpin.addChild(new ColorCube(0.4));
28.
29. // Create a new Behavior object that performs the desired
30. // operation on the specified transform object and add it into
31. // the scene graph.
32. Transform3D yAxis = new Transform3D();
33. Alpha rotationAlpha = new Alpha(-1, 4000);
34.
35. RotationInterpolator rotator =
36. new RotationInterpolator(rotationAlpha, objSpin, yAxis,
37. 0.0f, (float) Math.PI*2.0f);
38.
39. // a bounding sphere specifies a region a behavior is active
40. // create a sphere centered at the origin with radius of 1
41. BoundingSphere bounds = new BoundingSphere();
42. rotator.setSchedulingBounds(bounds);
43. objSpin.addChild(rotator);
44.
45. return objRoot;
46. } // end of createSceneGraph method of HelloJava3Dd
Code Fragment 1-8 Content Branch for Rotated Spinning ColorCube of HelloJava3Dd
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-32
BG
ColorCube
TG
TG
B
View branch
graph
objRoot
objRotate
rotate objSpin
Figure 1-20 Scene Graph for HelloJava3Dd Example
The image in Figure 1-21 shows one frame of the spinning and rotated ColorCube from HelloJava3Dd.
Figure 1-21 An Image of the ColorCube in Rotation as Rendered by HelloJava3Dd
Getting Started with Java 3D Chapter 1. Getting Started
The Java 3D Tutorial 1-33
1.10 Chapter Summary
This chapter begins assuming the reader knows nothing about Java 3D. Through the course of the chapter
the reader is introduced to some of the most important classes in the Java 3D API. Explanation is given for
how these classes, and classes from other packages, are used to assemble a scene graph. The scene graph,
which describes a virtual universe, and how the view is to be rendered, is discussed in some detail. The
SimpleUniverse utility class is used to create a series of example programs that demonstrate the simplest
Java 3D program, a simple transformation, a combination of transformations, behavior, and combining
transformation and behavior. Later in the chapter come explanations of capabilities of objects and the
compiling of branch graphs.
1.11 Self Test
On this page are a few exercises intended to test and enhance your understanding of the material presented
in this chapter. The solutions to some of these exercises are given in Appendix C.
1. In the HelloJava3Db program, which combines two rotations in one TransformGroup, what would be the
difference if you reverse the order of the multiplication in the specification of the rotation? Alter the
program to see if your answer is correct. There are only two lines of code to change to accomplish this.
2. In the HelloJava3Dd program, what would be the difference if you reverse the order of the Transform
Nodes above the ColorCube in the content branch graph? Alter the program to see if your answer is
correct.
3. In search of performance improvements, a programmer might want to make the scene graph smaller
6
.
Can you combine the rotation and the spin target transform of HelloJava3Dd into one TransformGroup
object?
4. Translate the ColorCube 1 unit in the Y dimension and rotate the cube. You can use HelloJava3Db as a
starting point. The code that follows the question shows the specification of a translation transformation.
Try the transformation in the opposite order. Do you expect to see a difference in the results? If so, why?
If not, why not? Try it and compare your expectations to the actual results.
Transform3D translate = new Transform3D();
Vector3f vector = new Vector3f(0.0f, 1.0f, 0.0f);
translate.setTransform(vector);
5. In HelloJava3Dc, the bounding sphere has a radius of 1 meter. Is this value larger or smaller than it
needs to be? What is the smallest value that would guarantees the cube will be rotating if it is in view?
Experiment with the program to verify your answers. The following line of code can be used to specify a
bounding sphere. In this line, the Point3D object specifies the center, followed by the radius.
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
6. The example programs give sufficient information for assembling a virtual universe with multiple color
cubes. How do you construct such a scene graph? In what part of the code would this be accomplished?
6
Performance is directly related to scene graph size. The most effective change is to reduce the number of
Shape3D objects in a scene graph. Refer to the Java 3D performance whitepaper available at java.sun.com/docs.
tutorial v1.4 (Java 3D API v1.1.2)
Getting Started with
the Java 3D
API
Chapter 2
Creating Geometry
Dennis J Bouvier
K Computing
Getting Started with the Java 3D API Creating Geometry 2
The Java 3D Tutorial 2-i
Sun Microsystems, Inc.
2550 Garcia Avenue, Mountain View, California 94043-1100 U.S.A
All Rights Reserved.
The information contained in this document is subject to change without notice.
SUN MICROSYSTEMS PROVIDES THIS MATERIAL "AS IS" AND MAKES NO WARRANTY OF ANY
KIND, EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS SHALL
NOT BE LIABLE FOR ERRORS CONTAINED HEREIN OR FOR INCIDENTAL OR CONSEQUENTIAL
DAMAGES (INCLUDING LOST PROFITS IN CONNECTION WITH THE FURNISHING, PERFORMANCE
OR USE OF THIS MATERIAL, WHETHER BASED ON WARRANTY, CONTRACT, OR OTHER LEGAL
THEORY).
THIS DOCUMENT COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS.
CHANGES ARE PERIODICALLY MADE TO THE INFORMATION HEREIN; THESE CHANGES WILL BE
INCORPORATED IN NEW EDITIONS OF THE PUBLICATION. SUN MICROSYSTEMS, INC. MAY MAKE
IMPROVEMENTS AND/OR CHANGES IN THE PRODUCT(S) AND/OR PROGRAM(S) DESCRIBED IN THIS
PUBLICATION AT ANY TIME.
Some states do not allow the exclusion of implied warranties or the limitations or exclusion of liability for
incidental or consequential damages, so the above limitations and exclusion may not apply to you. This warranty
gives you specific legal rights, and you also may have other rights which vary from state to state.
Permission to use, copy, modify, and distribute this documentation for NON-COMMERCIAL purposes and
without fee is hereby granted provided that this copyright notice appears in all copies.
This documentation was prepared for Sun Microsystems by K Computing (530 Showers Drive, Suite 7-225,
Mountain View, CA 94040, 770-982-7881, www.kcomputing.com). For further information about course
development or course delivery, please contact either Sun Microsystems or K Computing.
Java, JavaScript, Java 3D, HotJava, Sun, Sun Microsystems, and the Sun logo are trademarks or registered
trademarks of Sun Microsystems, Inc. All other product names mentioned herein are the trademarks of their
respective owners.
Getting Started with the Java 3D API Creating Geometry 2
The Java 3D Tutorial 2-i
Chapter 2:
Creating Geometry................................................................................................................................2-1
2.1 Virtual World Coordinate System.............................................................................................2-1
2.2 Visual Object Definition Basics ................................................................................................2-2
2.2.1 An Instance of Shape3D Defines a Visual Object ........................................................................... 2-2
2.2.2 Node Components.......................................................................................................................... 2-4
2.2.3 Defining Visual Object Classes ...................................................................................................... 2-5
2.3 Geometric Utility Classes..........................................................................................................2-6
2.3.1 Box................................................................................................................................................ 2-7
2.3.2 Cone .............................................................................................................................................. 2-8
2.3.3 Cylinder......................................................................................................................................... 2-9
2.3.4 Sphere............................................................................................................................................ 2-9
2.3.5 More About Geometric Primitives................................................................................................ 2-10
2.3.6 ColorCube.................................................................................................................................... 2-10
2.3.7 Example: Creating a Simple Yo-Yo From Two Cones.................................................................. 2-11
Advanced Topic: Geometric Primitive .................................................................................................... 2-14
2.4 Mathematical Classes .............................................................................................................2-15
2.4.1 Point Classes................................................................................................................................ 2-18
2.4.2 Color Classes ............................................................................................................................... 2-19
2.4.3 Vector Classes.............................................................................................................................. 2-19
2.4.4 TexCoord Classes......................................................................................................................... 2-20
2.5 Geometry Classes ...................................................................................................................2-20
2.5.1 GeometryArray Class ................................................................................................................... 2-21
2.5.2 Subclasses of GeometryArray....................................................................................................... 2-25
2.5.3 Subclasses of GeometryStripArray................................................................................................ 2-27
2.5.4 Subclasses of IndexedGeometryArray........................................................................................... 2-31
2.5.5 Axis.java is an Example of IndexedGeometryArray...................................................................... 2-34
2.6 Appearance and Attributes......................................................................................................2-34
2.6.1 Appearance NodeComponent ....................................................................................................... 2-36
2.6.2 Sharing NodeComponent Objects................................................................................................. 2-36
2.6.3 Attribute Classes .......................................................................................................................... 2-37
2.6.4 Example: Back Face Culling........................................................................................................ 2-42
2.7 Self Test.................................................................................................................................2-44
Getting Started with the Java 3D API Creating Geometry 2
The Java 3D Tutorial 2-ii
List of Figures
Figure 2-1 Orientation of Axis in Virtual World ....................................................................................2-2
Figure 2-2 A Shape3D Object Defines a Visual Object in a Scene Graph. ..............................................2-3
Figure 2-3 Partial Java 3D API Class Hierarchy Showing Subclasses of NodeComponent......................2-5
Figure 2-4 Class Hierarchy for Utility Geometric Primitives: Box, Cone, Cylinder, and Sphere ..............2-7
Figure 2-5 Class Hierarchy of ColorCube Utility Geometric Class .......................................................2-11
Figure 2-6 Scene Graph for ConeYoyoApp..........................................................................................2-12
Figure 2-7 Multiple Parent Exception While Attempting to Reuse a Cone Object .................................2-13
Figure 2-8 An Image Rendered by ConeYoyoApp.java ........................................................................2-13
Figure 2-9 Mathematical Classes Package and Hierarchy.....................................................................2-16
Figure 2-10 Geometry Class Hierarchy................................................................................................2-21
Figure 2-11 Axis Class in AxisApp.java Creates this Scene Graph.......................................................2-25
Figure 2-12 Non-Indexed GeometryArray Subclasses ..........................................................................2-26
Figure 2-13 GeometryArray Subclasses...............................................................................................2-26
Figure 2-14 GeometryStripArray Subclasses .......................................................................................2-27
Figure 2-15 Three Views of the Yo-yo.................................................................................................2-28
Figure 2-16 Yo-yo with Colored Filled Polygons..................................................................................2-31
Figure 2-17 Index and Data Arrays for a Cube ....................................................................................2-32
Figure 2-18 IndexedGeometryArray Subclasses...................................................................................2-32
Figure 2-19 An Appearance Bundle.....................................................................................................2-35
Figure 2-20 Appearance Bundle Created by Code Fragment 2-9. .........................................................2-36
Figure 2-21 Multiple Appearance Objects Sharing a Node Component.................................................2-37
Figure 2-22 Twisted Strip with Back Face Culling...............................................................................2-42
Figure 2-23 Twisted Strip without Back Face Culling..........................................................................2-43
Figure 2-24 Determining the Front Face of Polygons and Strips ...........................................................2-44
List of Tables
Table 2-1 Attribute Defaults................................................................................................................2-42
List of Code Fragments
Code Fragment 2-1 Skeleton Code for a VisualObject Class ..................................................................2-6
Code Fragment 2-2 Class ConeYoyo From ConeYoyoApp.java Example Program...............................2-14
Code Fragment 2-3 Example ColorConstants Class .............................................................................2-19
Code Fragment 2-4 GeometryArray Constructors ................................................................................2-23
Code Fragment 2-5 Storing Data into a GeometryArray Object............................................................2-24
Code Fragment 2-6 GeometryArray Objects Referenced by Shape3D Objects ......................................2-25
Code Fragment 2-7 yoyoGeometry() Method Creates TriangleFanArray Object ...................................2-29
Code Fragment 2-9 Using Appearance and ColoringAttributes NodeComponent Objects......................2-35
Code Fragment 2-10 Disable Back Face Culling for the Twisted Strip .................................................2-43
Getting Started with the Java 3D API Creating Geometry 2
The Java 3D Tutorial 2-iii
List of Reference Blocks
Shape3D Constructors ..........................................................................................................................2-3
Shape3D Methods (partial list)..............................................................................................................2-3
Shape3D Capabilities............................................................................................................................2-4
Box Constructors (partial list) ...............................................................................................................2-8
Box, Cone, and Cylinder Methods .........................................................................................................2-8
Cone Constructors (partial list)..............................................................................................................2-9
Cylinder Constructors (partial list) ........................................................................................................2-9
Sphere Constructors (partial list) ...........................................................................................................2-9
Sphere Methods ..................................................................................................................................2-10
Primitive Methods (partial list) ............................................................................................................2-15
Tuple2f Constructors ..........................................................................................................................2-17
Tuple2f Methods (partial list)..............................................................................................................2-17
Point3f Methods (partial list)...............................................................................................................2-18
Color* Classes ....................................................................................................................................2-19
Vector3f Methods (partial list) ............................................................................................................2-20
GeometryArray Constructor ................................................................................................................2-22
GeometryArray Methods (partial list) ..................................................................................................2-23
GeometryArray Methods (partial list, continued) .................................................................................2-24
GeometryArray Subclass Constructors ................................................................................................2-26
GeometryStripArray Subclass Constructors.........................................................................................2-27
Triangulator Class ..............................................................................................................................2-28
Constructor Summary.........................................................................................................................2-28
Method Summary................................................................................................................................2-28
IndexedGeometryArray and Subclasses Constructors...........................................................................2-33
IndexedGeometryStripArray and Subclasses Constructors ...................................................................2-33
IndexedGeometryArray Methods (partial list) ......................................................................................2-34
Appearance Constructor......................................................................................................................2-36
Appearance Methods (excluding lighting and texturing) .......................................................................2-36
PointAttributes Constructors ...............................................................................................................2-37
PointAttributes Methods......................................................................................................................2-38
LineAttributes Constructors ................................................................................................................2-38
LineAttributes Methods.......................................................................................................................2-38
PolygonAttributes Constructors...........................................................................................................2-39
PolygonAttributes Methods .................................................................................................................2-39
ColoringAttributes Constructors..........................................................................................................2-39
ColoringAttributes Methods ................................................................................................................2-40
TransparencyAttributes Constructors ..................................................................................................2-40
TransparencyAttributes Methods.........................................................................................................2-40
RenderingAttributes Constructors........................................................................................................2-41
RenderingAttributes Methods ..............................................................................................................2-41
Getting Started with the Java 3D API Creating Geometry 2
The Java 3D Tutorial 2-iv
Preface to Chapter 2
This document is one part of a tutorial on using the Java 3D API. You should be familiar with Java 3D
API basics to fully appreciate the material presented in this Chapter. Additional chapters and the full
preface to this material is presented in the Module 0 document available at:
http://java.sun.com/products/java-media/3D/collateral
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-1
2
Creating Geometry
T(dx, dy, dz) =
1 0 0 dx
0 1 0 dy
0 0 1 dz
0 0 0 1
Chapter Objectives
After reading this chapter, youll be able to:
Use geometric primitive utility classes
Write classes to define visual objects
Specify geometry using core classes
Specify appearance for visual objects
hapter 1 explores the basic concepts of building a Java 3D virtual universe, concentrating on specifying
transforms and simple behaviors. The HelloJava3D examples in Chapter 1 use the ColorCube class for the
only visual object. With ColorCube, the programmer doesn't specify shape or color. The ColorCube class
is easy to use but can not be used to create other visual objects.
There are three major ways to create new geometric content. One way uses the geometric utility classes for
box, cone, cylinder, and sphere. Another way is for the programmer to specify the vertex coordinates for
points, line segments, and/or polygonal surfaces. A third way is to use a geometry loader. This chapter
demonstrates creating geometric content the first two ways.
The focus of this chapter is the creation of geometric content, that is, the shape of visual objects. A few
topics related to geometry are also covered, including math classes and appearance. Before describing how
to create geometric content, more information on the virtual universe coordinate system is presented in
section 2.1.
2.1 Virtual World Coordinate System
As discussed in Chapter 1, an instance of VirtualUniverse class serves as the root of the scene graph in all
Java 3D programs. The term virtual universe commonly refers to the three dimensional virtual space Java
3D objects populate. Each Locale object in the virtual universe establishes a virtual world Cartesian
coordinate system.
A Locale object serves as the reference point for visual objects in a virtual universe. With one Locale in a
SimpleUniverse, there is one coordinate system in the virtual universe.
CHAPTER
C
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-2
The coordinate system of the Java 3D virtual universe is right-handed. The x-axis is positive to the right,
y-axis is positive up, and z-axis is positive toward the viewer, with all units in meters. Figure 2-1 shows
the orientation with respect to the viewer in a SimpleUniverse.
image plate viewer position
y
z
x
Figure 2-1 Orientation of Axis in Virtual World
2.2 Visual Object Definition Basics
Section 2.2.1 presents the Shape3D class. A general discussion of the NodeComponent class follows in
section 2.2.2. After discussing geometry primitives defined in the utility package, the rest of the chapter
covers Geometry and Appearance node components.
2.2.1 An Instance of Shape3D Defines a Visual Object
A Shape3D scene graph node defines a visual object
1
. Shape3D is one of the subclasses of Leaf class;
therefore, Shape3D objects can only be leaves in the scene graph. The Shape3D object does not contain
information about the shape or color of a visual object. This information is stored in the NodeComponent
objects referred to by the Shape3D object. A Shape3D object can refer to one Geometry node component
and one Appearance node component.
In the HelloJava3D scene graphs in Chapter 1, the generic object symbol (rectangle) was used to represent
the ColorCube object. The simple scene graph in Figure 2-2 shows a visual object represented as a
Shape3D leaf (triangle) and two NodeComponents (ovals) instead of the generic rectangle
2
.
1
Shape3D objects define the most common visual objects of a virtual universe, but there are other ways.
2
This scene graph is not correct for a ColorCube object. ColorCube does not use an Appearance NodeComponent.
This is an example of a typical visual object.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-3
BG
Appearance Geometry
S
visual object
View branch graph
Figure 2-2 A Shape3D Object Defines a Visual Object in a Scene Graph.
A visual object can be defined using just a Shape3D object and a Geometry node component. Optionally,
the Shape3D object refers to an Appearance node component as well. The constructors for Shape3D
(presented in the next reference block) show that a Shape3D object can be created without node component
references, with just a Geometry node component reference, or with references to both types of node
components.
Shape3D Constructors
Shape3D()
Constructs and initializes a Shape3D object without geometry and appearance node components.
Shape3D(Geometry geometry)
Constructs and initializes a Shape3D object with the specified geometry and a null appearance component.
Shape3D(Geometry geometry, Appearance appearance)
Constructs and initializes a Shape3D object with the specified geometry and appearance components.
As long as the Shape3D object is not live and not compiled, the node component references can be changed
with the methods shown in the next reference block. These methods can be used on live or compiled
Shape3D objects if the capabilities to do so are set first. Another reference block below lists the Shape3D
capabilities. Be sure to read the "Reading Reference Blocks" section. It applies to many future reference
blocks.
Shape3D Methods (partial list)
A Shape3D object references Geometry and/or Appearance NodeComponent objects. Along with the set-
methods shown here, there are complementary get-methods.
void setGeometry(Geometry geometry)
void setAppearance(Appearance appearance)
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-4
Reading Reference Blocks
The reference blocks in this tutorial do not list all of the constructors, methods, and capabilities for each
Java 3D API class. For example, the Shape3D methods reference block (above) does not list all the
methods of the Shape3D class. Two of the methods not listed are the "get-methods" that match the "set-
methods" shown. That is, Shape3D has getGeometry() and getAppearance() methods. Each of
these methods returns a reference to the appropriate NodeComponent.
Since many Java 3D API classes have many methods, not all are listed. The ones listed in the reference
blocks in this tutorial are the ones that pertain to the tutorial topics. Also, many classes have get-methods
that match set-methods. The get-methods are not listed in the reference blocks in this tutorial to reduce the
length of the reference blocks.
The following reference block shows the capabilities of Shape3D objects. This reference block introduces a
shorthand notation for listing capabilities. Each line in the reference block lists two capabilities instead of
one. There is an ALLOW_GEOMETRY_READ and an ALLOW_GEOMETRY_WRITE capability in
each Shape3D object. Quite often there are read and write pairs of capabilities. To reduce the size of the
reference blocks, capability reference blocks list the matched read and write capability pairs together in the
short hand notation.
Consult the API specification for the complete list of constructors, methods, and capabilities.
Shape3D Capabilities
Shape3D objects inherit capabilities from SceneGraphObject, Node, and Leaf classes. They are not listed
here. Refer to section 1.8.2 for more information on Capabilities.
ALLOW_GEOMETRY_READ | WRITE
ALLOW_APPEARANCE_READ | WRITE
ALLOW_COLLISION_BOUNDS_READ | WRITE
2.2.2 Node Components
NodeComponent objects contain the exact specification of the attributes of a visual object. Each of the
several subclasses of NodeComponent defines certain visual attributes. Figure 2-3 shows part of the Java
3D API hierarchy containing the NodeComponent class and its descendants. Section 2.5 presents the
Geometry NodeComponent. Section 2.6 presents the Appearance NodeComponent.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-5
SceneGraphObject
NodeComponent
Geometry
Material
Node
Texture
Attributes*
Appearance
Group
Leaf
Background
Behavior
Fog
Light
Morph
Shape3D
Sound
ViewPlatform
*There are several attribute classes.
Figure 2-3 Partial Java 3D API Class Hierarchy Showing Subclasses of NodeComponent.
2.2.3 Defining Visual Object Classes
The same visual object will quite often appear many times in a single virtual universe. It makes sense to
define a class to create the visual object instead of constructing each visual object from scratch. There are
several ways to design a class to define a visual object.
Code Fragment 2-1 shows the skeleton code of VisualObject class as an example of one possible
organization for a generic visual object class. The methods are empty in the code. The code of
VisualObject does not appear in the examples distribution because is it not particularly useful as is.
1. public class VisualObject extends Shape3D{
2.
3. private Geometry voGeometry;
4. private Appearance voAppearance;
5.
6. // create Shape3D with geometry and appearance
7. // the geometry is created in method createGeometry
8. // the appearance is created in method createAppearance
9. public VisualObject() {
10.
11. voGeometry = createGeometry();
12. voAppearance = createAppearance();
13. this.setGeometry(voGeometry);
14. this.setAppearance(voAppearance);
15. }
16.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-6
17. private Geometry createGeometry() {
18. // code to create default geometry of visual object
19. }
20.
21. private Appearance createAppearance () {
22. // code to create default appearance of visual object
23. }
24.
25. } // end of class VisualObject
Code Fragment 2-1 Skeleton Code for a VisualObject Class
The organization of the VisualObject class in Code Fragment 2-1 is similar to the ColorCube utility class
in that it extends a Shape3D object. The VisualObject class is a suggested starting point for defining
custom content classes for use in scene graph construction. Each individual Java 3D programmer will
almost certainly customize the VisualObject class for their own purposes. For a complete example of this
class organization, read the source code for ColorCube class in the com.sun.j3d.utils.geometry
package, which is available with the Java 3D API distribution.
Using Shape3D as a base for creating a visual object class makes it easy to use in a Java 3D program. The
visual object class can be used as easily as the ColorCube class in the HelloJava3D examples from Chapter
1. The constructor can be called and the newly created object inserted as the child of some Group in one
line of code. In the following example line of code, objRoot is an instance of Group. This code creates a
VisualObject and adds it as a child of objRoot in the scene graph:
objRoot.addChild(new VisualObject());
The VisualObject constructor creates the VisualObject by creating a Shape3D object which references the
NodeComponents created by the methods createGeometry() and createAppearance(). The
method createGeometry() creates a Geometry NodeComponent to be used in the visual object. The
method createAppearance() is responsible for creating the NodeComponent that defines the
Appearance of the visual object.
Another possible organization for a visual object is to define a container class not derived from Java 3D
API classes. In this design, the visual object class would contain a Group Node or a Shape3D as the root
of the subgraph it defines. The class must define method(s) to return a reference to this root. This
technique is a little more work, but may be easier to understand. Some program examples presented later
in this chapter give examples of independent visual object class definitions.
A third possible organization for a visual object class is one similar to the classes Box, Cone, Cylinder, and
Sphere defined in the com.sun.j3d.utils.geometry package. Each class extends Primitive,
which extends Group. The design details of Primitive and its descendants are not discussed in this tutorial,
but the source code for all of these classes is available with the Java 3D API distribution. From the source
of Primitive class, and other utility classes, the reader can learn more about this class design approach.
2.3 Geometric Utility Classes
This section covers the utility classes for creating box, cone, cylinder, and sphere geometric primitives.
The geometric primitives are the second easiest way to create content in a virtual universe. The easiest way
is to use the ColorCube class.
The primitive classes provide the programmer with more flexibility than the ColorCube class provides. A
ColorCube object defines the geometry and color in a Geometry node component. Consequently,
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-7
everything about a ColorCube is fixed, except its size
3
. The size of a ColorCube is only specified when the
object is created.
A primitive object provides more flexibility by specifying shape without specifying color. In a geometric
primitive utility class, the programmer cannot change the geometry, but can change the appearance
4
. The
primitive classes give the programmer the flexibility to have multiple instances of the same geometric
primitive where each can have a different appearance by having a reference to different Appearance
NodeComponents.
The Box, Cone, Cylinder and Sphere utility classes are defined in the
com.sun.j3d.utils.geometry package. Details of the Box, Cone, Cylinder, and Sphere classes
are presented in Sections 2.3.1 through 2.3.4, respectively. The superclass of these primitives, Primitive, is
discussed in Section 2.3.5. The portion of the com.sun.j3d.utils.geometry package hierarchy
that contains the primitive classes is shown in Figure 2-4.
com.sun.j3d.utils.geometry.Primitive
com.sun.j3d.utils.geometry.Box
com.sun.j3d.utils.geometry.Cone
com.sun.j3d.utils.geometry.Cylinder
com.sun.j3d.utils.geometry.Sphere
java.lang.Object
javax.media.j3d.SceneGraphObject
javax.media.j3d.Node
javax.media.j3d.Group
Figure 2-4 Class Hierarchy for Utility Geometric Primitives: Box, Cone, Cylinder, and Sphere
2.3.1 Box
The Box geometric primitive creates 3D box visual objects
5
. The defaults for length, width, and height are
2 meters, with the center at the origin, resulting in a cube with corners at ( -1, -1, -1) and ( 1, 1, 1). The
3
The Geometry NodeComponent referenced by a ColorCube object can be changed, but then it wouldn't appear as
a ColorCube.
4
Just like with ColorCube, the Geometry NodeComponent referenced by a primitive object can be changed, but
then it wouldn't appear as the primitive.
5
Technically, a box is a six-sided polyhedron with rectangular faces.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-8
length, width, and height can be specified at object creation time. Of course, TransformGroup along the
scene graph path to a Box can be used to change the location and/or orientation of instances of Box and
other visual objects.
Box Constructors (partial list)
Package: com.sun.j3d.utils.geometry
Box extends Primitive, another class in the com.sun.j3d.utils.geometry package.
Box()
Constructs a default box of 2.0 meters in height, width, and depth, centered at the origin.
Box(float xdim, float ydim, float zdim, Appearance appearance)
Constructs a box of a given dimension and appearance, centered at the origin.
While the constructors differ by class, Box, Cone, and Cylinder classes share the same methods. The
following reference block lists the methods for these classes.
Box, Cone, and Cylinder Methods
Package: com.sun.j3d.utils.geometry
These methods are defined in each of the Primitive classes: Box, Cone, and Cylinder. These primitives are
composed of multiple Shape3D objects in a group.
Shape3D getShape(int id)
Gets one of the faces (Shape3D) from the primitive that contains the geometry and appearance. Box, Cone,
and Cylinder objects are composed of more than one Shape3D object, each with its own Geometry node
component. The value used for partid specifies which of the Geometry node components to get.
void setAppearance(Appearance appearance)
Sets appearance of the primitive (for all of the Shape3D objects).
2.3.2 Cone
The Cone class defines capped, cone shaped objects centered at the origin with the central axis aligned
along the y-axis. The default for radius is 1.0 and 2.0 for height. The center of the cone is defined to be the
center of its bounding box rather than its centroid.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-9
Cone Constructors (partial list)
Package: com.sun.j3d.utils.geometry
Cone extends Primitive, another class in the com.sun.j3d.utils.geometry package.
Cone()
Constructs a default Cone of radius of 1.0 and height of 2.0.
Cone(float radius, float height)
Constructs a default Cone of a given radius and height.
2.3.3 Cylinder
Cylinder class creates a capped, cylindrical object centered at the origin with its central axis aligned along
the y-axis. The default for radius is 1.0 and 2.0 for height.
Cylinder Constructors (partial list)
Package: com.sun.j3d.utils.geometry
Cylinder extends Primitive, another class in the com.sun.j3d.utils.geometry package.
Cylinder()
Constructs a default cylinder of radius of 1.0 and height of 2.0.
Cylinder(float radius, float height)
Constructs a cylinder of a given radius and height.
Cylinder(float radius, float height, Appearance appearance)
Constructs a cylinder of a given radius, height, and appearance.
2.3.4 Sphere
The Sphere class creates spherical visual objects centered at the origin. The default radius is 1.0.
Sphere Constructors (partial list)
Package: com.sun.j3d.utils.geometry
Sphere extends Primitive, another class in the com.sun.j3d.utils.geometry package.
Sphere()
Constructs a default Sphere of radius of 1.0.
Sphere(float radius)
Constructs a default Sphere of a given radius.
Sphere(float radius, Appearance appearance)
Constructs a Sphere of a given radius and a given appearance.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-10
Sphere Methods
Package: com.sun.j3d.utils.geometry
As an extention of Primitive, a Sphere is a Group object that has a single Shape3D child object.
Shape3D getShape()
Gets the Shape3D that contains the geometry and appearance.
Shape3D getShape(int id)
This method is included for compatibility with the other Primitive classes: Box, Cone, and Cylinder.
However, since a Sphere has only one Shape3D object, it can be called only with id = 1.
void setAppearance(Appearance appearance)
Sets appearance of the sphere.
2.3.5 More About Geometric Primitives
The geometry of a primitive utility class does not define color. Geometry that does not define color derives
its color from its Appearance node component. Without a reference to an Appearance node
component, the visual object will be white, the default appearance color. Color is first discussed in Section
2.4.2 and added to geometry in Section 2.5.1. Section 2.6 presents the details of Appearance node
components.
The Primitive class defines default values common to Box, Cone, Cylinder, and Sphere. For example,
Primitive defines the default value for the number of polygons used to represent surfaces. Section 2.3.8
presents some of the details of the Primitive class. Since the default values defined by Primitive are fine for
most applications, Java 3D programs can be written without even using the Primitive class. For this
reason, the section describing the Primitive class is considered an advanced topic (which can be skipped).
You will recognize advanced sections when you get there by the Duke figure hanging from the double-line
outline.
2.3.6 ColorCube
The ColorCube class is presented here to contrast with the geometric primitive classes of Box, Cone,
Cylinder, and Sphere. The ColorCube class extends a different hierarchy than the graphic primitive
classes. It is a subclass of Shape3D. This hierarchy for ColorCube is shown in Figure 2-5. Chapter 1
contains the reference blocks for ColorCube.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-11
javax.media.j3d.Shape3D
com.sun.j3d.utils.geometry.ColorCube
java.lang.Object
javax.media.j3d.SceneGraphObject
javax.media.j3d.Node
javax.media.j3d.Leaf
Figure 2-5 Class Hierarchy of ColorCube Utility Geometric Class
ColorCube is the only class distributed with the Java 3D API that allows a programmer to ignore the issues
of colors and lights. For this reason, ColorCube class is useful for quickly assembling scene graphs for
testing or prototyping.
2.3.7 Example: Creating a Simple Yo-Yo From Two Cones
This section presents a simple example that uses the Cone class: ConeYoyoApp.java. The goal of the
program is to render a yo-yo. Two cones are used to form the yo-yo. Java 3D API behaviors could be
used to make the yo-yo move up and down, but that is beyond the scope of this Chapter. The program
spins the yo-yo so the geometry can be appreciated. The scene graph diagram in Figure 2-5 shows the
designs for the ConeYoyo and ConeYoyoApp classes in the ConoYoyoApp example program.
The default position of a Cone object is with its bounding box centered at the origin. The default
orientation is with the tip of the Cone object in the direction of the positive y-axis. The yo-yo is formed of
two cones that are rotated about the z-axis and translated along the x-axis to bring the tips of the cones
together at the origin. Other combinations of rotation and translation transformations could bring the tips
of the Cone objects together.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-12
View branch graph
G
S
Geometry
S
Geometry
BG
Cone object
Appearance
G
S
Geometry
S
Geometry
TG TG
TG TG
BG
Cone object
ConeYoyo object
Figure 2-6 Scene Graph for ConeYoyoApp
6
In the branch graph that begins with the BranchGroup object created by the ConeYoyo object, the scene
graph path to each Cone object begins with the TransformGroup object that specifies the translation,
followed by the TransformGroup that specifies the rotation, and terminates at the Cone object.
Several scene graphs may represent the same virtual world. Taking the scene graph of Figure 2-6 as an
example, some obvious changes can be made. One change eliminates the BranchGroup object whose child
is the ConeYoyo object and inserts the ConeYoyo object directly in the Locale. The BranchGroup is there
to add future visual objects to the visual world. Another change combines the two TransformGroup objects
inside the ConeYoyo object. The transformations are shown this way simply as an example.
Shape3D nodes of the Cone objects reference Geometry node components. These are internal to the Cone
objects. The Shape3D objects of the Cone are children of a Group in the Cone. Since Cone objects
6
Actually, the Cone primitive is shared automatically as a feature of the Primitive class. This feature is discussed
in Section 2.3.8.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-13
descend from Group, the same Cone (or other Primitive object) can not be used more than once in a scene
graph. Figure 2-7 shows an example error message produced when attempting to use the same Cone object
in a single scene graph. This error does not exist in the example program distributed with this tutorial.
Exception in thread "main" javax.media.j3d.MultipleParentException:
Group.addChild: child already has a parent
at javax.media.j3d.GroupRetained.addChild(GroupRetained.java:246)
at javax.media.j3d.Group.addChild(Group.java:241)
at ConeYoyoApp$ConeYoyo.<init>(ConeYoyoApp.java:89)
at ConeYoyoApp.createSceneGraph(ConeYoyoApp.java:119)
at ConeYoyoApp.<init>(ConeYoyoApp.java:159)
at ConeYoyoApp.main(ConeYoyoApp.java:172)
Figure 2-7 Multiple Parent Exception While Attempting to Reuse a Cone Object
Figure 2-8 An Image Rendered by ConeYoyoApp.java
Figure 2-8 shows one of the possible images rendered by ConeYoyoApp.java as the ConeYoyo object
spins. ConeYoyoApp.java is found in the example/Geometry subdirectory. The ConeYoyo
class in the program is reproduced here in Code Fragment 2-2.
Lines 14 through 21 create the objects of one half of the yo-yo scene graph. Lines 23 through 25 create the
relationships among these objects. The process is repeated for the other half of the yo-yo on lines 27
through 38.
Line 12 creates yoyoAppear, an Appearance node component with default values, to be used by the
Cone objects. Lines 21 and 34 set the appearance for the two cones.
1. public class ConeYoyo{
2.
3. private BranchGroup yoyoBG;
4.
5. // create Shape3D with geometry and appearance
6. //
7. public ConeYoyo() {
8.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-14
9. yoyoBG = new BranchGroup();
10. Transform3D rotate = new Transform3D();
11. Transform3D translate = new Transform3D();
12. Appearance yoyoAppear = new Appearance();
13.
14. rotate.rotZ(Math.PI/2.0d);
15. TransformGroup yoyoTGR1 = new TransformGroup(rotate);
16.
17. translate.set(new Vector3f(0.1f, 0.0f, 0.0f));
18. TransformGroup yoyoTGT1 = new TransformGroup(translate);
19.
20. Cone cone1 = new Cone(0.6f, 0.2f);
21. cone1.setAppearance(yoyoAppear);
22.
23. yoyoBG.addChild(yoyoTGT1);
24. yoyoTGT1.addChild(yoyoTGR1);
25. yoyoTGR1.addChild(cone1);
26.
27. translate.set(new Vector3f(-0.1f, 0.0f, 0.0f));
28. TransformGroup yoyoTGT2 = new TransformGroup(translate);
29.
30. rotate.rotZ(-Math.PI/2.0d);
31. TransformGroup yoyoTGR2 = new TransformGroup(rotate);
32.
33. Cone cone2 = new Cone(0.6f, 0.2f);
34. cone2.setAppearance(yoyoAppear);
35.
36. yoyoBG.addChild(yoyoTGT2);
37. yoyoTGT2.addChild(yoyoTGR2);
38. yoyoTGR2.addChild(cone2);
39.
40. yoyoBG.compile();
41.
42. } // end of ConeYoyo constructor
43.
44. public BranchGroup getBG(){
45. return yoyoBG;
46. }
47.
48. } // end of class ConeYoyo
Code Fragment 2-2 Class ConeYoyo From ConeYoyoApp.java Example Program
2.3.8 Advanced Topic: Geometric Primitive
The class hierarchy of Figure 2-4 shows Primitive as the superclass of Box, Cone, Cylinder, and
Sphere classes. It defines a number of fields and methods common to these classes, as well as
default values for the fields.
The Primitive class provides a way to share Geometry node components among instances of a primitive of
the same size. By default, all primitives of the same size share one geometry node component. An example
of a field defined in the Primitive class is the GEOMETRY_NOT_SHARED integer. This field specifies
the geometry being created will not be shared by another. Set this flag to prevent the geometry from being
shared among primitives of the same parameters (e.g., spheres with radius 1).
myCone.setPrimitiveFlags(Primitive.GEOMETRY_NOT_SHARED);
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-15
Primitive Methods (partial list)
Package: com.sun.j3d.utils.geometry
Primitive extends Group and is the superclass for Box, Cone, Cylinder, and Sphere.
public void setNumVertices(int num)
Sets total number of vertices in this primitive.
void setPrimitiveFlags(int fl)
The primitive flags are:
GEOMETRY_NOT_SHARED Normals are generated along with the positions.
GENERATE_NORMALS_INWARD Normals are flipped along the surface.
GENERATE_TEXTURE_COORDS Texture coordinates are generated.
GEOMETRY_NOT_SHARED The geometry created will not be shared by another node.
void setAppearance(int partid, Appearance appearance)
Sets the appearance of a subpart given a partid. Box, Cone, and Cylinder objects are composed of more
than one Shape3D object, each potentially with its own Appearance node component. The value used for
partid specifies which of the Appearance node components to set.
void setAppearance()
Sets the main appearance of the primitive (all subparts) to a default white appearance.
Additional constructors for Box, Cone, Cylinder, and Sphere allow the specification of Primitive flags at
object creation time. Consult the Java 3D API specification for more information.
2.4 Mathematical Classes
To create visual objects, the Geometry class and its subclasses are required. Many Geometry subclasses
describe vertex-based primitives, such as points, lines, and filled polygons. The subclasses of Geometry
will be discussed in Section 2.5, but before that discussion, several mathematical classes (Point*, Color*,
Vector*, TexCoord*) used to specify vertex-related data need to be discussed
7
.
Note the asterisk used above is a wildcard to represent variations of class names. For example, Tuple*
refers to all Tuple classes: Tuple2f, Tuple2d, Tuple3b, Tuple3f, Tuple3d, Tuple4b, Tuple4f, and Tuple4d.
In each case the number indicates the number of elements in the tuple, and the letter indicates the data type
of the elements. f indicates single-precision floating point, d indicates double-precision floating point,
and b is for bytes. So Tuple3f is a class that manipulates three single-precision floating point values.
All these mathematical classes are in the javax.vecmath.* package. This package defines several
Tuple* classes as generic abstract superclasses. Other more useful classes are derived from the various
Tuple classes. The hierarchy for some of the package is shown in Figure 2-9.
7
TexCoord* classes are not used in Java 3D API version 1.1. This will change in subsequent versions.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-16
javax.vecmath
Tuple2f
Point2f
TexCoord2f
Vector2f
Tuple3f
Point3f
TexCoord3f
Vector3f
Color3f
Tuple4f
Point4f
Quat4f
Vector4f
Color4f
Tuple2d
Point2d
Vector2d
Tuple4d
Point4d
Vector4d
Quat4d
Tuple3b
Color3b
Tuple4b
Color4b
Tuple3d
Point3d
Vector3d
Figure 2-9 Mathematical Classes Package and Hierarchy
Each vertex of a visual object may specify up to four javax.vecmath objects, representing
coordinates, colors, surface normals, and texture coordinates. The following classes are commonly used:
Point* (for coordinates)
Color* (for colors)
Vector* (for surface normals)
TexCoord* (for texture coordinates)
Note that coordinates (Point* objects) are necessary to position each vertex. The other data is optional,
depending upon how the primitive is rendered. For instance, a color (a Color* object) may be defined at
each vertex and the colors of the primitive are interpolated between the colors at the vertices. If lighting is
enabled, surface normals (and therefore Vector* objects) are needed. If texture mapping is enabled, then
texture coordinates may be needed.
(The Quat* objects represent quaternions, which are only used for advanced 3D matrix transformations.)
Since all the useful classes inherit from the abstract Tuple* classes, its important to be familiar with the
Tuple constructors and methods, which are listed below.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-17
Tuple2f Constructors
Package: javax.vecmath
Tuple* classes are not typically used directly in Java 3D programs but provide the base for Point*, Color*,
Vector*, and TexCoord* classes. In particular, Tuple2f provides the base for Point2f, Color2f, and
TexCoord2f. The constructors listed here are available to these subclasses. Tuple3f and Tuple4f have
similar sets of constructors.
Tuple2f()
Constructs and initializes a Tuple object with the coordinates (0,0).
Tuple2f(float x, float y)
Constructs and initializes a Tuple object from the specified x, y coordinates.
Tuple2f(float[] t)
Constructs and initializes a Tuple object from the specified array.
Tuple2f(Tuple2f t)
Constructs and initializes a Tuple object from the data in another Tuple object.
Tuple2f(Tuple2d t)
Constructs and initializes a Tuple object from the data in another Tuple object.
Tuple2f Methods (partial list)
Package: javax.vecmath
Tuple* classes are not typically used directly in Java 3D programs but provide the base for Point*, Color*,
Vector*, and TexCoord* classes. In particular, Tuple2f provides the base for Point2f, Color2f, and
TexCoord2f. The methods listed here are available to these subclasses. Tuple3f and Tuple4f have similar
sets of methods.
void set(float x, float y)
void set(float[] t)
Sets the value of this tuple from the specified values.
boolean equals(Tuple2f t1)
Returns true if the data in the Tuple t1 are equal to the corresponding data in this tuple.
final void add(Tuple2f t1)
Sets the value of this tuple to the vector sum of itself and Tuple t1.
void add(Tuple2f t1, Tuple2f t2)
Sets the value of this tuple to the vector sum of tuples t1 and t2.
void sub(Tuple2f t1, Tuple2f t2)
Sets the value of this tuple to the vector difference of tuple t1 and t2 (this = t1 - t2).
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-18
void sub(Tuple2f t1)
Sets the value of this tuple to the vector difference of itself and tuple t1 (this = this - t1).
void negate()
Negates the value of this vector in place.
void negate(Tuple2f t1)
Sets the value of this tuple to the negation of tuple t1.
void absolute()
Sets each component of this tuple to its absolute value.
void absolute(Tuple2f t)
Sets each component of the tuple parameter to its absolute value, and places the modified values into this
tuple.
There are subtle, but predictable, differences among Tuple* constructors and methods, due to number and
data type. For example, Tuple3d differs from Tuple2f, because it has a constructor method:
Tuple3d(double x, double y, double z);
which expects three, not two, double-precision, not single-precision, floating point parameters.
Each of the Tuple* classes has public members. For Tuple2*, they are x and y. For Tuple3* the members
are x, y, and z. For Tuple4* the members are x, y, z, and w.
2.4.1 Point Classes
Point* objects usually represent coordinates of a vertex, although they can also represent the position of a
raster image, point light source, spatial location of a sound, or other positional data. The constructors for
Point* classes are similar to the Tuple* constructors, except they return Point* objects. (Some constructors
are passed parameters which are Point* objects, instead of Tuple* objects.)
Point3f Methods (partial list)
Package: javax.vecmath
The Point* classes are derived from Tuple* classes. Each instance of the Point* classes represents a single
point in two-, three-, or four-space. In addition to the Tuple* methods, Point* classes have additional
methods, some of which are listed here.
float distance(Point3f p1)
Returns the Euclidean distance between this point and point p1.
float distanceSquared(Point3f p1)
Returns the square of the Euclidean distance between this point and point p1.
float distanceL1(Point3f p1)
Returns the L
1
(Manhattan) distance between this point and point p1. The L
1
distance is equal to:
abs(x
1
- x
2
) + abs(y
1
- y
2
) + abs(z
1
- z
2
)
Once again, there are subtle, predictable differences among Point* constructors and methods, due to
number and data type. For example, for Point3d, the distance method returns a double-precision floating
point value.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-19
2.4.2 Color Classes
Color* objects represent a color, which can be for a vertex, material property, fog, or other visual object.
Colors are specified either as Color3* or Color4*, and only for byte or single-precision floating point data
types. Color3* objects specify a color as a combination of red, green, and blue (RGB) values. Color4*
objects specify a transparency value, in addition to RGB. (By default, Color3* objects are opaque.) For
byte-sized data types, color values range between 0 and 255, inclusive. For single-precision floating point
data, color values range between 0.0 and 1.0, inclusive.
Once again, the constructors for Color* classes are similar to the Tuple* constructors, except they return
Color* objects. (Some constructors are passed parameters which are Color* objects.) The Color* classes
do not have additional methods, so they rely upon the methods they inherit from their Tuple* superclasses.
It is sometimes convenient to create constants for colors that are used repetitiously in the creation of visual
object. For example,
Color3f red = new Color3f(1.0f, 0.0f, 0.0f);
instantiates the Color3f object red that may be used multiple times. It may be helpful to create a class that
contains a number of color constants. An example of such a class appears in Code Fragment 2-1.
1. import javax.vecmath.*;
2.
3. class ColorConstants{
4. public static final Color3f red = new Color3f(1.0f,0.0f,0.0f);
5. public static final Color3f green = new Color3f(0.0f,1.0f,0.0f);
6. public static final Color3f blue = new Color3f(0.0f,0.0f,1.0f);
7. public static final Color3f yellow = new Color3f(1.0f,1.0f,0.0f);
8. public static final Color3f cyan = new Color3f(0.0f,1.0f,1.0f);
9. public static final Color3f magenta = new Color3f(1.0f,0.0f,1.0f);
10. public static final Color3f white = new Color3f(1.0f,1.0f,1.0f);
11. public static final Color3f black = new Color3f(0.0f,0.0f,0.0f);
12. }
Code Fragment 2-3 Example ColorConstants Class
Color* Classes
Package: javax.vecmath
The Color* classes are derived from Tuple* classes. Each instances of the Color* classes represents a
single color in three components (RGB), or four components (RGBA). The Color* classes do not add any
methods to those supplied by Tuple* classes.
2.4.3 Vector Classes
Vector* objects often represent surface normals at vertices although they can also represent the direction of
a light source or sound source. Again, the constructors for Vector* classes are similar to the Tuple*
constructors. However, Vector* objects add many methods that are not found in the Tuple* classes.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-20
Vector3f Methods (partial list)
Package: javax.vecmath
The Vector* classes are derived from Tuple* classes. Each instances of the Vector* classes represents a
single vector in two-, three-, or four-space. In addition to the Tuple* methods, Vector* classes have
additional methods, some of which are listed here.
float length()
Returns the length of this vector.
float lengthSquared()
Returns the squared length of this vector.
void cross(Vector3f v1, Vector3f v2)
Sets this vector to be the vector cross product of vectors v1 and v2.
float dot(Vector3f v1)
Computer and return the dot product of this vector and vector v1.
void normalize()
Normalizes this vector.
void normalize(Vector3f v1)
Sets the value of this vector to the normalization of vector v1.
float angle(Vector3f v1)
Returns the angle in radians between this vector and the vector parameter; the return value is constrained to
the range [0,PI].
And yes, there are subtle, predictable differences among Vector* constructors and methods, due to number
or data type.
2.4.4 TexCoord Classes
There are only two TexCoord* classes which can be used to represent a set of texture coordinates at a
vertex: TexCoord2f and TexCoord3f. TexCoord2f maintains texture coordinates as an (s, t) coordinate
pair; TexCoord3f as an (s, t, r) triple.
The constructors for TexCoord* classes are again similar to the Tuple* constructors. Like the Color*
classes, the TexCoord* classes also do not have additional methods, so they rely upon the methods they
inherit from their Tuple* superclasses.
2.5 Geometry Classes
In 3D computer graphics, everything from the simplest triangle to the most complicated jumbo jet model is
modeled and rendered with vertex-based data. With Java 3D, each Shape3D object should call its method
setGeometry() to reference one and only one Geometry object. To be more precise, Geometry is an
abstract superclass, so the referenced object is an instance of a subclass of Geometry.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-21
Subclasses of Geometry fall into three broad categories:
Non-indexed vertex-based geometry (each time a visual object is rendered, its vertices may be used
only once)
Indexed vertex-based geometry (each time a visual object is rendered, its vertices may be reused)
Other visual objects (the classes Raster, Text3D, and CompressedGeometry)
This section covers the first two aforementioned categories. The class hierarchy for Geometry classes
and subclasses is shown in Figure 2-10 Geometry Class Hierarchy
.
SceneGraphObject
IndexedGeometryArray
TriangleArray
QuadArray
PointArray
LineArray
GeometryStripArray
Geometry
GeometryArray
CompressedGeometry
Raster
Text3D
TriangleStripArray
LineStripArray
TriangleFanArray
IndexedLineArray
IndexedPointArray
IndexedQuadArray
IndexedTriangleArray
IndexedGeometryStripArray
NodeComponent
IndexedLineStripArray
IndexedTriangleStripArray
IndexedTriangleFanArray
Figure 2-10 Geometry Class Hierarchy
2.5.1 GeometryArray Class
As you may deduce from the class names, the Geometry subclasses may be used to specify points, lines,
and filled polygons (triangles and quadrilaterals). These vertex-based primitives are subclasses of the
GeometryArray abstract class, which indicates that each has arrays that maintain data per vertex.
For example, if a GeometryArray object is used to specify one triangle, a three-element array is defined:
one element for each vertex. Each element of this array maintains the coordinate location for its vertex
(which can be defined with a Point* object or similar data). In addition to the coordinate location, three
more arrays may be optionally defined to store color, surface normal, and texture coordinate data. These
arrays, containing the coordinates, colors, surface normals, and texture coordinates, are the data arrays.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-22
There are three steps in the life of a GeometryArray object:
1. Construction of an empty object.
2. Filling the object with data.
3. Associating (referencing) the object from (one or more) Shape3D objects.
Step 1: Construction of an Empty GeometryArray Object
When a GeometryArray object is initially constructed, two things must be defined:
the number of vertices (array elements) to be needed.
the type of data (coordinate location, color, surface normal, and/or texture coordinate) to be stored at
each vertex. This is called the vertex format.
There is only one GeometryArray constructor method:
GeometryArray Constructor
GeometryArray(int vertexCount, int vertexFormat)
Constructs an empty GeometryArray object with the specified number of vertices, and vertex format. One
or more individual flags are bitwise "OR"ed together to describe the per-vertex data. The flag constants
used for specifying the format are:
COORDINATES: Specifies this vertex array contains coordinates. This bit must be set.
NORMALS: Specifies this vertex array contains surface normals.
COLOR_3: Specifies this vertex array contains colors without transparency.
COLOR_4: Specifies this vertex array contains colors with transparency.
TEXTURE_COORDINATE_2: Specifies this vertex array contains 2D texture coordinates.
TEXTURE_COORDINATE_3: Specifies this vertex array contains 3D texture coordinates.
For each vertex format flags set, there is a corresponding array created internal to the GeometryArray
object. Each of these arrays is vertexCount in size.
Lets see how this constructor works, but first recall that GeometryArray is an abstract class. Therefore,
you actually call the constructor for one of GeometryArrays subclasses, for instance, LineArray. (A
LineArray object describes a set of vertices, and each two vertices defines the endpoints of a line. The
constructor and other methods of LineArray are very similar to its superclass GeometryArray. LineArray is
explained in more detail in Section 2.5.2.)
Code Fragment 2-4 shows the Axis class from the program examples/Geometry/AxisApp.java
which uses multiple LineArray objects to draw lines to represent the x, y, and z axes. The X axis object
creates an object with two vertices (to draw one line between them), with only coordinate location data. The
Y axis object also has two vertices, but allows for RGB color, as well as coordinate location, at each
vertex. Therefore, the Y axis line may be drawn with colors interpolated from one vertex to the other.
Finally, the Z axis has ten vertices with coordinate and color data at each vertex. Five color-interpolated
lines may be drawn, one line between each pair of vertices. Note the use of the bitwise OR operation for
the vertex format of both the Y and Z axes.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-23
1. // construct object to represent the X axis
2. LineArray axisXLines= new LineArray (2, LineArray.COORDINATES);
3.
4. // construct object to represent the Y axis
5. LineArray axisYLines = new LineArray(2, LineArray.COORDINATES
6. | LineArray.COLOR_3);
7.
8. // construct object to represent the Z axis
9. LineArray axisZLines = new LineArray(10, LineArray.COORDINATES
10. | LineArray.COLOR_3);
Code Fragment 2-4 GeometryArray Constructors
Be careful! The Axis class in AxisApp.java is different from the Axis class defined in
examples/geometry/Axis.java, which uses only one LineArray object. Make sure you have the
right one. The Axis class defined in Axis.java is intended for use in your programs, where
AxisApp.java is the demonstration program for this tutorial. Also, the Axis class defined in Axis.java
demonstrates creating a visual object class that extends Shape3D.
Step 2: Fill the GeometryArray Object with Data
After constructing the GeometryArray object, assign values to the arrays, corresponding to the assigned
vertex format. This may be done per vertex, or by using an array to assign data to many vertices with one
method call. The available methods are:
GeometryArray Methods (partial list)
GeometryArray is the superclass for PointArray, LineArray, TriangleArray, QuadArray,
GeometryStripArray, and IndexedGeometryArray.
void setCoordinate(int index, float[] coordinate)
void setCoordinate(int index, double[] coordinate)
void setCoordinate(int index, Point* coordinate)
Sets the coordinate associated with the vertex at the specified index for this object.
void setCoordinates(int index, float[] coordinates)
void setCoordinates(int index, double[] coordinates)
void setCoordinates(int index, Point*[] coordinates)
Sets the coordinates associated with the vertices starting at the specified index for this object.
void setColor(int index, float[] color)
void setColor(int index, byte[] color)
void setColor(int index, Color* color)
Sets the color associated with the vertex at the specified index for this object.
void setColors(int index, float[] colors)
void setColors(int index, byte[] colors)
void setColors(int index, Color*[] colors)
Sets the colors associated with the vertices starting at the specified index for this object.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-24
GeometryArray Methods (partial list, continued)
void setNormal(int index, float[] normal)
void setNormal(int index, Vector* normal)
Sets the normal associated with the vertex at the specified index for this object.
void setNormals(int index, float[] normals)
void setNormals(int index, Vector*[] normals)
Sets the normals associated with the vertices starting at the specified index for this object.
void setTextureCoordinate(int index, float[] texCoord)
void setTextureCoordinate(int index, Point* coordinate)
Sets the texture coordinate associated with the vertex at the specified index for this object.
void setTextureCoordinates(int index, float[] texCoords)
void setTextureCoordinates(int index, Point*[] texCoords)
Sets the texture coordinates associated with the vertices starting at the specified index for this object.
Code Fragment 2-5 shows use of the GeometryArray methods to store coordinate and color values in the
LineArray objects. The X axis object calls only the method setCoordinate() to store coordinate location
data. The Y axis object calls both setColor() and setCoordinate() to load RGB color and coordinate
location values. And the Z axis object calls setCoordinate() ten times for each individual vertex and
setColors() once to load all ten vertices with one method call.
1. axisXLines.setCoordinate(0, new Point3f(-1.0f, 0.0f, 0.0f));
2. axisXLines.setCoordinate(1, new Point3f( 1.0f, 0.0f, 0.0f));
3.
4. Color3f red = new Color3f(1.0f, 0.0f, 0.0f);
5. Color3f green = new Color3f(0.0f, 1.0f, 0.0f);
6. Color3f blue = new Color3f(0.0f, 0.0f, 1.0f);
7. axisYLines.setCoordinate(0, new Point3f( 0.0f,-1.0f, 0.0f));
8. axisYLines.setCoordinate(1, new Point3f( 0.0f, 1.0f, 0.0f));
9. axisYLines.setColor(0, green);
10. axisYLines.setColor(1, blue);
11.
12. axisZLines.setCoordinate(0, z1);
13. axisZLines.setCoordinate(1, z2);
14. axisZLines.setCoordinate(2, z2);
15. axisZLines.setCoordinate(3, new Point3f( 0.1f, 0.1f, 0.9f));
16. axisZLines.setCoordinate(4, z2);
17. axisZLines.setCoordinate(5, new Point3f(-0.1f, 0.1f, 0.9f));
18. axisZLines.setCoordinate(6, z2);
19. axisZLines.setCoordinate(7, new Point3f( 0.1f,-0.1f, 0.9f));
20. axisZLines.setCoordinate(8, z2);
21. axisZLines.setCoordinate(9, new Point3f(-0.1f,-0.1f, 0.9f));
22.
23. Color3f colors[] = new Color3f[9];
24. colors[0] = new Color3f(0.0f, 1.0f, 1.0f);
25. for(int v = 0; v < 9; v++)
26. colors[v] = red;
27. axisZLines.setColors(1, colors);
Code Fragment 2-5 Storing Data into a GeometryArray Object
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-25
The default color for vertices of a GeometryArray object is white, unless either COLOR_3 or COLOR_4 is
specified in the vertex format. When either COLOR_3 or COLOR_4 is specified, the default vertex color
is black. When lines or filled polygons are rendered with different colors at the vertices, the color is
smoothly shaded (interpolated) between vertices using Gouraud shading.
Step 3: Make Shape3D Objects Reference the GeometryArray Objects
Finally, Code Fragment 2-6 shows how the GeometryArray objects are referenced by newly created
Shape3D objects. In turn, the Shape3D objects are added to a BranchGroup, which is added elsewhere to
the overall scene graph. (Unlike GeometryArray objects, which are NodeComponents, Shape3D is a
subclass of Node, so Shape3D objects may be added as children to a scene graph.)
1. axisBG = new BranchGroup();
2.
3. axisBG.addChild(new Shape3D(axisYLines));
4. axisBG.addChild(new Shape3D(axisZLines));
Code Fragment 2-6 GeometryArray Objects Referenced by Shape3D Objects
Figure 2-11 shows the partial scene graph created by the Axis class in AxisApp.java.
BG
S
Geometry
S
Geometry Geometry
axisZLines
S
axisXLines axisYLines
axisBG
Figure 2-11 Axis Class in AxisApp.java Creates this Scene Graph
2.5.2 Subclasses of GeometryArray
As was discussed in the previous section, the GeometryArray class is an abstract superclass for more
useful subclasses, such as LineArray. Figure 2-12 shows the class hierarchy for GeometryArray and some
of its subclasses. The main distinction among these subclasses is how the Java 3D renderer decides to
render their vertices.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-26
TriangleArray
QuadArray
PointArray
LineArray
GeometryStripArray
Geometry
GeometryArray
TriangleStripArray
LineStripArray
TriangleFanArray
Figure 2-12 Non-Indexed GeometryArray Subclasses
Figure 2-13 shows examples of the four GeometryArray subclasses: PointArray, LineArray,
TriangleArray, and QuadArray (the ones which are not also subclasses of GeometryStripArray). In this
figure, the three leftmost sets of vertices show the same six vertex points rendering six points, three lines, or
two triangles. The fourth image shows four vertices defining a quadrilateral. Note that none of the vertices
are shared: each line or filled polygon is rendered independently of any other.
v0 v2 v4
v1 v3 v5
PointArray
v0 v3
v1 v2
QuadArray
v0 v2 v4
v1 v3 v5
LineArray
v0 v2 v4
v1 v3 v5
TriangleArray
Figure 2-13 GeometryArray Subclasses
By default, the interiors of triangles and quadrilaterals are filled. In later sections, you will learn that
attributes can influence how filled primitives can be rendered in different ways.
These four subclasses inherit their constructors and methods from GeometryArray. Their constructors are
listed below. For their methods, go back to the listing entitled GeometryArray Methods.
GeometryArray Subclass Constructors
Constructs an empty object with the specified number of vertices and the vertex format. The format is one
or more individual flags bitwise "OR"ed together to describe the per-vertex data. The format flags are the
same as defined in the GeometryArray superclass.
PointArray(int vertexCount, int vertexFormat)
LineArray(int vertexCount, int vertexFormat)
TriangleArray(int vertexCount, int vertexFormat)
QuadArray(int vertexCount, int vertexFormat)
To see the use of these constructors and methods, go back to Code Fragment 2-4, Code Fragment 2-5, and
Code Fragment 2-6, which use a LineArray object.
If you are rendering quadrilaterals, be careful that the vertices do not create concave, self-intersecting, or
non-planar geometry. If they do, they may not be rendered properly.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-27
2.5.3 Subclasses of GeometryStripArray
The previously described four subclasses of GeometryArray do not allow for any reuse of vertices. Some
geometric configurations invite the reuse of vertices, so specialized classes may result in better rendering
performance.
The GeometryStripArray is an abstract class from which strip primitives (for creating compound lines and
surfaces) are derived. GeometryStripArray is the superclass of LineStripArray, TriangleStripArray, and
TriangleFanArray. Figure 2-14 shows an instance of each type of strip and how vertices are reused. The
LineStripArray renders connected lines. The TriangleStripArray results in triangles that share an edge,
reusing the most recently rendered vertex. The TriangleFanArray reuses the very first vertex in its strip for
each triangle.
v0 v2 v4
v1 v3 v5
TriangleStripArray
v0
v1 v2 v3 v4
TriangleFanArray
v0 v2 v4
v1 v3 v5
LineStripArray
Figure 2-14 GeometryStripArray Subclasses
The GeometryStripArray has a different constructor than GeometryArray. The GeometryStripArray
constructor has a third parameter, which is an array of vertex counts per strip, enabling a single object to
maintain multiple strips. (GeometryStripArray also introduces a couple of querying methods,
getNumStrips() and getStripVertexCounts(), which are infrequently used.)
GeometryStripArray Subclass Constructors
Constructs an empty object with the specified number of vertices, the vertex format, and an array of vertex
counts per strip. The format is one or more individual flags bitwise "OR"ed together to describe the per-
vertex data. The format flags are the same as defined in the GeometryArray superclass. Multiple strips are
supported. The sum of the vertex counts for all strips (from the stripVertexCounts array) must equal the
total count of all vertices (vtxCount).
LineStripArray(int vtxCount, int vertexFormat, int stripVertexCounts[])
TriangleStripArray(int vtxCount, int vertexFormat, int stripVertexCounts[]))
TriangleFanArray(int vtxCount, int vertexFormat, int stripVertexCounts[]))
Note that Java 3D does not support filled primitives with more than four sides. The programmer is
responsible for using tessellators to break down more complex polygons into Java 3D objects, such as
triangle strips or fans. The Triangulator utility class converts complex polygons into triangles
8
.
8
The Triangulator class and related classes are explained in more detail in Chapter 3.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-28
Triangulator Class
Package: com.sun.j3d.utils.geometry
Used for converting non-triangular polygon geometry into triangles for rendering by Java 3D. Polygons
can be concave, nonplanar, and can contain holes (see GeometryInfo.setContourCounts()). Nonplanar
polygons are projected onto the nearest plane. NOTE: See the current class documentation for limitations.
See Section 3.3 of this tutorial for more information.
Constructor Summary
Triangulator()
Create a Triangulator object.
Method Summary
void triangulate(GeometryInfo ginfo)
This routine converts the GeometryInfo object from primitive type POLYGON_ARRAY to primitive type
TRIANGLE_ARRAY using polygon decomposition techniques.
Parameters:
ginfo - com.sun.j3d.utils.geometry.GeometryInfo to be triangulated.
Example of usage:
Triangulator tr = new Triangulator();
tr.triangulate(ginfo); // ginfo contains the geometry
shape.setGeometry(ginfo.getGeometryArray()); // shape is a Shape3D
Yo-yo Code Demonstrates TriangleFanArray
The Yoyo object in the YoyoApp.java program shows how to use a TriangleFanArray object to model
the geometry of a yo-yo. The TriangleFanArray contains four independent fans: two exterior faces (circular
disks) and two internal faces (cones). Only one TriangleFanArray object is needed to represent the four
fans.
Figure 2-15 shows three renderings of the TriangleFanArray. The first view shows its default rendering, as
white, filled polygons. However, its hard to see detail, especially the location of the vertices. To show the
triangles better, the other two views show the TriangleFanArray with its vertices connected with lines. To
render what would be filled polygons as lines, see the class PolygonAttributes in Section 2.6.
Figure 2-15 Three Views of the Yo-yo
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-29
In Code Fragment 2-7, the method yoyoGeometry() creates and returns the desired TriangleFanArray.
Lines 15-18 calculates the central points for all four fans. Each fan has 18 vertices, which are calculated in
lines 20-28. Lines 30-32 construct the empty TriangleFanArray object, and then line 34 is where the
previously calculated coordinate data (from lines 15-28) is stored into the object.
1. private Geometry yoyoGeometry() {
2.
3. TriangleFanArray tfa;
4. int N = 17;
5. int totalN = 4*(N+1);
6. Point3f coords[] = new Point3f[totalN];
7. int stripCounts[] = {N+1, N+1, N+1, N+1};
8. float r = 0.6f;
9. float w = 0.4f;
10. int n;
11. double a;
12. float x, y;
13.
14. // set the central points for four triangle fan strips
15. coords[0*(N+1)] = new Point3f(0.0f, 0.0f, w);
16. coords[1*(N+1)] = new Point3f(0.0f, 0.0f, 0.0f);
17. coords[2*(N+1)] = new Point3f(0.0f, 0.0f, 0.0f);
18. coords[3*(N+1)] = new Point3f(0.0f, 0.0f, -w);
19.
20. for (a = 0,n = 0; n < N; a = 2.0*Math.PI/(N-1) * ++n){
21. x = (float) (r * Math.cos(a));
22. y = (float) (r * Math.sin(a));
23.
24. coords[0*(N+1)+N-n] = new Point3f(x, y, w);
25. coords[1*(N+1)+n+1] = new Point3f(x, y, w);
26. coords[2*(N+1)+N-n] = new Point3f(x, y, -w);
27. coords[3*(N+1)+n+1] = new Point3f(x, y, -w);
28. }
29.
30. tfa = new TriangleFanArray (totalN,
31. TriangleFanArray.COORDINATES,
32. stripCounts);
33.
34. tfa.setCoordinates(0, coords);
35.
36. return tfa;
37.} // end of method yoyoGeometry in class Yoyo
Code Fragment 2-7 yoyoGeometry() Method Creates TriangleFanArray Object
The all white yo-yo is just a starting point. Figure 2-16 shows a similar object, modified to include colors at
each vertex. The modified yoyoGeometry() method, which includes colors in the TriangleFanArray
object, is shown in Code Fragment 2-8. Lines 23 through 26, 36 through 39, and line 46 specify color
values for each vertex.
More possibilities exist for specifying the appearance of a visual object through the use of lights, textures,
and material properties of a visual object. These topics are not covered in this tutorial module. Lights and
textures are the topics of tutorial module 2.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-30
1. private Geometry yoyoGeometry() {
2.
3. TriangleFanArray tfa;
4. int N = 17;
5. int totalN = 4*(N+1);
6. Point3f coords[] = new Point3f[totalN];
7. Color3f colors[] = new Color3f[totalN];
8. Color3f red = new Color3f(1.0f, 0.0f, 0.0f);
9. Color3f yellow = new Color3f(0.7f, 0.5f, 0.0f);
10. int stripCounts[] = {N+1, N+1, N+1, N+1};
11. float r = 0.6f;
12. float w = 0.4f;
13. int n;
14. double a;
15. float x, y;
16.
17. // set the central points for four triangle fan strips
18. coords[0*(N+1)] = new Point3f(0.0f, 0.0f, w);
19. coords[1*(N+1)] = new Point3f(0.0f, 0.0f, 0.0f);
20. coords[2*(N+1)] = new Point3f(0.0f, 0.0f, 0.0f);
21. coords[3*(N+1)] = new Point3f(0.0f, 0.0f, -w);
22.
23. colors[0*(N+1)] = red;
24. colors[1*(N+1)] = yellow;
25. colors[2*(N+1)] = yellow;
26. colors[3*(N+1)] = red;
27.
28. for(a = 0,n = 0; n < N; a = 2.0*Math.PI/(N-1) * ++n){
29. x = (float) (r * Math.cos(a));
30. y = (float) (r * Math.sin(a));
31. coords[0*(N+1)+n+1] = new Point3f(x, y, w);
32. coords[1*(N+1)+N-n] = new Point3f(x, y, w);
33. coords[2*(N+1)+n+1] = new Point3f(x, y, -w);
34. coords[3*(N+1)+N-n] = new Point3f(x, y, -w);
35.
36. colors[0*(N+1)+N-n] = red;
37. colors[1*(N+1)+n+1] = yellow;
38. colors[2*(N+1)+N-n] = yellow;
39. colors[3*(N+1)+n+1] = red;
40. }
41. tfa = new TriangleFanArray (totalN,
42. TriangleFanArray.COORDINATES|TriangleFanArray.COLOR_3,
43. stripCounts);
44.
45. tfa.setCoordinates(0, coords);
46. tfa.setColors(0,colors);
47.
48. return tfa;
49. } // end of method yoyoGeometry in class Yoyo
Code Fragment 2-8 Modified yoyoGeometry() Method with Added Colors
The observant reader will notice the differences in lines 36 through 39. The code is written to make the
front face of each triangle in the geometry the outside of the yo-yo. The discussion of front and back
triangle faces, and why it makes a difference is in Section 2.6.4.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-31
Figure 2-16 Yo-yo with Colored Filled Polygons
2.5.4 Subclasses of IndexedGeometryArray
The previously described subclasses of GeometryArray declare vertices wastefully. Only the
GeometryStripArray subclasses have even limited reuse of vertices. Many geometric objects invite reuse of
vertices. For example, to define a cube, each of its eight vertices is used by three different squares. In a
worse case, a cube requires specifying 24 vertices, even though only eight unique vertices are needed (16 of
the 24 are redundant).
IndexedGeometryArray objects provide an extra level of indirection, so redundant vertices may be avoided.
Arrays of vertex-based information must still be provided, but the vertices may be stored in any order, and
any vertex may be reused during rendering. We call these arrays, containing the coordinates, colors,
surface normals, and texture coordinates, the data arrays.
However, IndexedGeometryArray objects also need additional arrays (index arrays) that contain indices
into the data arrays. There are up to four index arrays: coordinate indices, color indices, surface
normal indices, and texture coordinate indices, which corresponds to the data arrays. The number of
index arrays is always the same as the number of data arrays. The number of elements in each index array
is the same and typically larger than the number of elements in each data array.
The index arrays may have multiple references to the same vertex in the data arrays. The values in
these index arrays determine the order in which the vertex data is accessed during rendering. Figure 2-17
shows the relationships between index and data coordinate arrays for a cube as an example.
It is worth mentioning that there is a price to pay for the reuse of vertices provided by indexed geometry
you pay for it in performance. The indexing of geometry at render time adds more work to the rendering
process. If performance is an issue, use strips whenever possible and avoid indexed geometry. Indexed
geometry is useful when speed is not critical and there is some memory to be gained through indexing, or
when indexing provides programming convenience.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-32
(-1, 1, -1)
(-1, -1, -1)
(1, -1, -1)
(1, 1, -1)
(-1, 1, 1)
(-1, -1, 1)
(1, -1, 1)
(1, 1, 1)
coordinate data array
coordinate
index array
front face
top face
back face
Figure 2-17 Index and Data Arrays for a Cube
Subclasses of IndexedGeometryArray parallel the subclasses of GeometryArray. The class hierarchy of
IndexedGeometryArray is shown in Figure 2-18.
IndexedGeometryArray
Geometry
GeometryArray
IndexedLineArray
IndexedPointArray
IndexedQuadArray
IndexedTriangleArray
IndexedGeometryStripArray
IndexedLineStripArray
IndexedTriangleStripArray
IndexedTriangleFanArray
Figure 2-18 IndexedGeometryArray Subclasses
The constructors for IndexedGeometryArray, IndexedGeometryStripArray, and their subclasses are similar
to constructors for GeometryArray and GeometryStripArray. The classes of indexed data have an
additional parameter to define how many indices are used to describe the geometry (the number of elements
in the index arrays).
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-33
IndexedGeometryArray and Subclasses Constructors
Constructs an empty object with the specified number of vertices, vertex format, and number of indices in
this array.
IndexedGeometryArray(int vertexCount, int vertexFormat, int indexCount)
IndexedPointArray(int vertexCount, int vertexFormat, int indexCount)
IndexedLineArray(int vertexCount, int vertexFormat, int indexCount)
IndexedTriangleArray(int vertexCount, int vertexFormat, int indexCount)
IndexedQuadArray(int vertexCount, int vertexFormat, int indexCount)
IndexedGeometryStripArray and Subclasses Constructors
Constructs an empty object with the specified number of vertices, vertex format, number of indices in this
array, and an array of vertex counts per strip.
IndexedGeometryStripArray(int vc, int vf, int ic, int stripVertexCounts[]))
IndexedLineStripArray(int vc, int vf, int ic, int stripVertexCounts[]))
IndexedTriangleStripArray(int vc, int vf, int ic, int stripVertexCounts[]))
IndexedTriangleFanArray(int vc, int vf, int ic, int stripVertexCounts[]))
IndexedGeometryArray, IndexedGeometryStripArray, and their subclasses inherit the methods from
GeometryArray and GeometryStripArray to load the data arrays. The classes of indexed data have added
methods to load indices into the index arrays.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-34
IndexedGeometryArray Methods (partial list)
void setCoordinateIndex(int index, int coordinateIndex)
Sets the coordinate index associated with the vertex at the specified index for this object.
void setCoordinateIndices(int index, int[] coordinateIndices)
Sets the coordinate indices associated with the vertices starting at the specified index for this object.
void setColorIndex(int index, int colorIndex)
Sets the color index associated with the vertex at the specified index for this object.
void setColorIndices(int index, int[] colorIndices)
Sets the color indices associated with the vertices starting at the specified index for this object.
void setNormalIndex (int index, int normalIndex)
Sets the normal index associated with the vertex at the specified index for this object.
void setNormalIndices (int index, int[] normalIndices)
Sets the normal indices associated with the vertices starting at the specified index for this object.
void setTextureCoordinateIndex (int index, int texCoordIndex)
Sets the texture coordinate index associated with the vertex at the specified index for this object.
void setTextureCoordinateIndices (int index, int[] texCoordIndices)
Sets the texture coordinate indices associated with the vertices starting at the specified index for this object.
2.5.5 Axis.java is an Example of IndexedGeometryArray
The examples/geometry subdirectory contains the Axis.java source code. This file defines the
Axis visual object useful for visualizing the axis and origin in a virtual universe. It also serves as an
example of indexed geometry.
The Axis object defines 18 vertices and 30 indices to specify 15 lines. There are five lines per axis used to
create a simple 3D arrow.
2.6 Appearance and Attributes
Shape3D objects may reference both a Geometry and an Appearance object. As was previously discussed
in Section 2.5, the Geometry object specifies the per-vertex information of a visual object. The per-vertex
information in a Geometry object can specify the color of visual objects. Data in a Geometry object are
often insufficient to fully describe how an object looks. In most cases, an Appearance object is also needed.
An Appearance object does not contain the information for how the Shape3D object should look, but an
Appearance object knows where to find appearance data. An Appearance object (already a subclass of
NodeComponent) may reference several objects of other subclasses of the NodeComponent abstract class.
Therefore, information which describes the appearance of a geometric primitive is said to be stored within
an appearance bundle, such as the one shown in Figure 2-19.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-35
Appearance Geometry
S
LineAttributes
Coloring
Attributes
Material
Figure 2-19 An Appearance Bundle
An Appearance object can refer to several different NodeComponent subclasses called appearance attribute
objects, including:
PointAttributes
LineAttributes
PolygonAttributes
ColoringAttributes
TransparencyAttributes
RenderingAttributes
Material
TextureAttributes
Texture
TexCoordGeneration
The first six of the listed NodeComponent subclasses are explained in this section. Of the remaining four
subclasses in the list, Material is used for lighting, and the last three are used for texture mapping. Lighting
and texture mapping are advanced topics, which are not discussed in this section.
An Appearance object with the attributes objects it refers to is called an appearance bundle. To reference
any of these node components, an Appearance object has a method with an obvious name. For example, for
an Appearance object to refer to a ColoringAttributes object, use the method
Appearance.setColoringAttributes(). A simple code example looks like Code Fragment
2-9:
1. ColoringAttributes ca = new ColoringAttributes();
2. ca.setColor (1.0, 1.0, 0.0);
3. Appearance app = new Appearance();
4. app.setColoringAttributes(ca);
5. Shape3D s3d = new Shape3D();
6. s3d.setAppearance (app);
7. s3d.setGeometry (someGeomObject);
Code Fragment 2-9 Using Appearance and ColoringAttributes NodeComponent Objects
The scene graph that results from this code is shown in Figure 2-20.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-36
Appearance Geometry
S
Coloring
Attributes
Figure 2-20 Appearance Bundle Created by Code Fragment 2-9.
2.6.1 Appearance NodeComponent
The next two reference blocks list the default constructor and other methods of the Appearance class.
Appearance Constructor
The default Appearance constructor creates an Appearance object with all component object references
initialized to null. The default values, for components with null references, are generally predictable:
points and lines are drawn with sizes and widths of 1 pixel and without antialiasing, the intrinsic color is
white, transparency is disabled, and the depth buffer is enabled and is both read and write accessible.
Appearance()
An Appearance component usually references one or more attribute components, by calling the following
methods. These attribute classes are described in Section 2.6.3.
Appearance Methods (excluding lighting and texturing)
Each method sets its corresponding NodeComponent object to be part of the current Appearance bundle.
void setPointAttributes(PointAttributes pointAttributes)
void setLineAttributes(LineAttributes lineAttributes)
void setPolygonAttributes(PolygonAttributes polygonAttributes)
void setColoringAttributes(ColoringAttributes coloringAttributes)
void setTransparencyAttributes(TransparencyAttributes transparencyAttributes)
void setRenderingAttributes(RenderingAttributes renderingAttributes)
2.6.2 Sharing NodeComponent Objects
It is legal and often desirable for several different objects to reference, and therefore share, the same
NodeComponent objects. For example in Figure 2-21, two Shape3D objects reference the same Appearance
component. Also, two different Appearance objects are sharing the same LineAttributes component.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-37
Appearance
Geometry
S
LineAttributes
Coloring
Attributes
Material
Geometry
S
Geometry
S
Appearance
Figure 2-21 Multiple Appearance Objects Sharing a Node Component
Sharing the same NodeComponent can enhance performance. For instance, if several Appearance
components share the same LineAttributes component, which enables antialiasing, the Java 3D rendering
engine may decide to group the antialiased wire frame shapes together. That would minimize turning
antialiasing on and off, which should be faster.
Note that it is illegal for a Node to have more than one parent. However, since NodeComponents are
referenced, they arent Node objects, so they really dont have any parents. Therefore, NodeComponent
objects may be shared (referenced) by any number of other objects.
2.6.3 Attribute Classes
In this section, six of the NodeComponent subclasses that can be referenced by Appearance are described
(excluding the ones used for lighting and texturing).
PointAttributes
PointAttributes objects manage how point primitives are rendered. By default, if a vertex is rendered as a
point, it fills a single pixel. You can use setPointSize() to make a point larger. However, by default, a
larger point still looks square, unless you also use setPointAntialiasingEnable(). Antialiasing points
changes the colors of the pixels to make the point look "rounder" (or at least, less visibly square).
PointAttributes Constructors
PointAttributes()
Creates a component object that describes 1 pixel size points without antialiasing.
PointAttributes(float pointSize, boolean state)
Creates a component object that describes the pixel size for points and whether to enable antialiasing.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-38
PointAttributes Methods
void setPointSize(float pointSize)
Describes pixel size for points.
void setPointAntialiasingEnable(boolean state)
Enables or disables point antialiasing. Visually interesting only if point is larger than 1 pixel.
LineAttributes
LineAttributes objects change how line primitives are rendered in three ways. By default, a line is drawn
solidly filled, one pixel wide, and without antialiasing (the smoothing effect). You can change these
attributes by calling the methods setLinePattern(), setLineWidth(), and setLineAntialiasingEnable().
LineAttributes Constructors
LineAttributes()
Creates a component object that describes 1 pixel wide, solidly filled lines without antialiasing.
LineAttributes(float pointSize, int linePattern, boolean state)
Creates a component object that describes the pixel size for lines, the pattern to use for drawing, and
whether to enable antialiasing.
LineAttributes Methods
void setLineWidth(float lineWidth)
Describes pixel width for lines.
void setLinePattern(int linePattern)
where linePattern is one of the following constants: PATTERN_SOLID (the default), PATTERN_DASH,
PATTERN_DOT, or PATTERN_DASH_DOT. Describes how the pixels of a line should be filled.
void setLineAntialiasingEnable(boolean state)
Enables or disables line antialiasing.
PolygonAttributes
PolygonAttributes governs how polygon primitives are rendered in three ways: how the polygon is
rasterized, if it is culled, and whether a special depth offset is applied. By default, a polygon is filled, but
setPolygonMode() can change the polygon rasterization mode so that the polygon is drawn as wire frame
(lines) or only as the points at the vertices. (In the latter two cases, the LineAttributes or PointAttributes
also affect how the primitive is visualized.) The method setCullFace() may be used to reduce the number of
polygons which are rendered. If setCullFace() is set to either to CULL_FRONT or CULL_BACK, on
average, half the polygons are no longer rendered.
By default, vertices rendered as both wire frame and filled polygons are not always rasterized with the same
depth values, which can cause stitching when the wire frame should be fully visible. With
setPolygonOffset(), the depth values of the filled polygons could be nudged toward the image
plate, so that the wire frame would outline the filled object properly. setBackFaceNormalFlip() is
useful to render a lit, filled polygon, where a both sides of the polygon are to be shaded. See Section 2.6.4
for an example program that shades both sides of polygons.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-39
PolygonAttributes Constructors
PolygonAttributes()
Creates a component object with default filled polygons, no face culling, and no polygon offset.
PolygonAttributes(int polygonMode, int cullFace, float polygonOffset)
Creates a component object to render polygons as either points, lines, or filled polygons, with the specified
face culling, and the specified polygon offset.
PolygonAttributes(int polygonMode, int cullFace, float polygonOffset, boolean
backFaceNormalFlip)
Creates a component object similar to the previous constructor, but also reverses how front and back facing
polygons are determined.
PolygonAttributes Methods
void setCullFace(int cullFace)
where cullFace is one of the following: CULL_FRONT, CULL_BACK, or CULL_NONE. Cull (do not
render) front facing polygons or back facing polygons, or dont cull any polygons at all.
void setPolygonMode(int polygonMode)
where polygonMode is one of the following: POLYGON_POINT, POLYGON_LINE, or
POLYGON_FILL. Render polygons as either points, lines, or filled polygons (the default).
void setPolygonOffset(float polygonOffset)
where polygonOffset is the screen-space offset added to adjust the depth value of the polygon primitives.
void setBackFaceNormalFlip(boolean backFaceNormalFlip)
where backFaceNormalFlip determines whether vertex normals of back facing polygons should be flipped
(negated) prior to lighting. When this flag is set to true and back face culling is disabled, a polygon is
rendered as if the polygon had two sides with opposing normals.
ColoringAttributes
ColoringAttributes controls how any primitive is colored. setColor() sets an intrinsic color, which in some
situations specifies the color of the primitive. Also, setShadeModel() determines whether there is color
interpolation across primitives (usually polygons and lines).
ColoringAttributes Constructors
ColoringAttributes()
Creates a component object using white for the intrinsic color and SHADE_GOURAUD as the default
shading model.
ColoringAttributes(Color3f color, int shadeModel)
ColoringAttributes(float red, float green, float blue, int shadeModel)
where shadeModel is one of SHADE_GOURAUD, SHADE_FLAT, FASTEST, or NICEST. Both
constructors create a component object using parameters to specify the intrinsic color and shading model.
(In most cases, FASTEST is also SHADE_FLAT, and NICEST is also SHADE_GOURAUD.)
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-40
ColoringAttributes Methods
void setColor(Color3f color)
void setColor(float red, float green, float blue)
Both methods specify the intrinsic color.
void setShadeModel(int shadeModel)
where shadeModel is one of the following constants: SHADE_GOURAUD, SHADE_FLAT, FASTEST,
or NICEST. Specifies the shading model for rendering primitives.
Since colors can also be defined at each vertex of a Geometry object, there may be a conflict with the
intrinsic color defined by ColoringAttributes. In case of such a conflict, the colors defined in the Geometry
object overrides the ColoringAttributes intrinsic color. Also, if lighting is enabled, the ColoringAttributes
intrinsic color is ignored altogether.
TransparencyAttributes
TransparencyAttributes manages the transparency of any primitive. setTransparency() defines the opacity
value (often known as alpha blending) for the primitive. setTransparencyMode() enables transparency and
selects what kind of rasterization is used to produce transparency.
TransparencyAttributes Constructors
TransparencyAttributes()
Creates a component object with the transparency mode of FASTEST.
TransparencyAttributes(int tMode, float tVal)
where tMode is one of BLENDED, SCREEN_DOOR, FASTEST, NICEST, or NONE, and tVal specifies
the objects opacity (where 0.0 denotes fully opaque and 1.0, fully transparent). Creates a component
object with the specified method for rendering transparency and the opacity value of the objects
appearance.
TransparencyAttributes Methods
void setTransparency(float tVal)
where tVal specifies an objects opacity (where 0.0 denotes fully opaque and 1.0, fully transparent).
void setTransparencyMode(int tMode)
where tMode (one of BLENDED, SCREEN_DOOR, FASTEST, NICEST, or NONE) specifies if and how
transparency is performed.
RenderingAttributes
RenderingAttributes controls two different per-pixel rendering operations: the depth buffer test and the
alpha test. setDepthBufferEnable() and setDepthBufferWriteEnable() determine whether and how the depth
buffer is used for hidden surface removal. setAlphaTestValue() and setAlphaTestFunction() determine
whether and how the alpha test function is used.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-41
RenderingAttributes Constructors
RenderingAttributes()
Creates a component object which defines per-pixel rendering states with enabled depth buffer testing and
disabled alpha testing.
RenderingAttributes(boolean depthBufferEnable, boolean depthBufferWriteEnable,
float alphaTestValue, int alphaTestFunction)
where depthBufferEnable turns on and off the depth buffer comparisons (depth testing),
depthBufferWriteEnable turns on and off writing to the depth buffer, alphaTestValue is used for testing
against incoming source alpha values, and alphaTestFunction is one of ALWAYS, NEVER, EQUAL,
NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER, or GREATER_OR_EQUAL, which denotes
what type of alpha test is active. Creates a component object which defines per-pixel rendering states for
depth buffer comparisons and alpha testing.
RenderingAttributes Methods
void setDepthBufferEnable(boolean state)
turns on and off the depth buffer testing.
void setDepthBufferWriteEnable(boolean state)
turns on and off writing to the depth buffer.
void setAlphaTestValue(float value)
specifies the value to be used for testing against incoming source alpha values.
void setAlphaTestFunction(int function)
where function is one of ALWAYS, NEVER, EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL,
GREATER, or GREATER_OR_EQUAL, which denotes what type of alpha test is active. If function is
ALWAYS (the default), then the alpha test is effectively disabled.
Appearance Attribute Defaults
The default Appearance constructor initializes an Appearance object with all attribute references set to
null. Table 2-1 lists the default values for those attributes with null references.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-42
Table 2-1 Attribute Defaults
color white (1, 1, 1)
texture environment mode TEXENV_REPLACE
texture environment color white (1, 1, 1)
depth test enable true
shade model SHADE_GOURAUD
polygon mode POLYGON_FILL
transparency enable false
transparency mode FASTEST
cull face CULL_BACK
point size 1.0
line width 1.0
point antialiasing enable false
line antialiasing enable false
2.6.4 Example: Back Face Culling
Polygons have two faces. For many visual objects, only one face of the polygons need be rendered. To
reduce the computational power required to render the polygonal surfaces, the renderer can cull the
unneeded faces. The culling behavior is defined on a per visual object basis in the PolygonAttribute
component of Appearance. The front face of an object is the face for which the vertices are defined in
counter-clockwise order.
TwistStripApp.java creates a 'twisted strip' visual object and rotates it about the y-axis. As the
twisted strip rotates, parts of it seemed to disappear. The missing pieces are easily noticed Figure 2-22.
Actually, TwistStripApp defines two visual objects, each with the same geometry - that of a Twisted strip.
One of the visual objects renders as a wireframe, the other as a solid surface. Since the two visual objects
have the same location and orientation, the wireframe visual object is only visible when the surface is not
visible.
Figure 2-22 Twisted Strip with Back Face Culling
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-43
The reason for the missing polygons is the culling mode hasnt been specified, so it defaults to
CULL_BACK. The triangles of the surface disappear when their back side (back face) face the image
plate. This is a feature that allows the rendering system to ignore rendering triangle surfaces that are
unnecessary, unwanted, or both.
However, sometimes back face culling is a problem, as in the TwistStripApp. The problem has a simple
solution: turn off culling. To do this, create an Appearance component that references a PolygonAttributes
component which disables culling, as shown in Code Fragment 2-10.
1. PolygonAttributes polyAppear = new PolygonAttributes();
2. polyAppear.setCullFace(PolygonAttributes.CULL_NONE);
3. Appearance twistAppear = new Appearance();
4. twistAppear.setPolygonAttributes(polyAppear);
5. // several lines later, after the twistStrip TriangleStripArray has
6. // been defined, create a Shape3D object with culling turned off
7. // in the Appearance bundle, and add the Shape3D to the scene graph
8. twistBG.addChild(new Shape3D(twistStrip, twistAppear));
Code Fragment 2-10 Disable Back Face Culling for the Twisted Strip
In Figure 2-23, disabling back face culling clearly fills in the cracks. Now all polygons are rendered, no
matter which direction they are facing.
Figure 2-23 Twisted Strip without Back Face Culling
The front face of a polygon is the side for which the vertices are appear in counter-clock wise order. This
is often referred to as the "right-hand rule" (see the glossary). The rule used to determine the front face of a
geometric strip (i.e., triangle strip, quad strip) alternates for each element in the strip. Figure 2-24 shows
examples of using the right-hand rule for front face determination.
Getting Started with the Java 3D API Chapter 2. Creating Geometry
The Java 3D Tutorial 2-44
0
0
1
1
2
2
0
1
2
3
4
5
6
7
8
9
Figure 2-24 Determining the Front Face of Polygons and Strips
2.7 Self Test
On the next couple of pages are a few exercises designed to test and enhance your understanding of the
material presented in this chapter. The solutions to some of these exercises are given in Appendix C.
1. Try your hand at creating a new yo-yo using two cylinders instead of two cones. Using
ConeYoyoApp.java as a starting point, what changes are needed?
2. A two-cylinder yo-yo can be created with two quad-strip objects and four triangle-fan objects. Another
way is to reuse one quad-strip and one triangle fan. What objects would form this yo-yo visual object?
The same approach can be used to create the cone yo-yo. What object would form this yo-yo visual
object?
3. The default culling mode is used in YoyoLineApp.java and YoyoPointApp.java. Change either, or
both, of these programs to cull nothing, then compile and run the modified program. What difference
do you see?
tutorial v1.5 (Java 3D API v1.1.2)
Getting Started with
the Java 3D
API
Chapter 3
Easier Content Creation
Dennis J Bouvier
K Computing
Getting Started with Java 3D
The Java 3D Tutorial
1999 Sun Microsystems, Inc.
2550 Garcia Avenue, Mountain View, California 94043-1100 U.S.A
All Rights Reserved.
The information contained in this document is subject to change without notice.
SUN MICROSYSTEMS PROVIDES THIS MATERIAL "AS IS" AND MAKES NO WARRANTY OF ANY KIND,
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS SHALL NOT BE
LIABLE FOR ERRORS CONTAINED HEREIN OR FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING
LOST PROFITS IN CONNECTION WITH THE FURNISHING, PERFORMANCE OR USE OF THIS MATERIAL,
WHETHER BASED ON WARRANTY, CONTRACT, OR OTHER LEGAL THEORY).
THIS DOCUMENT COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE
PERIODICALLY MADE TO THE INFORMATION HEREIN; THESE CHANGES WILL BE INCORPORATED IN NEW
EDITIONS OF THE PUBLICATION. SUN MICROSYSTEMS, INC. MAY MAKE IMPROVEMENTS AND/OR CHANGES
IN THE PRODUCT(S) AND/OR PROGRAM(S) DESCRIBED IN THIS PUBLICATION AT ANY TIME.
Some states do not allow the exclusion of implied warranties or the limitations or exclusion of liability for incidental or
consequential damages, so the above limitations and exclusion may not apply to you. This warranty gives you specific legal
rights, and you also may have other rights which vary from state to state.
Permission to use, copy, modify, and distribute this documentation for NON-COMMERCIAL purposes and without fee is
hereby granted provided that this copyright notice appears in all copies.
This documentation was prepared for Sun Microsystems by K Computing (530 Showers Drive, Suite 7-225, Mountain View,
CA 94040, 770-982-7881, www.kcomputing.com). For further information about course development or course delivery,
please contact either Sun Microsystems or K Computing.
Java, JavaScript, Java 3D, HotJava, Sun, Sun Microsystems, and the Sun logo are trademarks or registered trademarks of Sun
Microsystems, Inc. All other product names mentioned herein are the trademarks of their respective owners.
Module 1: Getting Started with the Java 3D API
The Java 3D Tutorial 3-i
Table of Contents
Chapter 3
Easier Content Creation .......................................................................................................................3-1
3.1 What is in this Chapter ..............................................................................................................3-1
3.2 Loaders .....................................................................................................................................3-2
3.2.1 Simple Example of Using a Loader.....................................................................................3-2
3.2.2 Publicly Available Loaders.................................................................................................3-4
3.2.3 Loader Package Interfaces and Base Classes ......................................................................3-4
3.2.4 Writing a Loader................................................................................................................3-6
3.3 GeometryInfo ............................................................................................................................3-7
3.3.1 Simple GeometryInfo Example...........................................................................................3-8
3.3.2 Classes for GeometryInfo...................................................................................................3-9
3.4 Text2D....................................................................................................................................3-13
3.4.1 Simple Text2D Example ..................................................................................................3-14
3.4.2 Classes Used in Creating Text2D Objects.........................................................................3-15
3.5 Text3D....................................................................................................................................3-16
3.5.1 Simple Text3D Example ..................................................................................................3-16
3.5.2 Classes Used in Creating Text3D Objects.........................................................................3-18
3.6 Background.............................................................................................................................3-22
3.6.1 Background Examples......................................................................................................3-23
3.6.2 Background Class ............................................................................................................3-24
3.7 BoundingLeaf..........................................................................................................................3-26
3.7.1 BoundingLeaf Class.........................................................................................................3-27
3.8 User Data................................................................................................................................3-28
3.9 Chapter Summary....................................................................................................................3-29
3.10 Self Test..................................................................................................................................3-29
Getting Started with Java 3D Chapter 3. Contents
The Java 3D Tutorial 3-ii
List of Figures
Figure 3-1 Recipe for Using a Loader....................................................................................................3-2
Figure 3-2 A GeometryInfo Polygon and One Possible Triangulation .....................................................3-7
Figure 3-3 Two Renderings of a Car (facing opposite directions) Created Using GeometryInfo...............3-8
Figure 3-4 Class Hierarchy for the GeometryInfo Utility Class, and Related Classes ..............................3-9
Figure 3-5 Recipe for Text2D .............................................................................................................3-14
Figure 3-6 Image from Text2DApp.java..............................................................................................3-15
Figure 3-7 The Class Hierarchy for Text2D.........................................................................................3-15
Figure 3-8 Recipe for Creating a Text3D Object..................................................................................3-16
Figure 3-9 The Default Reference Point and Extrusion for a 3DText Object.........................................3-17
Figure 3-10 Class Hierarchy for Text3D .............................................................................................3-18
Figure 3-11 Recipe for Backgrounds ...................................................................................................3-23
Figure 3-12 Viewing the Constellation in the Background of BackgroundApp.java............................3-24
Figure 3-13 The Class Hierarchy for Background................................................................................3-24
Figure 3-14 BoundlingLeaf Moves with a Visual Object and Independently of a Light Source ..............3-26
Figure 3-15 Java 3D API Class Hierarchy for BoundingLeaf ...............................................................3-28
List of Tables
Table 3-1 Publicly Available Java 3D Loaders ......................................................................................3-4
Table 3-2 The Orientation of Text and Position of the Reference Point for Combinations of Text3D
Alignment and Path .....................................................................................................................3-18
List of Code Fragments
Code Fragment 3-1 A Portion of jdk1.2/demo/java3d/ObjLoad/ObjLoad.java................3-3
Code Fragment 3-2 Using GeometryInfo, Triangulator, NormalGenerator, and Stripifier Utilities. ..........3-9
Code Fragment 3-3 A Text2D Object Created (excerpt from Text2DApp.java) ....................................3-14
Code Fragment 3-4 Making a Two-sided Text2D Object. ....................................................................3-15
Code Fragment 3-5 Creating a Text3D Visual Object ..........................................................................3-17
Code Fragment 3-6 Adding a Colored Background ..............................................................................3-23
Code Fragment 3-7 Adding a Geometric Background...........................................................................3-23
Code Fragment 3-8 Adding a BoundingLeaf to the View Platform for an "Always-On" Bounds............3-27
Getting Started with Java 3D Chapter 3. Contents
The Java 3D Tutorial 3-iii
List of Reference Blocks
Class ObjectFile....................................................................................................................................3-3
com.sun.j3d.loaders Interface Summary.................................................................................................3-5
com.sun.j3d.loaders Class Summary......................................................................................................3-5
Interface Loader Method Summary........................................................................................................3-5
LoaderBase Constructor Summary........................................................................................................3-6
SceneBase Method Summary (partial list: loader users' methods) ...........................................................3-6
SceneBase Constructor Summary..........................................................................................................3-7
GeometryInfo Constructor Summary...................................................................................................3-10
GeometryInfo Method Summary (partial list).......................................................................................3-11
Triangulator Constructor Summary.....................................................................................................3-12
Triangulator Method Summary ...........................................................................................................3-12
Stripifier Constructor Summary ..........................................................................................................3-12
Stripifier Method Summary.................................................................................................................3-12
NormalGenerator Constructor Summary..............................................................................................3-13
NormalGenerator Method Summary....................................................................................................3-13
Text2D Constructor Summary ............................................................................................................3-16
Text2D Method Summary...................................................................................................................3-16
Text3D Constructor Summary ............................................................................................................3-19
Text3D Method Summary...................................................................................................................3-20
Text3D Capabilities Summary ...........................................................................................................3-20
Font3D Constructor Summary.............................................................................................................3-21
Font3D Method Summary...................................................................................................................3-21
Font Constructor Summary (partial list) ..............................................................................................3-21
FontExtrusion Constructor Summary ..................................................................................................3-22
FontExtrusion Method Summary.........................................................................................................3-22
Background Constructor Summary......................................................................................................3-25
Background Method Summary ............................................................................................................3-25
Background Capabilities Summary......................................................................................................3-26
BoundingLeaf Constructor Summary...................................................................................................3-28
BoundingLeaf Method Summary.........................................................................................................3-28
SceneGraphObject Methods (Partial List - User Data Methods) ...........................................................3-29
Preface to Chapter 3
This document is one part of a tutorial on using the Java 3D API. You should be familiar with Java 3D
API basics to fully appreciate the material presented in this Chapter. Additional chapters and the full
preface to this material are presented in the Module 0 document available at:
http://java.sun.com/products/javamedia/3d/collateral
Cover Image
The cover image is of a galleon as modeled in an obj file and rendered by Java 3D. The Java 3D program
that produced the rendering, ObjLoadApp.java, is a modification of the ObjLoad.java
example program discussed in Section 3.2. The program source code for ObjLoad.java and the
galleon model file are available with the JDK 1.2 distribution.
Module 1: Getting Started with the Java 3D API
The Java 3D Tutorial 3-1
3
Easier Content Creation
T(dx, dy, dz) =
1 0 0 dx
0 1 0 dy
0 0 1 dz
0 0 0 1
Chapter Objectives
After reading this chapter, youll be able to:
Use loader classes to load geometry from files into Java 3D worlds
Use GeometryInfo to specify geometry as arbitrary polygons
Use Text2D to add text to Java 3D worlds
Use Text3D to add geometric text to Java 3D worlds
Specify colors, images, or geometry for background
Use BoundingLeaf for specifying bounds for backgrounds, behaviors, and lights
Use the UserData field of SceneGraphObject class for a variety of applications
As the third chapter of the "Getting Started" Module, Chapter Three presents easier ways of creating
visual content. Chapters one and two present the basic ways of creating virtual worlds, which includes
creating visual objects from geometry classes. It only takes a little programming to learn that creating
complex visual content one triangle at a time is tedious. Fortunately, there are a variety of easier ways to
produce visual content. This chapter surveys a number of content creation methods and content issues
beyond creating simple geometry.
3.1 What is in this Chapter
If you want to create a large or complex visual object, a great deal of code is required to just specify
coordinates and normals. If you are concerned about performance, you spend more time, and code, to
specify the geometry in as few triangle strips as possible. Geometry coding, fraught with details, can de a
big sink on your development time. Fortunately, there are ways to create visual objects that require less
code, resulting in fewer mistakes, and quiet often taking much less time.
Section 3.2 presents content loader classes, or "Loaders" as they are commonly referred to. Loaders, one
alternative to hand coded geometry, create Java 3D visual objects from files created with 3D modeling
CHAPTER
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-2
software. Loaders exist today for Alias obj files, VRML files, Lightwave files, Autocad dfx files, and a
variety of other 3D file formats. New loaders are in development as well. The most important feature is
the ability to write custom loaders for Java 3D.
Section 3.3 presents the GeometryInfo utility class, another alternative to hand coded geometry.
GeometryInfo, along with the Triangulator, Stripifier, and NormalGeneration classes allows you to specify
visual object geometry as arbitrary polygons. These classes convert the polygons to triangles, make strips
of the triangles, and compute normals for the triangles at runtime, potentially saving you much coding time.
The next three sections present specific content creation techniques. Sections 3.4 and 3.5 present the
Text2D utility and Text3D classes, respectively. These two classes represent two easy ways to add text to
the contents of your virtual world. Section 3.6 presents the Background class. The Background class
allows you to specify a color, image or geometry as the background for a virtual world.
The next two sections dont have as much to do with content. However, these are important topics.
Section 3.7 presents the BoundingLeaf class. BoundingLeaf objects are useful in conjunction with
backgrounds, behaviors, lights, fog, and other Java 3D classes that require a bounds specification. Section
3.8 discusses the use of the UserData field of SceneGraphObject class.
Of course, the Chapter concludes with a summary and Self-Test exercises for the adventurous.
3.2 Loaders
A loader class reads 3D scene files (not Java 3D files) and creates Java 3D representations of the file's
contents that can be selectively added to a Java 3D world and augmented by other Java 3D code. The
utility com.sun.j3d.loaders package provides the means for loading content from files created in
other applications into Java 3D applications. Loader classes implement the loader interface defined in the
utility com.sun.j3d.loaders package.
Since there are a variety of file formats for the purpose of representing 3D scenes (e.g., .obj, .vrml,
etc.) and there will always be more file formats, the actual code to load a file is not part of Java 3D or of
the loaders package; only the interface for the loading mechanism is included. With the interface definition,
the Java 3D user can develop file loader classes with the same interface as other loader classes.
3.2.1 Simple Example of Using a Loader
Without a class that actually reads a file, it is not possible to load content from a file. With a loader class
it is easy. Figure 3-1 presents the recipe for using a loader.
0. find a loader (if one is not available, write one: see section 3.2.4)
1. import the loader class for your file format (see Section 3.2.2 to find a loader)
2. import other necessary classes
3. declare a Scene variable (don't use the constructor)
4. create a loader object
5. load the file in a try block, assigning the result to the Scene variable
6. insert the Scene into the scene graph
Figure 3-1 Recipe for Using a Loader
A loader example based on the ObjectFile class is distributed with JDK 1.2. It is found in
jdk1.2/demo/java3d/ObjLoad. Code Fragment 3-1 presents a excerpt from the code from this
demo.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-3
The ObjectFile class is distributed in the com.sun.j3d.loaders package as an example file loader.
Other loaders are available (some are listed in Table 3-1).
Class ObjectFile
Package: com.sun.j3d.loaders
Implements: Loader
The ObjectFile class implements the Loader interface for the Wavefront .obj file format, a standard 3D object file
format created for use with Wavefront's Advanced Visualizer . Object Files are text based files supporting both
polygonal and free-form geometry (curves and surfaces). The Java 3D .obj file loader supports a subset of the file
format, but it is complete enough to load almost all commonly available Object Files. Free-form geometry is not
supported.
Code Fragment 3-1 is annotated with numbers corresponding to the loader usage recipe given in Figure 3-1.
1. import com.sun.j3d.loaders.objectfile.ObjectFile;
2. import com.sun.j3d.loaders.ParsingErrorException;
3. import com.sun.j3d.loaders.IncorrectFormatException;
4. import com.sun.j3d.loaders.Scene;
5. import java.applet.Applet;
6. import javax.media.j3d.*;
7. import javax.vecmath.*;
8. import java.io.*;
9.
10. public class ObjLoad extends Applet {
11.
12. private String filename = null;
13.
14. public BranchGroup createSceneGraph() {
15. // Create the root of the branch graph
16. BranchGroup objRoot = new BranchGroup();
17.
18. ObjectFile f = new ObjectFile();
19. Scene s = null;
20. try {
21. s = f.load(filename);
22. }
23. catch (FileNotFoundException e) {
24. System.err.println(e);
25. System.exit(1);
26. }
27. catch (ParsingErrorException e) {
28. System.err.println(e);
29. System.exit(1);
30. }
31. catch (IncorrectFormatException e) {
32. System.err.println(e);
33. System.exit(1);
34. }
35.
36. objRoot.addChild(s.getSceneGroup());
37. }
Code Fragment 3-1 An Excerpt from jdk1.2/demo/java3d/ObjLoad/ObjLoad.java.
This program goes on to add behaviors (the default spin, or the mouse interaction - covered in Chapter 4)
and lights (Chapter 6) to provide a shaded rendering of the object model. Of course, you can do many
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-4
other things with the model in a Java 3D program such as add animations, add other geometry, change the
color of the model, and so on.
A Lightwave loader example is available with the JDK 1.2 distribution and is found at
jdk1.2/demos/java3d/lightwave/Viewer.java. This loader will load the lights and
animations specified in a Lightwave lws file.
3.2.2 Publicly Available Loaders
A variety of loader classes exist for Java 3D. Table 3-1 lists file formats for which loaders are publicly
available. At the time of this writing, at least one loader class is available for each of the file formats listed
in Table 3-1.
Table 3-1 Publicly Available Java 3D Loaders
File Format Description
3DS 3D-Studio
COB Caligari trueSpace
DEM Digital Elevation Map
DXF AutoCAD Drawing Interchange File
IOB Imagine
LWS Lightwave Scene Format
NFF WorldToolKit NFF format
OBJ Wavefront
PDB Protein Data Bank
PLAY PLAY
SLD Solid Works (prt and asm files)
VRT Superscape VRT
VTK Visual Toolkit
WRL Virtual Reality Modeling Language
For a current list of loader classes, check the web. For that matter, loader classes can be downloaded from
the web. Loaders can be found by following links from the Java 3D home page, or check the references
section of this tutorial for a web address.
3.2.3 Loader Package Interfaces and Base Classes
The number and variety of loaders exist because the Java 3D designers made it easy to write a loader
1
.
Loader classes are implementations of the Loader Interface which lowers the level of difficulty in writing a
loader. More importantly, the interfaces make the various loader classes consistent in their interface.
As in the example, a program loading a 3D file actually uses both a loader and a scene object. The loader
reads, parses, and creates the Java 3D representation of the file's contents. The scene object stores the
scene graph created by the loader. It is possible to load scenes from more than one file (of the same
format) using the same loader object creating multiple scene objects. Files of different formats can be
combined in one Java 3D program using the appropriate loader classes.
The following reference block lists the interfaces in the com.sun.j3d.loaders package. A loader
implements the loader interface and uses a class that implements the scene interface.
1
Having the loader interface and base class actually makes it easy to write a loader for a simple file format. It also
makes it possible to write a loader for a complex file format.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-5
com.sun.j3d.loaders Interface Summary
Loader The Loader interface is used to specify the location and elements of a file format to load.
Scene The Scene interface is a set of methods used to extract Java 3D scene graph information from a file
loader utility.
In addition to the interfaces, the com.sun.j3d.loaders package provides base implementations of
the interfaces.
com.sun.j3d.loaders Class Summary
LoaderBase This class implements the Loader interface and adds constructors. This class is extended by the
authors of specific loader classes.
SceneBase This class implements the Scene interface and extends it to incorporate methods used by loaders.
This class is also used by programs that use loader classes.
The methods defined in the loader interface are used by programmers using loader classes.
Interface Loader Method Summary
Package: com.sun.j3d.loaders
The Loader interface is used to specify the location and elements of a file format to load. The interface is used to
give loaders of various file formats a common public interface. Ideally the Scene interface will be implemented to
give the user a consistent interface to extract the data.
Scene load(java.io.Reader reader)
This method loads the Reader and returns the Scene object containing the scene.
Scene load(java.lang.String fileName)
This method loads the named file and returns the Scene object containing the scene.
Scene load(java.net.URL url)
This method loads the named file and returns the Scene object containing the scene.
void setBasePath(java.lang.String pathName)
This method sets the base path name for data files associated with the file passed into the load(String) method.
void setBaseUrl(java.net.URL url)
This method sets the base URL name for data files associated with the file passed into the load(URL) method.
void setFlags(int flags)
This method sets the load flags for the file.
LOAD_ALL This flag enables the loading of all objects into the scene.
LOAD_BACKGROUND_NODES This flag enables the loading of background objects into the scene.
LOAD_BEHAVIOR_NODES This flag enables the loading of behaviors into the scene.
LOAD_FOG_NODES This flag enables the loading of fog objects into the scene.
LOAD_LIGHT_NODES This flag enables the loading of light objects into the scene.
LOAD_SOUND_NODES This flag enables the loading of sound objects into the scene.
LOAD_VIEW_GROUPS This flag enables the loading of view (camera) objects into the scene.
LoaderBase class provides an implementation for each of the three load() methods of Interface Loader.
LoaderBase also implements two constructors. Note the three loader methods return a Scene object.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-6
LoaderBase Constructor Summary
Package: com.sun.j3d.loaders
Implements: Loader
This class implements the Loader interface. The author of a file loader would extend this class. The user of a file
loader would use these methods.
LoaderBase()
Constructs a Loader with default values for all variables.
LoaderBase(int flags)
Constructs a Loader with the specified flags word.
In addition to the constructors listed in the reference block above, the methods listed in the following
reference block are used by programmers using any loader class.
SceneBase Method Summary (partial list: loader users' methods)
In a departure from the normal formatting of a reference block, this reference block lists the methods.
Background[] getBackgroundNodes()
Behavior[] getBehaviorNodes()
java.lang.String getDescription()
Fog[] getFogNodes()
float[] getHorizontalFOVs()
Light[] getLightNodes()
java.util.Hashtable getNamedObjects()
BranchGroup getSceneGroup()
Sound[] getSoundNodes()
TransformGroup[] getViewGroups()
3.2.4 Writing a Loader
As I mentioned above, one of the most important features of loaders is that you can write your own - which
means that all other Java 3D users can too! Space and time constraints do not permit me to go into details
on writing a loader here. However, the point of this section is to outline the process. If you have no
intention of writing a loader, at least not now, you can skip to the next section.
In writing a loader, the author of the new loader class extends the LoaderBase class defined in the
com.sun.j3d.loaders package. The new loader class uses the SceneBase class of the same
package.
There should be little need for future loaders to subclass SceneBase, or to implement Scene directly, as the
functionality of a SceneBase is fairly straightforward. SceneBase class is responsible for both the storage
and retrieval of data created by a loader while reading a file. The storage methods (used only by Loader
authors) are all of the add* routines. The retrieval methods (used primarily by Loader users) are all of the
get* routines.
Writing a file loader can be quite complex depending on the complexity of the file format. The hardest part
is to parse the file. Of course, you have to start with the documentation for the file format you want to
write a loader class for. Once the format is understood, begin by reading the loader and scene base classes.
The new loader class will extend the loader base class and use the scene base class.
In extending the loader base class, most of the work will be writing methods that recognize the various
types of content that can be represented in the file format. Each of these methods then create the
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-7
corresponding Java 3D scene graph component and store it in the scene object. The SceneBase constructor
is listed in the following reference block. Other relevant reference blocks appear in the previous section.
SceneBase Constructor Summary
Package: com.sun.j3d.loaders
Implements: Scene
This class implements the Scene interface and extends it to incorporate utilities that could be used by loaders.
This class is responsible for both the storage and retrieval of data from the Scene
SceneBase()
Create a SceneBase object - there should be no reason to use this constructor except in the implementation of a new
loader class.
3.3 GeometryInfo
If you don't have access to geometric model files, or geometric modeling software, you have to create your
geometry by hand. As mentioned in the chapter introduction, hand coding geometry often requires much
time and is an error prone activity. As you know, when you specify geometry through the core classes, you
are limited to triangles and quads. Using the GeometryInfo utiltity class can ease the time and tedium of
geometry creation. Instead of specifying each triangle, you can specify arbitrary polygons, which can be
concave, non-planer polygons - even with holes
2
. The GeometryInfo object, and other utility classes,
convert the geometry into a triangular geometry that Java 3D can render.
For example, if you wanted to create a car in Java 3D, instead of specifying triangles, you can specify the
profile of the car as a polygon in a GeometryInfo object. Then, using a Triangulator object, the polygon
can be subdivided into triangles. The left image of Figure 3-2 shows a profile of a car as polygon. The
right image is the polygon subdivided into triangles
3
.
Figure 3-2 A GeometryInfo Polygon and One Possible Triangulation
If you are interested in performance, and who isn't, use a Stripifier object to convert the triangles to triangle
strips. If you want to shade the visual object, use the NormalGenerator to calculate normals for the
geometry
4
.
2
While you can specify non-planar polygons in GeometryInfo, and a Triangulator object will create a
surface from it; non-planar contours do not specify a unique surface. In other words, if you specify a non-
planar contour, you may not get the surface you want from Triangulator.
3
Note that the figure does not necessarily represent the quality of the triangulation produced by the
Triangulator class.
4
If you are unfamiliar with the term shade as used in the context of computer graphics, check the glossary and
read the introductory sections of Chapter 6.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-8
An example program, GeomInfoApp.java, using the GeometryInfo, Triangulator, Stripifier, and
NormalGeneration classes to create a car is included in the examples/easyContent directory.
Figure 3-3 shows two renderings produced by GeomInfoApp.java. In both renderings the blue
outlines shows the contours specified in the GeometryInfo object. The red triangles (filled and shaded on
the left, outline on the right) were computed by the GeometryInfo object with Triangulation,
NormalGeneration, and Stripification done automatically.
Figure 3-3 Two Renderings of a Car (facing opposite directions) Created Using GeometryInfo
A single planar polygon, similar to the one in shown in Figure 3-2, specifies the profile of the car (each
side) in the GeomInfoApp example. Quadrilaterals specify the hood, roof, trunk lid, and other surfaces of
the car.
3.3.1 Simple GeometryInfo Example
Using a GeometryInfo object is as easy as using core GeomertryArray classes, if not easier. In creating a
GeomertyInfo object, simply specify the type of geometry you are going to need. The choices are
POLYGON_ARRAY, QUAD_ARRAY, TRIANGLE_ARRAY, TRIANGLE_FAN_ARRAY, and
TRIANGLE_STRIP_ARRAY. Then set the coordinates and strip counts for the geometry. You dont
have to tell the GeometryInfo object how many coordinates are in the data; it will be automatically
calculated.
Code Fragment 3-2 shows an example GeometryInfo application. Lines 1 through 3 of Code Fragment 3-2
show creating a GeometryInfo object and the initial geometry specification.
After having created the GeometryInfo object, the other classes may be used. If you want to use the
NormalGenerator, for example, first create a NormalGenerator object, then pass the GeometryInfo object
to it. Lines 8 and 9 of Code Fragment 3-2 do just that.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-9
1. GeometryInfo gi = new GeometryInfo(GeometryInfo.POLYGON_ARRAY);
2. gi.setCoordinates(coordinateData);
3. gi.setStripCounts(stripCounts);
4.
5. Triangulator tr = new Triangulator();
6. tr.triangulate(gi);
7.
8. NormalGenerator ng = new NormalGenerator();
9. ng.generateNormals(gi);
10.
11. Stripifier st = new Stripifier();
12. st.stripify(gi);
13.
14. Shape3D part = new Shape3D();
15. part.setAppearance(appearance);
16. part.setGeometry(gi.getGeometryArray());
Code Fragment 3-2 Using GeometryInfo, Triangulator, NormalGenerator, and Stripifier Utilities.
3.3.2 Classes for GeometryInfo
The GeometryInfo and related classes are members of the com.sun.j3d.util.geometry package
and are subclasses of Object. Figure 3-4 shows the hierarchy for these classes.
java.lang.Object
com.sun.j3d.utils.geometry.GeometryInfo
com.sun.j3d.utils.geometry.NormalGenerator
com.sun.j3d.utils.geometry.Stripifier
com.sun.j3d.utils.geometry.Triangulator
Figure 3-4 Class Hierarchy for the GeometryInfo Utility Class, and Related Classes
The GeometryInfo class has only one constructor and in this constructor you specify the kind of geometry
to be specified by the coordinate data. The following reference block gives more detail.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-10
GeometryInfo Constructor Summary
Package: com.sun.j3d.utils.geometry
Extends: java.lang.Object
The GeometryInfo object is where you put your geometry if you want to use the Java 3D utility libraries. Once you
have your data in the GeometryInfo object, you can send it to any (or all) of several utilities to have operations
performed on it, such as generating normals or turning it into long strips for more efficient rendering
("stripifying"). Geometry is loaded just as it is in the Java 3D GeometryArray object, but there are fewer options for
getting data into the object. GeometryInfo itself contains some simple utilities, such as calculating indices for non-
indexed data ("indexifying") and getting rid of unused data in your indexed geometry information ("compacting").
GeometryInfo(int primitive)
Construct a GeometryInfo object, where primitive is one of
POLYGON_ARRAY possibly multi-contour, possibly non-planar polygons
QUAD_ARRAY each set of four vertices forms an independent quad
TRIANGLE_ARRAY each set of three vertices form an independent triangle
TRIANGLE_FAN_ARRAY the stripCounts array indicates how many vertices to use for each triangle fan.
TRIANGLE_STRIP_ARRAY that the stripCounts array indicates how many vertices to use for each triangle strip.
The GeometryInfo class has many methods. Most methods are for setting (or getting) coordinate, color,
index, normal, or texture coordinate data. Most applications will only use a few of available methods.
However, it is convienient to be able to specify geometry to any level of detail and have the rest computed.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-11
GeometryInfo Method Summary (partial list)
void recomputeIndices()
Redo indexes to guarantee connection information.
void reverse()
Reverse the order of all lists.
void setColorIndices(int[] colorIndices)
Sets the array of indices into the Color array.
void setColors(Color3f[] colors)
Sets the colors array.
void setColors(Color4f[] colors)
Sets the colors array. There are other setColors methods.
void setContourCounts(int[] contourCounts)
Sets the list of contour counts.
void setCoordinateIndices(int[] coordinateIndices)
Sets the array of indices into the Coordinate array.
void setCoordinates(Point3f[] coordinates)
Sets the coordinates array.
void setCoordinates(Point3d[] coordinates)
Sets the coordinates array. There are other setCoordinates methods.
void setNormalIndices(int[] normalIndices)
Sets the array of indices into the Normal array.
void setNormals(Vector3f[] normals)
Sets the normals array.
void setNormals(float[] normals)
Sets the normals array.
void setStripCounts(int[] stripCounts)
Sets the array of strip counts.
void setTextureCoordinateIndices(int[] texCoordIndices)
Sets the array of indices into the TextureCoordinate array.
void setTextureCoordinates(Point2f[] texCoords)
Sets the TextureCoordinates array. There are other setTextureCoordinates methods.
Each of the GeometryInfo 'helper' classes are used in a way similar to the GeometryInfo class. The
following reference blocks show the constructors and methods for Triangulator, Stripifier, and
NormalGenerator, in that order. This is the order in which they would be used for a POLYGON_ARRAY.
The Triangulator utility is only used with POLYGON_ARRAY geometry. GeometryInfo objects with
other primitive geometry would only use Stripifier and NormalGenerator, as appropriate.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-12
The default constructor of the Triangulator class simply creates a Triangulation object. See the reference
block for more information.
Triangulator Constructor Summary
Package: com.sun.j3d.utils.geometry
Extends: java.lang.Object
Triangulator is a utility for turning arbitrary polygons into triangles so they can be rendered by Java 3D. Polygons
can be concave, nonplanar, and can contain holes (see GeometryInfo).
Triangulator()
Creates a new instance of the Triangulator.
The only method of the Triangulator class is to triangulate a polygon array GeometryInfo object.
Triangulator Method Summary
void triangulate(GeometryInfo gi)
This routine converts the GeometryInfo object from primitive type POLYGON_ARRAY to primitive type
TRIANGLE_ARRAY using polygon decomposition techniques.
The only constructor of the Stripifier class creates a stripification object
5
.
Stripifier Constructor Summary
Package: com.sun.j3d.utils.geometry
Extends: java.lang.Object
The Stripifier utility will change the primitive of the GeometryInfo object to Triangle Strips. The strips are made
by analyzing the triangles in the original data and connecting them together.
For best results Normal Generation should be performed on the GeometryInfo object before Stripification.
Stripifier()
Creates the Stripifier object.
The only method of the Stripifier class is to stripify the geometry of a GeometryInfo class.
Stripifier Method Summary
void stripify(GeometryInfo gi)
Turn the geometry contained in the GeometryInfo object into an array of Triangle Strips.
The NormalGenerator class has two constructors. The first constructs a NormalGenerator with a default
value for the crease angle. The second constructor allows the specification of a crease angle with the
construction of the NormalGenerator object. See the reference block below.
5
Each paragraph introduces a new word into the English language.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-13
NormalGenerator Constructor Summary
Package: com.sun.j3d.utils.geometry
Extends: java.lang.Object
The NormalGenerator utility will calculate and fill in the normals of a GeometryInfo object. The calculated
normals are estimated based on an analysis of the indexed coordinate information. If your data isn't indexed, index
lists will be created.
If two (or more) triangles in the model share the same coordinate index then the normal generator will attempt to
generate one normal for the vertex, resulting in a "smooth" looking surface. If two coordinates don't have the same
index then they will have two separate normals, even if they have the same position. This will result in a "crease"
in your object. If you suspect that your data isn't properly indexed, call GeometryInfo.recomputeIndexes().
Of course, sometimes your model has a crease in it. If two triangles' normals differ by more than creaseAngle,
then the vertex will get two separate normals, creating a discontinuous crease in the model. This is perfect for the
edge of a table or the corner of a cube, for instance.
NormalGenerator()
Construct a NormalGenerator with the default crease angle (0.76794 radians, or 44).
NormalGenerator(double radians)
Construct a NormalGenerator with a specified crease angle in radians.
The methods for the NormalGenerator class include ones for setting and getting the crease angle, and
computing normals for the geometry of a GeometryInfo object. See the NormalGenerator Constructor
Summary reference block for a discussion of crease angle.
NormalGenerator Method Summary
void generateNormals(GeometryInfo geom)
Generate normals for the GeometryInfo object.
double getCreaseAngle()
Returns the current value of the crease angle, in radians.
void setCreaseAngle(double radians)
Set the crease angle in radians.
3.4 Text2D
There are two ways to add text to a Java 3D scene. One way uses the Text2D class and the other way uses
the Text3D class. Obviously, one significant difference is that Text2D objects are two dimensional and
Text3D objects are three dimensional. Another significant difference is how these objects are created.
Text2D objects are rectangular polygons with the text applied as a texture (texturing is the subject of
Chapter 7). Text3D objects are 3D geometric objects created as an extrusion of the text. See Section 3.5
for more information on the Text3D class and related classes.
As a subclass of Shape3D, instances of Text2D can be children of group objects. To place a Text2D
object in a Java 3D scene, simply create the Text2D object and add it to the scene graph. Figure 3-5
presents this simple recipe.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-14
1. Create a Text2D object
2. Add it to the scene graph
Figure 3-5 Recipe for Text2D
Text2D objects are implemented using a polygon and a texture. The polygon is transparent so that only the
texture is visible. The texture is of the text string set in the named typeface with the specified font
parameters
6
. The typefaces available on your system will vary. Typically, Courier, Helvetica, and
TimesRoman typefaces will be available, among others. Any font available in the AWT is available to you
for Text2D (and Text3D) applications. Using a Text2D object is straightforward as demonstrated in the
next section.
3.4.1 Simple Text2D Example
Code Fragment 3-3 shows an example of adding a Text2D object to a scene. The Text2D object is created
on lines 21 through 23. In this constructor, the text string, color, typeface, size, and font style are
specified. The Text2D object is added to the scene graph on line 24. Note the import statement for Font
(line 5) used for the font style constants.
1. import java.applet.Applet;
2. import java.awt.BorderLayout;
3. import java.awt.Frame;
4. import java.awt.event.*;
5. import java.awt.Font;
6. import com.sun.j3d.utils.applet.MainFrame;
7. import com.sun.j3d.utils.geometry.Text2D;
8. import com.sun.j3d.utils.universe.*;
9. import javax.media.j3d.*;
10. import javax.vecmath.*;
11.
12. // Text2DApp renders a single Text2D object.
13.
14. public class Text2DApp extends Applet {
15.
16. public BranchGroup createSceneGraph() {
17. // Create the root of the branch graph
18. BranchGroup objRoot = new BranchGroup();
19.
20. // Create a Text2D leaf node, add it to the scene graph.
21. Text2D text2D = new Text2D("2D text is a textured polygon",
22. new Color3f(0.9f, 1.0f, 1.0f),
23. "Helvetica", 18, Font.ITALIC));
24. objRoot.addChild(text2D);
Code Fragment 3-3 A Text2D Object Created (excerpt from Text2DApp.java)
Text2DApp.java is a complete program that includes the above Code Fragment. In this example, the
Text2D object rotates about the origin in the scene. As the application runs you can see, by default, the
textured polygon is invisible when viewed from behind.
6
A font is a specific typeface set at a size with a set of font style attributes. Refer to the glossary for definitions of
font and typeface.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-15
Figure 3-6 Image from Text2DApp.java
Some attributes of a Text2D object can be changed by modifying the referenced appearance bundle and/or
Geometry NodeComponent. Code Fragment 3-4 shows the code to make text2d, the Text2D object
created in Code Fragment 3-3, two-sided through modification of its appearance bundle.
25. Appearance textAppear = text2d.getAppearance();
26.
27. // The following 4 lines of code make the Text2D object 2-sided.
28. PolygonAttributes polyAttrib = new PolygonAttributes();
29. polyAttrib.setCullFace(PolygonAttributes.CULL_NONE);
30. polyAttrib.setBackFaceNormalFlip(true);
31. textAppear.setPolygonAttributes(polyAttrib);
Code Fragment 3-4 Making a Two-sided Text2D Object.
The texture created by one Text2D object can be applied to other visual objects as well. Since the
application of textures to visual objects is the subject of Chapter 7, the details on this are left until then.
3.4.2 Classes Used in Creating Text2D Objects
The only class needed is the Text2D class. As you can see from Figure 3-7, Text2D is a utility class which
extends Shape3D.
java.lang.Object
javax.media.j3d.SceneGraphObject
javax.media.j3d.Node
javax.media.j3d.Leaf
javax.media.j3d.Shape3D
com.sun.j3d.utils.geometry.Text2D
Figure 3-7 The Class Hierarchy for Text2D
In the Text2D constructor, the text string, typeface, font size, and font style are specified.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-16
Text2D Constructor Summary
Package: com.sun.j3d.utils.geometry
This class creates a texture-mapped rectangle which displays the text string sent in by the user, given the
appearance parameters also supplied by the user. The size of the rectangle (and its texture map) is determined by
the font parameters passed in to the constructor. The resulting Shape3D object is a transparent (except for the text)
rectangle located at (0, 0, 0) and extending up the positive y-axis and out the positive x-axis.
Text2D(java.lang.String text, Color3f color, java.lang.String fontName, int
fontSize, int fontStyle)
Constructor.
With the Text2D constructor, there is one method. This method sets a scale factor to create Text2D
objects larger or smaller than the specified point size. This method is not useful in version 1.1.x of the
API, since it is only utilized when the text is specified. In version 1.2 a setText() method will be
introduced making the setRectangleScaleFactor() useful.
Text2D Method Summary
void setRectangleScaleFactor(float newScaleFactor)
Sets the scale factor used in converting the image width/height to width/height values in 3D.
3.5 Text3D
Another way to add text to a Java 3D virtual world is to create a Text3D object for the text. Where
Text2D creates text with a texture, Text3D creates text using geometry. The textual geometry of a Text3D
object is an extrusion of the font.
Creating a Text3D object is a little more involved than creating a Text2D object. The first step is to create
a Font3D object of the desired typeface, size, and font style. Then a Text3D object for a particular string
is made using the Font3D object. Since the Text3D class is a subclass of Geometry, the Text3D object is a
NodeComponent that is referenced by one or more Shape3D object(s). Figure 3-8 summarizes the process
of adding Text3D objects to a scene graph.
1. Create a Font3D object from an AWT Font
2. Create Text3D for a string using the Font3D object, optionally specifying a reference point
3. Reference the object from a Shape3D object added to the scene graph
Figure 3-8 Recipe for Creating a Text3D Object
3.5.1 Simple Text3D Example
Code Fragment 3-5 shows the basic construction of a Text3D object. The Font3D object is created on
lines 19 and 20. The typeface used here is "Helvetica". Just like with Text2D, any typeface available in
the AWT can be used for Font3D and therefore Text3D objects. This Font3D constructor (lines 19 and 20
of Code Fragment 3-5) also sets the font size to 10 points and uses the default extrusion.
The statement on lines 21 and 22 create a Text3D object using the newly created Font3D object for the
string "3DText" while specifying a reference point for the object. The last two statements create a
Shape3D object for the Text3D object and add it to the scene graph. Note the import statement for Font
(line 5) is necessary since a Font object is used in the Font3D creation.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-17
1. import java.applet.Applet;
2. import java.awt.BorderLayout;
3. import java.awt.Frame;
4. import java.awt.event.*;
5. import java.awt.Font;
6. import com.sun.j3d.utils.applet.MainFrame;
7. import com.sun.j3d.utils.universe.*;
8. import javax.media.j3d.*;
9. import javax.vecmath.*;
10.
11. // Text3DApp renders a single Text3D object.
12.
13. public class Text3DApp extends Applet {
14.
15. public BranchGroup createSceneGraph() {
16. // Create the root of the branch graph
17. BranchGroup objRoot = new BranchGroup();
18.
19. Font3D font3d = new Font3D(new Font("Helvetica", Font.PLAIN, 10),
20. new FontExtrusion());
21. Text3D textGeom = new Text3D(font3d, new String("3DText"),
22. new Point3f(-2.0f, 0.0f, 0.0f));
23. Shape3D textShape = new Shape3D(textGeom);
24. objRoot.addChild(textShape);
Code Fragment 3-5 Creating a Text3D Visual Object
Figure 3-9 shows a Text3D object illuminated to illustrate the extrusion of the type. In the figure, the
extrusion is shown in gray while the type is shown in black. To recreate this figure in Java 3D, a Material
object and a DirectionalLight is necessary. Since Chapter 6 covers these topics, they are not discussed
here. You can't set the color of the individual vertices in the Text3D object since you don't have access to
the geometry of the Text3D object.
extrusion
reference
point
Figure 3-9 The Default Reference Point and Extrusion for a 3DText Object
The text of a Text3D object can be oriented in a variety of ways. The orientation is specified as a path
direction. The choices are right, left, up, and down. See Table 3-2 and the Text3D reference blocks
(beginning on page 3-19) for more information.
Each Text3D object has a reference point. The reference point for a Text3D object is the origin of the
object. The reference point for each object is defined by the combination of the path and alignment of the
text. Table 3-2 shows the effects of path and alignment specification on the orientation of the text and
placement of the reference point.
The placement of the reference point can be defined explicitly overriding the path and alignment
positioning. See the Text3D reference blocks (beginning on page 3-19) for more information.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-18
Table 3-2 The Orientation of Text and Position of the Reference Point for Combinations of Text3D
Alignment and Path
ALIGN_FIRST
(default)
ALIGN_CENTER ALIGN_LAST
PATH_RIGHT
(default)
Text3D Text3D Text3D
PATH_LEFT
D3txeT D3txeT D3txeT
PATH_DOWN T
e
x
t
T
e
x
t
T
e
x
t
PATH_UP t
x
e
T
t
x
e
T
t
x
e
T
Text3D objects have normals. The addition of an appearance bundle that includes a Material object to a
Shape3D object referencing Text3D geometry will enable lighting for the Text3D object.
3.5.2 Classes Used in Creating Text3D Objects
This section presents reference material for the three classes used in creating Text3D objects: Text3D,
Font3D, and FontExtrusion, in that order. Figure 3-10 shows the class hierarchy for Text3D class.
java.lang.Object
javax.media.j3d.SceneGraphObject
javax.media.j3d.NodeComponent
javax.media.j3d.Geometry
javax.media.j3d.Text3D
Figure 3-10 Class Hierarchy for Text3D
The Text3D class defines a number of constructors. Each constructor allows you to specify none, some, or
all of the attributes of a Text3D object. The following reference block lists the constructors, along with the
default values, for Text3D.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-19
Text3D Constructor Summary
A Text3D object is a text string that has been converted to 3D geometry. The Font3D object determines the
appearance of the Text3D NodeComponent object. Each Text3D object has a position - a reference point placing
the Text3D object. The 3D text can be placed around this position using different alignments and paths.
Text3D()
Creates an empty Text3D object. The default values used for this, and other constructors as appropriate, are:
font 3D null
string null
position (0,0,0)
alignment ALIGN_FIRST
path PATH_RIGHT
character spacing 0.0
Text3D(Font3D font3D)
Creates a Text3D object with the given Font3D object.
Text3D(Font3D font3D, String string)
Creates a Text3D object given a Font3D object and a string.
Text3D(Font3D font3D, String string, Point3f position)
Creates a Text3D object given a Font3D object and a string. The position point defines a reference point for the
Text3D object. Its position is defined relative to the lower left front corner of the geometry.
Text3D(Font3D font3D, String string, Point3f position,
int alignment, int path)
Creates a Text3D object given a Font3D object and a string.
ALIGN_CENTER alignment: the center of the string is placed on the position point.
ALIGN_FIRST alignment: the first character of the string is placed on the position point.
ALIGN_LAST alignment: the last character of the string is placed on the position point.
PATH_DOWN path: succeeding glyphs are placed below the current glyph.
PATH_LEFT path: succeeding glyphs are placed to the left of the current glyph.
PATH_RIGHT path: succeeding glyphs are placed to the right of the current glyph.
PATH_UP path: succeeding glyphs are placed above the current glyph.
See Table 3-2 for examples.
The Text3D class also defines a number of methods. Each allows you to modify (set) the attributes of the
Text3D object. This class also defines corresponding get* methods. The following reference block lists
the set* methods for the Text3D class.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-20
Text3D Method Summary
void setAlignment(int alignment)
Sets the text alignment policy for this Text3D NodeComponent object.
void setCharacterSpacing(float characterSpacing)
Sets the character spacing to be used when constructing the Text3D string.
void setFont3D(Font3D font3d)
Sets the Font3D object used by this Text3D NodeComponent object.
void setPath(int path)
Sets the node's path direction.
void setPosition(Point3f position)
Sets the node's reference point to the supplied parameter.
void setString(java.lang.String string)
Copies the character string from the supplied parameter into the Text3D node.
The following reference block lists the Capabilities of the Text3D class.
Text3D Capabilities Summary
ALLOW_ALIGNMENT_READ | WRITE allow reading (writing) the text alignment value.
ALLOW_BOUNDING_BOX_READ allow reading the text string bounding box value
ALLOW_CHARACTER_SPACING_READ | WRITE allow reading (writing) the text character spacing value.
ALLOW_FONT3D_READ | WRITE allow reading (writing) Font3D component information.
ALLOW_PATH_READ | WRITE allow reading (writing) the text path value.
ALLOW_POSITION_READ | WRITE allow reading (writing) the text position value.
ALLOW_STRING_READ | WRITE allow reading (writing) the String object.
Each Text3D object is created from a Font3D object. A single Font3D object can be used to create an
unlimited number of Text3D objects
7
. A Font3D object holds the extrusion geometry for each glyph in the
typeface. A Text3D object copies the geometry to form the specified string. Font3D objects can be
garbage collected without affecting Text3D objects created from them.
The following reference block shows the constructor for the Font3D class.
7
Of course, memory constraints will limit the actual number of Text3D objects to some number significantly less
than infinity.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-21
Font3D Constructor Summary
Extends: java.lang.Object
A 3D Font consists of a Java 2D font and an extrusion path. The extrusion path describes how the edge of a glyph
varies in the Z axis. The Font3D object is used to store extruded 2D glyphs. These 3D glyphs can then be used to
construct Text3D NodeComponent objects. Custom 3D fonts as well as methods to store 3D fonts to disk will be
addressed in a future release.
See Also: java.awt.Font, FontExtrusion, Text3D
Font3D(java.awt.Font font, FontExtrusion extrudePath)
Creates a Font3D object from the specified Font object.
The following reference block lists the methods of the Font3D class. Normally, get* methods are not
listed in reference blocks in this tutorial. However, since the Font3D class has no set* methods, the
Font3D get* methods are listed here. The effect of a set* method would be essentially the same as
invoking a constructor, so to keep the class smaller, no set* methods are defined.
Font3D Method Summary
void getBoundingBox(int glyphCode, BoundingBox bounds)
Returns the 3D bounding box of the specified glyph code.
java.awt.Font getFont()
Returns the Java 2D Font used to create this Font3D object.
void getFontExtrusion(FontExtrusion extrudePath)
Copies the FontExtrusion object used to create this Font3D object into the specified parameter.
The Font class is used in creating a Font3D object. The following reference block lists one constructor for
Font. Other constructors and many methods are not listed in this tutorial. See the Java 3D API
Specification for details.
Font Constructor Summary (partial list)
Package: java.awt
An AWT class that creates an internal representation of fonts. Font extends java.lang.Object.
public Font(String name, int style, int size)
Creates a new Font from the specified name, style and point size.
Parameters:
name - the typeface name. This can be a logical name or a typeface name. A logical name must be one of:
Dialog, DialogInput, Monospaced, Serif, SansSerif, or Symbol.
style - the style constant for the Font. The style argument is an integer bitmask that may be PLAIN, or a
bitwise union of BOLD and/or ITALIC (for example, Font.ITALIC or Font.BOLD|Font.ITALIC). Any
other bits set in the style parameter are ignored. If the style argument does not conform to one of the expected
integer bitmasks then the style is set to PLAIN.
size - the point size of the Font
The following reference block lists the constructors for the FontExtrusion class.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-22
FontExtrusion Constructor Summary
Extends: java.lang.Object
The FontExtrusion object is used to describe the extrusion path for a Font3D object. The extrusion path is used in
conjunction with a Font2D object. The extrusion path defines the edge contour of 3D text. This contour is
perpendicular to the face of the text. The extrusion has its origin at the edge of the glyph with 1.0 being the height
of the tallest glyph. Contour must be monotonic in x. User is responsible for data sanity and must make sure that
extrusionShape does not cause intersection of adjacent glyphs or within single glyph. The output is undefined for
extrusions that cause intersections.
FontExtrusion()
Constructs a FontExtrusion object with default parameters.
FontExtrusion(java.awt.Shape extrusionShape)
Constructs a FontExtrusion object with the specified shape.
The following reference block lists the methods for the FontExtrusion class.
FontExtrusion Method Summary
java.awt.Shape getExtrusionShape()
Gets the FontExtrusion's shape parameter.
void setExtrusionShape(java.awt.Shape extrusionShape)
Sets the FontExtrusion's shape parameter.
3.6 Background
By default, the background of a Java 3D virtual universe is solid black. However, you can specify other
backgrounds for your virtual worlds. The Java 3D API provides an easy way to specify a solid color, an
image, geometry, or a combination of these, for a background.
When specifying an image for the background, it overrides a background color specification, if any. When
geometry is specified, it is drawn on top of the background color or image.
The only tricky part is in the specification of a geometric background. All background geometry is
specified as points on a unit sphere. Whether your geometry is a PointArray, which could represent stars
light years away, or a TriangleArray, which could represent mountains in the distance, all coordinates are
specified at a distance of one unit. The background geometry is projected to infinity when rendered.
Background objects have Application bounds which allows different backgrounds to be specified for
different regions of the virtual world. A Background node is active when its application region intersects
the ViewPlatform's activation volume.
If multiple Background nodes are active, the Background node that is "closest" to the eye will be used. If
no Background nodes are active, then the window is cleared to black. However, the definition of "closest"
is not specified. For closest, the background with the innermost application bounds that encloses the
ViewPlatform is chosen.
It is unlikely that your application will need lit background geometry - in reality the human visual system
can't perceive visual detail at great distances. However, a background geometry can be shaded. The
background geometry subgraph may not contain Lights, but Lights defined in the scene graph can influence
background geometry.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-23
To create a background, follow the simple recipe given in Figure 3-11. Example backgrounds are
presented in the next section.
1. Create Background object specifying a color or an image
2. Add geometry (optional)
3. Provide an Application Boundary or BoundingLeaf
4. Add the Background object to the scene graph
Figure 3-11 Recipe for Backgrounds
3.6.1 Background Examples
As explained in the previous section, a background can have either a color or an image. Geometry can
appear in the background with either the color or image. This section provides an example of a solid white
background. A second example shows adding geometry to a background.
Colored Background Example
As shown in Figure 3-11, the recipe for creating a solid color background is straightforward. The lines of
code in Code Fragment 3-6 correspond to the recipe steps. The besides customizing the color, the only
other possible adjustment to this code would be to define a more appropriate application bounds for the
background (or use a BoundingLeaf).
1. Background backg = new Background(1.0f, 1.0f, 1.0f);
2. //
3. backg.setApplicationBounds(BoundingSphere());
4. contentRoot.addChild(backg);
Code Fragment 3-6 Adding a Colored Background
Geometry Background Example
Once again, the lines of code in Code Fragment 3-7 correspond to the background recipe steps shown in
Figure 3-11. In this code fragment, the createBackGraph() method is invoked to create the
background geometry. This method returns a BranchGroup object. For a more complete example, see
BackgroundApp.java in the examples/easyContent directory.
1. Background backg = new Background(); //black background
2. backg.setGeometry(createBackGraph()); // add BranchGroup of background
3. backg.setApplicationBounds(new BoundingSphere(new Point3d(), 100.0));
4. objRoot.addChild(backg);
Code Fragment 3-7 Adding a Geometric Background
BackgroundApp.java
To appreciate a Background, you need to experience it. BackgroundApp.java, a program
included in the examples/easyContent directory, is a complete working application with a geometric
background. This application allows you to move in the Java 3D virtual world. While moving, you can
see the relative movement between the local geometry and the background geometry.
BackgroundApp uses the KeyNavigatorBehavior class provided in the utility library for viewer motion.
Interaction (as implemented through behaviors) is the subject of Chapter 4, so the details of this
programming is delayed until then.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-24
KeyNavigatorBehavior responds to the arrow keys, PgUp, and PgDn keys for motion. The Alt key also
plays a role (more details in Chapter 4). When you run BackgroundApp, be sure to rotate to find the
constellation, as well as travel far into the distance.
Figure 3-12 Viewing the Constellation in the Background of BackgroundApp.java
3.6.2 Background Class
Figure 3-13 shows the class hierarchy for Background class. As an extension of Leaf class, an instance of
Background class can be a child of a Group object.
java.lang.Object
javax.media.j3d.SceneGraphObject
javax.media.j3d.Node
javax.media.j3d.Leaf
javax.media.j3d.Background
Figure 3-13 The Class Hierarchy for Background
Background has a variety of constructors. Background constructors with parameters allow the specification
of a color or an image for a background. The following reference block gives more detail. Background
Geometry can only be specified through the appropriate method.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-25
Background Constructor Summary
The Background leaf node defines either a solid background color or a background image that is used to fill the
window at the beginning of each new frame. It optionally allows background geometry to be referenced.
Background geometry must be pre-tessellated onto a unit sphere and is drawn at infinity. It also specifies an
application region in which this background is active.
Background()
Constructs a Background node with a default color (black).
Background(Color3f color)
Constructs a Background node with the specified color.
Background(float r, float g, float b)
Constructs a Background node with the specified color.
Background(ImageComponent2D image)
Constructs a Background node with the specified image.
Any attribute of a Background can be set through a method. The following reference block lists the
methods of the Background class.
Background Method Summary
void setApplicationBoundingLeaf(BoundingLeaf region)
Set the Background's application region to the specified bounding leaf.
void setApplicationBounds(Bounds region)
Set the Background's application region to the specified bounds.
void setColor(Color3f color)
Sets the background color to the specified color.
void setColor(float r, float g, float b)
Sets the background color to the specified color.
void setGeometry(BranchGroup branch)
Sets the background geometry to the specified BranchGroup node.
void setImage(ImageComponent2D image)
Sets the background image to the specified image.
The following reference block lists the capability bits of the Background class.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-26
Background Capabilities Summary
ALLOW_APPLICATION_BOUNDS_READ | WRITE allow read (write) access to its application bounds
ALLOW_COLOR_READ | WRITE allow read (write) access to its color
ALLOW_GEOMETRY_READ | WRITE allow read (write) access to its background geometry
ALLOW_IMAGE_READ | WRITE allow read (write) access to its image
3.7 BoundingLeaf
Bounds are used with lights, behaviors, backgrounds, and a variety of other applications in Java 3D.
Bounds allow the programmer to vary action, appearance, and/or sound over the virtual landscape. Bounds
specification also allows the Java 3D rendering system to perform execution culling, thereby improving
rendering performance
8
.
The typical bounds specification utilizes a Bounds object to specify a bounding region. In the resulting
scene graph the Bounds object moves with the object that references it. This is fine for many applications;
however, there may be situations in which it is desirable to have the bounding region move independently of
the object using the bounds.
For example, if a world includes a stationary light source that illuminates moving objects, the bounds for
the light must include the moving object. One way to handle this would be to make the bounds large
enough to include all of the places the object moves. This is not the best answer in most cases. A better
solution is to use a BoundingLeaf. Placed in the scene graph with the visual object, the BoundingLeaf
object moves with the visual object and independently of the light source. Figure 3-14 shows a scene graph
in which a light uses a BoundingLeaf node.
BG
TG
Appearance
S
Geometry
L
BL
TG
Figure 3-14 BoundlingLeaf Moves with a Visual Object and Independently of a Light Source
While the applications for BoundingLeaf include the ApplicationBounds of Background objects (Section
3.5), the SchedulingBounds of Behaviors (Section 4.2), and the InfluencingBounds of Lights (Section 6.6),
it would not make sense to repeat this information in all three places
9
.
8
Bounds should be chosen as small as possible, while still achieving the desired effect, to reduce the computation
required to render the Java 3D scene.
9
BoundingLeaf nodes are also useful for fog, clip, sound, and soundscape objects, which are not covered in this
tutorial.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-27
One interesting application of a BoundingLeaf object places a BoundingLeaf in the viewPlatform. This
BoundingLeaf can be used for an "always on" scheduling bounds for a Behavior, or "always applies"
application bounds for Background or Fog. Code Fragment 3-8 presents an example "always applies"
BoundingLeaf application used with a Background. Another example application of a BoundingLeaf is
presented in Section 6.6.
Code Fragment 3-8 presents an example of adding a BoundingLeaf as a child of the PlatformGeometry to
provide an "always applies" bounds for a Background
10
. In this code, the standard
createSceneGraph() method is modified to takes a single parameter, that of the SimpleUniverse
object
11
. This is necessary for creating a PlatformGeometry object.
Lines 2, 3, and 4, create the BoundingLeaf object, create the PlatformGeometry object, and make the
BoundingLeaf object a child of the PlatformGeometry, in that order. If there were to be more to the
PlatformGeometry, it would be added at this point. The PlatformGeometry object is then added to the view
branch graph in line 6.
The BoundingLeaf object is set as the application bounds for the background object on line 11. This same
BoundingLeaf can be used for other purposes in this program. For example, it can also be used for
behaviors. Note that using the BoundingLeaf in this program as the InfluencingBoundingLeaf of a light
would not make the light influence all objects in the virtual world.
1. void createSceneGraph (SimpleUniverse su) {
2. BoundingLeaf boundingLeaf = new BoundingLeaf();
3. PlatformGeometry platformGeom = new PlatformGeometry();
4. platformGeom.addChild(boundingLeaf);
5. platformGeom.compile();
6. simpleUniv.getViewingPlatform().setPlatformGeometry(platformGeom);
7.
8. BranchGroup contentRoot = new BranchGroup();
9.
10. Background backg = new Background(1.0f, 1.0f, 1.0f);
11. backg.setApplicationBoundingLeaf(boundingLeaf);
12. contentRoot.addChild(backg);
Code Fragment 3-8 Adding a BoundingLeaf to the View Platform for an "Always-On" Bounds
3.7.1 BoundingLeaf Class
The BoundingLeaf class extends Leaf class. Figure 3-15 presents the complete class hierarchy for
BoundingLeaf.
10
PlatformGeometry moves with the viewer, so it is the appropriate parent for geometry associated with a viewer.
For example, if the viewer is to be riding in a vehicle, it would be appropriate to make the geometry that represents
the instrumentation of the vehicle a child of PlatformGeometry.
11
The createSceneGraph() method is only standard in that is keeps appearing in the examples of this tutorial.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-28
java.lang.Object
javax.media.j3d.SceneGraphObject
javax.media.j3d.Node
javax.media.j3d.Leaf
javax.media.j3d.BoundingLeaf
Figure 3-15 Java 3D API Class Hierarchy for BoundingLeaf
The parameterless constructor for BoundingLeaf creates a bounds of a unit sphere. The other constructor
allows the specification of the bounds for the BoundingLeaf object. The following reference block lists the
two BoundingLeaf constructors.
BoundingLeaf Constructor Summary
The BoundingLeaf node defines a bounding region object that can be referenced by other nodes to define a region
of influence, an activation region, or a scheduling region.
BoundingLeaf()
Constructs a BoundingLeaf node with a unit sphere object.
BoundingLeaf(Bounds region)
Constructs a BoundingLeaf node with the specified bounding region.
The following reference block lists the two methods of BoundingLeaf. The get* method is listed since its
parameters are different than that of the corresponding set* method.
BoundingLeaf Method Summary
Bounds getRegion()
Retrieves this BoundingLeaf's bounding region
void setRegion(Bounds region)
Sets this BoundingLeaf node's bounding region.
3.8 User Data
Any SceneGraphObject can reference any object as user data
12
. First, you should realize that nearly every
Java 3D API core class is a descendant of SceneGraphObject. The list of descendants of
SceneGraphObject includes Appearance, Background, Behavior, BranchGroup, Geometry, Lights,
Shape3D, and TransformGroup.
12
This is not limited to Java 3D API classes, but any class derived from java.lang.Object.
Getting Started with Java 3D Chapter 3. Easier Content Creation
The Java 3D Tutorial 3-29
The applications for this, the UserData field, are limited only by your imagination. For example, an
application may have a number of pickable objects. Each of these objects could have some text
information stored in the user data object. When a user picks an object, the user data text can be displayed.
Another application could store some calculated value for a scene graph object such as its position in
virtual world coordinates. Yet another application could store some behavior specific information that
could control a behavior applied to a variety of objects.
SceneGraphObject Methods (Partial List - User Data Methods)
SceneGraphObject is a common superclass for all scene graph component objects. This includes Node, Geometry,
Appearance, etc.
java.lang.Object getUserData()
Retrieves the userData field from this scene graph object.
void setUserData(java.lang.Object userData)
Sets the userData field associated with this scene graph object.
3.9 Chapter Summary
This chapter presents the Java 3D features for easier content creation. Loader utilities and GeometryInfo
classes are the primary easy content creation techniques. These topics are covered in sections 3.2 and 3.3,
respectively. Text is added to the Java 3D world using Text2D and Text3D classes in sections 3.4 and 3.5.
Background is covered in detail in section 3.6 and BoundingLeaf is covered in section 3.7. Section 3.8
presents the UserData field of the SceneGraphObject class. You are reading section 3.9.
3.10 Self Test
1. Using the wire frame view in the GeomInfoApp.java program, you can see the effect of the
triangulation. Using the example program as a starting point, change the specification of the polygons
to use three polygons (one for each side, and one for the roof, hood, trunk lid and other surfaces). How
does the Triangulator do with this surface?
2. The code to make the Text2D object visible from both sides is included in Text2DApp.java. You
can uncomment the code, recompile and run it. Other experiments with this program include using the
texture from the Text2D object on other visual objects. For example, try adding a geometric primitive
and apply the texture to that object. Of course, you may want to wait until you read Chapter 7 for this
exercise.
3. Using Text3DApp.java as a starting point, experiment with the various alignment and path
settings. Other experiments include changing the appearance of the Text3D object.
4. Playing with the BackgroundApp.java example program, if you move far enough away from the
origin of the virtual world the background disappears. Why does this happen? If you add another
Background object to the BackgroundApp, what will the effect be?
Tutorial version 1.5 (Java 3D API v 1.1.2)
Getting Started with
the Java 3D
API
Chapter 4
Interaction
BG
TG
View Platform
View Canvas3D Screen3D
Physical Body Physical Environment
S
TG
S
TG
S
TG
S
TG
S
TG
S
TG
TG
BG
B
Dennis J Bouvier
K Computing
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial
Sun Microsystems, Inc.
2550 Garcia Avenue, Mountain View, California 94043-1100 U.S.A
All Rights Reserved.
The information contained in this document is subject to change without notice.
SUN MICROSYSTEMS PROVIDES THIS MATERIAL "AS IS" AND MAKES NO WARRANTY OF ANY KIND,
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS SHALL NOT BE
LIABLE FOR ERRORS CONTAINED HEREIN OR FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES
(INCLUDING LOST PROFITS IN CONNECTION WITH THE FURNISHING, PERFORMANCE OR USE OF
THIS MATERIAL, WHETHER BASED ON WARRANTY, CONTRACT, OR OTHER LEGAL THEORY).
THIS DOCUMENT COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE
PERIODICALLY MADE TO THE INFORMATION HEREIN; THESE CHANGES WILL BE INCORPORATED IN NEW
EDITIONS OF THE PUBLICATION. SUN MICROSYSTEMS, INC. MAY MAKE IMPROVEMENTS AND/OR CHANGES
IN THE PRODUCT(S) AND/OR PROGRAM(S) DESCRIBED IN THIS PUBLICATION AT ANY TIME.
Some states do not allow the exclusion of implied warranties or the limitations or exclusion of liability for incidental or
consequential damages, so the above limitations and exclusion may not apply to you. This warranty gives you specific legal
rights, and you also may have other rights which vary from state to state.
Permission to use, copy, modify, and distribute this documentation for NON-COMMERCIAL purposes and without fee is
hereby granted provided that this copyright notice appears in all copies.
This documentation was prepared for Sun Microsystems by K Computing (530 Showers Drive, Suite 7-225, Mountain View,
CA 94040, 770-982-7881, www.kcomputing.com). For further information about course development or course delivery,
please contact either Sun Microsystems or K Computing.
Java, JavaScript, Java 3D, HotJava, Sun, Sun Microsystems, and the Sun logo are trademarks or registered trademarks of Sun
Microsystems, Inc. All other product names mentioned herein are the trademarks of their respective owners.
Module 2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-i
Table of Contents
Chapter 4:
Interaction ...........................................................................................................................................4-1
4.1 Behavior: the Base for Interaction and Animation ......................................................................4-1
4.1.1 Applications of Behavior ...................................................................................................4-2
4.1.2 Overview of Behavior Classes ...........................................................................................4-3
4.2 Behavior Basics ........................................................................................................................4-3
4.2.1 Writing a Behavior Class ..................................................................................................4-4
4.2.2 Using a Behavior Class .....................................................................................................4-7
4.2.3 Behavior Class API .........................................................................................................4-10
4.3 Wakeup Conditions: How Behaviors are Triggered ..................................................................4-12
4.3.1 WakeupCondition ...........................................................................................................4-13
4.3.2 WakeupCriterion .............................................................................................................4-13
4.3.3 Specific WakeupCriterion Classes ...................................................................................4-14
4.3.4 WakeupCondition Composition....................................................................................... 4-24
4.4 Behavior Utility Classes for Keyboard Navigation ...................................................................4-25
4.4.1 Simple KeyNavigatorBehavior Example Program ............................................................4-26
4.4.2 KeyNavigatorBehavior and KeyNavigator Classes ...........................................................4-28
4.5 Utility Classes for Mouse Interaction ......................................................................................4-29
4.5.1 Using the Mouse Behavior Classes ..................................................................................4-29
4.5.2 Mouse Behavior Foundation............................................................................................ 4-31
4.5.3 Specific Mouse Behavior Classes ....................................................................................4-32
4.5.4 Mouse Navigation ...........................................................................................................4-34
4.6 Picking ...................................................................................................................................4-35
4.6.1 Using Picking Utility Classes .......................................................................................... 4-38
4.6.2 Java 3D API Core Picking Classes .................................................................................. 4-40
4.6.3 General Picking Package Classes .....................................................................................4-44
4.6.4 Specific Picking Behavior Classes ...................................................................................4-48
4.7 Chapter Summary ...................................................................................................................4-51
4.8 Self Test .................................................................................................................................4-51
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-ii
List of Figures
Figure 4-1 Hierarchy of Subclasses of Behavior ....................................................................................4-4
Figure 4-2 Recipe for Writing a Custom Behavior Class........................................................................4-5
Figure 4-3 Recipe for Using a Behavior Class........................................................................................4-8
Figure 4-4 Scene Graph Diagram of the Content Branch Graph Created in SimpleBehaviorApp.java......4-8
Figure 4-5 An Alternative Scene Graph Placement for the Behavior Object in SimpleBehaviorApp.......4-10
Figure 4-6 API Class Hierarchy for Behavior ......................................................................................4-11
Figure 4-7 The Java 3D API Class Hierarchy for WakeupCondition and Related Classes. ....................4-13
Figure 4-10 The Basic View Branch Graph Showing the View Platform Transform.............................4-26
Figure 4-11Recipe for Using the KeyNavigatorBehavior Utility Class..................................................4-26
Figure 4-12 Recipe for Using Mouse Behavior Classes ........................................................................4-30
Figure 4-13 Projection of PickRay in the Virtual World......................................................................4-36
Figure 4-14 Scene Graph Diagram for a Cube Composed of Discrete Shape3D Plane Objects. .............4-36
Figure 4-15 Recipe for Using Mouse Picking Utility Classes................................................................4-38
List of Tables
Table 4-1 Applications of Behavior Categorized by Stimulus and Object of Change..............................4-2
Table 4-2 The 14 Specific WakeupCriterion Classes............................................................................4-14
Table 4-3 KeyNavigatorBehavior Movements......................................................................................4-28
Table 4-4 Summary of Specific MouseBehavior Classes......................................................................4-29
List of Code Fragments
Code Fragment 4-1 SimpleBehavior Class in SimpleBehaviorApp.java ..................................................4-6
Code Fragment 4-2 CreateSceneGraph Method in SimpleBehaviorApp.java...........................................4-8
Code Fragment 4-3 Outline of OpenBehavior Class, an Example of Coordinated Behavior Classes.......4-17
Code Fragment 4-4 Code using OpenBehavior and CloseBehavior, Coordinated Behavior Classes........4-17
Code Fragment 4-5 Using the KeyNavigatorBehavior Class (part 1) ....................................................4-27
Code Fragment 4-6 Using the KeyNavigatorBehavior Class (part 2) ....................................................4-28
Code Fragment 4-7 Using the MouseRotate Utility Class.....................................................................4-30
Code Fragment 4-8 Using Mouse Behavior Classes for Interactive Navigation of the Virtual World. ....4-35
Code Fragment 4-9 The createSceneGraph Method of the MousePickApp Example Program. ..............4-39
List of Reference Blocks
Behavior Method Summary.................................................................................................................4-12
ViewPlatform Method Summary (partial list) ......................................................................................4-12
WakeupCondition Method Summary...................................................................................................4-13
WakeupCriterion Method Summary ....................................................................................................4-14
WakeupOnActivation Constructor Summary .......................................................................................4-15
WakeupOnAWTEvent Constructor Summary......................................................................................4-15
WakeupOnAWTEvent Method Summary............................................................................................4-16
WakeupOnBehaviorPost Constructor Summary...................................................................................4-16
WakeupOnBehaviorPost Method Summary.........................................................................................4-16
WakeupOnCollisionEntry Constructor Summary.................................................................................4-18
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-iii
WakeupOnCollisionExit Constructor Summary...................................................................................4-19
WakeupOnCollisionExit Method Summary .........................................................................................4-19
WakeupOnCollisionMovement Constructor Summary .........................................................................4-20
WakeupOnCollisionMovement Method Summary................................................................................4-20
WakeupOnDeactivation Constructor Summary....................................................................................4-21
WakeupOnElapsedFrames Constructor Summary................................................................................4-21
WakeupOnElapsedFrames Method Summary ......................................................................................4-21
WakeupOnElapsedTime Constructor Summary ...................................................................................4-21
WakeupOnElapsedTime Method Summary..........................................................................................4-22
WakeupOnSensorEntry Constructor Summary ....................................................................................4-22
WakeupOnSensorEntry Method Summary...........................................................................................4-22
WakeupOnSensorExit Constructor Summary ......................................................................................4-22
WakeupOnSensorExit Method Summary.............................................................................................4-22
WakeupOnTransformChange Constructor Summary ...........................................................................4-23
WakeupOnTransformChange Method Summary..................................................................................4-23
WakeupOnViewPlatformEntry Constructor Summary .........................................................................4-23
WakeupOnViewPlatformEntry Method Summary................................................................................4-23
WakeupOnViewPlatformExit Constructor Summary ...........................................................................4-24
WakeupOnViewPlatformExit Method Summary..................................................................................4-24
WakeupAnd Constructor Summary .....................................................................................................4-24
WakeupOr Constructor Summary .......................................................................................................4-24
WakeupAndOfOrs Constructor Summary............................................................................................4-25
WakeupOrOfAnds Constructor Summary............................................................................................4-25
KeyNavigatorBehavior Constructor Summary.....................................................................................4-29
KeyNavigatorBehavior Method Summary............................................................................................4-29
MouseBehavior Method Summary.......................................................................................................4-31
Interface MouseBehaviorCallback Method Summary...........................................................................4-31
MouseRotate Constructor Summary....................................................................................................4-32
MouseRotate Method Summary ..........................................................................................................4-32
MouseTranslate Constructor Summary................................................................................................4-33
MouseTranslate Method Summary......................................................................................................4-33
MouseZoom Constructor Summary.....................................................................................................4-34
MouseZoom Method Summary ...........................................................................................................4-34
Node Method (partial list) ...................................................................................................................4-37
Node Capabilities Summary (partial list) .............................................................................................4-37
PickShape...........................................................................................................................................4-40
PickBounds Constructor Summary......................................................................................................4-40
Method Summary................................................................................................................................4-40
PickPoint Constructor Summary..........................................................................................................4-41
PickPoint Method Summary................................................................................................................4-41
PickRay Constructor Summary ...........................................................................................................4-41
PickRay Method Summary..................................................................................................................4-41
PickSegment Constructor Summary.....................................................................................................4-42
PickSegment Method Summary...........................................................................................................4-42
SceneGraphPath Overview..................................................................................................................4-42
SceneGraphPath Constructor Summary...............................................................................................4-43
SceneGraphPath Method Summary (partial list) ..................................................................................4-43
BranchGroup and Locale picking methods for use with PickShape.......................................................4-44
PickMouseBehavior Method Summary................................................................................................4-45
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-iv
PickObject Constructor Summary .......................................................................................................4-45
PickObject Method Summary (partial list) ...........................................................................................4-45
Interface PickingCallback Method Summary .......................................................................................4-46
Intersect Constructor Summary ...........................................................................................................4-47
Intersect Method Summary (partial list)...............................................................................................4-47
PickRotateBehavior Constructor Summary..........................................................................................4-48
PickRotateBehavior Method Summary ................................................................................................4-49
PickTranslateBehavior Constructor Summary......................................................................................4-49
PickTranslateBehavior Method Summary............................................................................................4-50
PickZoomBehavior Constructor Summary...........................................................................................4-50
PickZoomBehavior Method Summary .................................................................................................4-51
Preface to Chapter 4
This document is one part of a tutorial on using the Java 3D API. You should be familiar with Java 3D
API basics to fully appreciate the material presented in this Chapter. Additional chapters and the full
preface to this material are presented in the Module 0 document available at:
http://java.sun.com/products/javamedia/3d/collateral
Cover Image
The cover image represents the interaction possible in Java 3D through the use of the mouse. The mouse
appears to be connected to the window with a visual, the cube, but the wire proceeds to the scene graph
diagram to the Behavior object. The scene graph diagram represents a cube created with six individual
shape objects (each of the six faces of the cube is a plane of course you don't have to do this). The image
of the application is from an early version of MouseRotateApp.java, an example program included
in the examples jar available with this tutorial. The image of the mouse is from the clip art distributed with
Microsoft Office 97.
Module 2: Interaction and Animation
The Java 3D Tutorial 4-1
4
Interaction
Chapter Objectives
After reading this chapter, youll be able to:
Appreciate the Behavior Class as the foundation for interaction and animation
Create custom behavior classes
Incorporate behavior objects into virtual worlds to provide interaction
Use utility classes for keyboard navigation
Use utility classes for mouse interaction
Use utility picking classes
In the previous chapters of the tutorial, the Java 3D virtual universes are almost all static. For Java 3D
worlds to be more interesting, and more useful, interaction and animation are necessary. Interaction is
when the imagery changes in response to user action. Animation is defined as changes in the imagery
without direct user action, and usually corresponds with the passage of time.
In Java 3D, both interaction and animations are specified through the use of the Behavior class. This
chapter introduces the Behavior class and explains its use in interactive programs. The next chapter,
Animation, continues with animation examples and explanations.
4.1 Behavior: the Base for Interaction and Animation
Both interaction and animation are specified with Behavior objects. The Behavior class is an abstract class
that provides the mechanism to include code to change the scene graph. The Behavior class, and its
descendants, are links to user code providing changes to the graphics and sounds of the virtual universe.
The purpose of a Behavior object in a scene graph is to change the scene graph, or objects in the scene
graph, in response to some stimulus. A stimulus can be the press of a key, a mouse movement, the
collision of objects, the passage of time, some other event, or a combination of these. Changes produced
include adding objects to the scene graph, removing objects from the scene graph, changing attributes of
objects in the scene graph, rearranging objects in the scene graph, or a combination of these. The
possibilities are only limited by the capabilities of the scene graph objects.
CHAPTER
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-2
4.1.1 Applications of Behavior
Since a behavior is a link between a stimulus and an action, considering all the combinations of possible
stimuli and possible actions is to consider the many applications of Behavior objects. The following table
surveys the realm of possibilities with Behavior, listing possible stimuli down the left column and possible
changes across the top.
The table does not list all possible applications of Behavior, only the simple ones (one stimulus results in
one change). Some combinations of stimulus and change only make sense in a specific setting; these are
listed as 'application specific'. Furthermore, combinations of stimuli and combinations of actions are
possible.
Table 4-1 Applications of Behavior Categorized by Stimulus and Object of Change
object of change
stimulus
(reason for
change)
TransformGroup
(visual objects change
orientation or location)
Geometry
(visual objects change
shape or color)
Scene Graph
(adding, removing, or
switching objects)
View
(change viewing
location or direction)
user interaction application specific application specific navigation
collisions
visual objects
change orientation
or location
visual objects
change appearance
in collision
visual objects
disappear in
collision
View changes with
collision
time animation animation animation animation
View location
billboard level of detail
(LOD)
application specific application specific
In Table 4-1 some of the possible behaviors are spelled out. For example, collision actions are described.
Others, such as billboard or level of detail (LOD) behaviors, may not be familiar to you. Below are some
quick explanations.
The chart does not include all applications of Behavior; combinations of stimuli and/or changes are not
shown. Picking is also implemented using behaviors but is not listed in the table. Although listed in Table
4-1 and implemented in Java 3D API, collision detection is not addressed in this tutorial.
Natural things, such as trees, take a tremendous amount of geometry to accurately represent all of the
branches, leaves and bark structure. One alternative is to use a textured polygon instead of the geometry.
This technique is sometime referred to as the billboard approach. This is especially true when a behavior is
used to automatically orient the textured polygon orthogonal to the viewer such that only the front textured
face is viewed. This orienting behavior is called billboard behavior.
The billboard approach is effective when the object to be represented by the texture is distant so that the
individual parts of the visual object represented by the texture would not easily be distinguished. For the
tree example, if the viewer is so distant that branches are hardly distinguishable, it is hardly worth the
memory and computation requirements to represent each leaf of the tree. This technique is recommended
for any application requiring visually complex objects in a distance. However, if the viewer were able to
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-3
approach the billboard, at some distance the lack of depth of the textured polygon would be detected by the
viewer.
The level of detail (LOD) behavior has a related application. With LOD, visually complex objects are
represented by multiple visual objects of varying levels of detail (hence the name). The visual object
representation with the least detail is used when the viewer is far away. The most detailed representation is
used when the viewer is close. The LOD behavior automatically switches between the representations
based on the objects distance to the viewer.
Both the billboard and level of detail behaviors correspond to classes extended from Behavior which
implement these common applications. Other specializations of behavior are possible and several are listed
in Figure 4-1. For example, there are several MouseBehavior classes that manipulate a transform in
response to mouse movements. Normally the view transform is changed by the mouse behavior to change
the view in response to mouse actions.
Also note how the behaviors can chain. For example, mouse movements or key strokes can be used to
change the view. In response to the movement of the view, billboard, level of detail, and/or other behaviors
may take place. Fortunately, each behavior is specified separately.
Animation Versus Interaction
Since the distinction between animation and interaction used in this tutorial is fairly fine, here is an example
to help clarify this distinction. If a user navigates in a program where such a behavior is provided, the view
platform will move in response to the keyboard and/or mouse events. The motion of the view platform is
an interaction because it is the direct result of the user action. However, other things may change as a
result of the view platform motion (e.g., billboard and LOD behaviors). Changes as a result of the view
platform motion are indirectly caused by the user and are therefore animations.
4.1.2 Overview of Behavior Classes
The following figure, Figure 4-1, shows specializations of behavior made in the Java 3D API core and
utility packages. User defined specializations of Behavior are also possible and are only limited in
functionality by the programmer's imagination. This module of the tutorial covers each of the classes in
Figure 4-1. This chapter covers the shaded classes in the figure; Chapter 5 covers the remaining classes.
This figure does not present the total coverage of the Java 3D API in Chapters 4 and 5; each chapter
presents more than the classes in this figure.
4.2 Behavior Basics
As explained in the previous section, Behavior classes are used in many Java 3D applications and in many
ways. It is important to understand the workings and programming considerations of the behavior class.
This section explains the Behavior class, gives a recipe for programming a custom behavior class, and
gives a simple example application using a behavior class.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-4
Behavior
Billboard
Interpolator
LOD
DistanceLOD
ColorInterpolator
RotPosPathScaleInterpolator
MouseBehavior
MouseRotate
MouseZoom
MouseTranslate
KeyNavigatorBehavior
PickRotateBehavior
PickZoomBehavior
PickTranslateBehavior PickMouseBehavior
Figure 4-1 Hierarchy of Subclasses of Behavior
4.2.1 Writing a Behavior Class
This section explains how to write a custom behavior class. You know from Section 4.1 that there are
behavior classes you can use without writing a class. However, in seeing how to create a Behavior class
you learn how behaviors work. So even if you only plan to use a behavior class, you might want to read
this section. Also, the class written in this section is used in the next section. (If you don't plan to write a
Behavior class you can skip this section for now.)
Mechanics of Behaviors
A custom behavior class implements the initialization and processStimulus methods from the abstract
Behavior class. Of course, the custom behavior class also has at least one constructor and may have other
methods as well.
Most behaviors will act on a scene graph object to affect the behavior. In Table 4-1, the object a behavior
acts upon is refered to as the object of change. It is through this object, or objects, that the behavior
affects the virtual world. While it is possible to have a behavior that does not have an object of change,
most do.
The behavior needs a reference to its object(s) of change to be able to make the behavioral changes. The
constructor can be used to set the reference to the object of change. If it does not, another method in the
custom behavior class must store this information. In either case, the reference is made at the time the
scene graph is being constructed, which is the first computation of the behavior.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-5
The initialization method is invoked when the scene graph containing the behavior class becomes live. The
initialization method is responsible for setting the initial trigger event for the behavior and setting the initial
condition of the state variables for the behavior. The trigger is specified as a WakeupCondition object, or a
combination of WakeupCondition objects.
The processStimulus method is invoked when the trigger event specified for the behavior occurs. The
processStimulus method is responsible for responding to the event. As many events may be encoded into a
single WakeupCondition object (e.g., a variety of keyboard actions may be encoded in a
WakeupOnAWTEvent), this includes decoding the event. The processStimulus method responds to the
stimulus, usually by changing its object of change, and, when appropriate, resets the trigger.
The information in this section, Mechanics of Behaviors, is summarized in a recipe for writing custom
behavior classes. Figure 4-2 presents this recipe.
1. write (at least one) constructor
store a reference to the object of change
2. override public void initialization()
specify initial wakeup criteria (trigger)
3. override public void processStimulus()
decode the trigger condition
act according to the trigger condition
reset trigger as appropriate
Figure 4-2 Recipe for Writing a Custom Behavior Class
The recipe of Figure 4-2 shows the basic steps for creating a custom behavior class. Complex behaviors
may require more programming than is described in the recipe. Using a behavior object is another issue
and is discussed in Section 4.2.2. But before using a behavior, this recipe is used in creating the following
example custom behavior.
Example Custom Behavior Class: SimpleBehavior
As an example of using the custom behavior class recipe of Figure 4-2, this section goes through the
process of writing a custom behavior class. For the example custom behavior, the class will implement a
simple behavior of making something rotate in response to a keyboard key press.
To create such a behavior class, all that is needed is a reference to a TransformGroup (the object of change
for this class), and an angle variable. In response to a key press, the angle variable is changed and the
angle of the target TransformGroup is set to the angle. Since the behavior will act on a TransformGroup
object, what is being rotated is not an issue.
To create this class nothing more than the three essential programming ingredients listed in the recipe are
needed: a constructor, the initialization method, and the processStimulus method. The constructor will
store a reference to the TransformGroup object of change. The initialization method sets the initial trigger
to WakeOnAWTEvent, and sets the rotation angle to zero. As mentioned above, the stimulus to a behavior
is specified as a WakeupCondition object. Section 4.3 introduces WakeupCondition classes.
Since there is only one possible triggering wakeup condition, the processStimulus method does not decode
the triggering wakeup condition. It is possible to further decode the key press event to determine which
key, or combination of keys, was pressed.
The processStimulus method always increments the angle variable, then uses it to adjust the
TransformGroup object of change. The last job of the processStimulus method is to reset the trigger. In
this example, the trigger is always reset to a key press. Behaviors can change their trigger event over time
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-6
for changing behaviors (another reason for having to decode the trigger event), or not set another trigger for
one time behaviors.
Code Fragment 4-1 presents the SimpleBehavior class which is an implementation of the described custom
behavior class. The import statements listed in Code Fragment 4-1 are necessary for the behavior class.
The java.awt.event import is necessary for the keyboard interaction. The java.util.eumeration import is
necessary for decoding the WakeupCondition; and therefore necessary for virtually any custom behavior
class. The normal Java 3D API import statements are needed in addition to the listed import statements.
Code Fragment 4-1 is annotated with the step numbers from the recipe.
1. import java.awt.event.*;
2. import java.util.Enumeration;
3.
4. // SimpleBehaviorApp renders a single, rotated cube.
5.
6. public class SimpleBehaviorApp extends Applet {
7.
8. public class SimpleBehavior extends Behavior{
9.
10. private TransformGroup targetTG;
11. private Transform3D rotation = new Transform3D();
12. private double angle = 0.0;
13.
14. // create SimpleBehavior - set TG object of change
15. O SimpleBehavior(TransformGroup targetTG){
16. this.targetTG = targetTG;
17. }
18.
19. // initialize the Behavior
20. // set initial wakeup condition
21. // called when behavior becomes live
22. O public void initialize(){
23. // set initial wakeup condition
24. this.wakeupOn(new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED));
25. }
26.
27. // called by Java 3D when appropriate stimulus occurs
28. O public void processStimulus(Enumeration criteria){
29. // do what is necessary in response to stimulus
30. angle += 0.1;
31. rotation.rotY(angle);
32. targetTG.setTransform(rotation);
33. this.wakeupOn(new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED));
34. }
35.
36. } // end of class SimpleBehavior
Code Fragment 4-1 SimpleBehavior Class in SimpleBehaviorApp.java
This class is used in the SimpleBehaviorApp example found in the examples/Interaction
directory.
This class only demonstrates the basic programming necessary for this simple behavior. Enhancements to
this custom class are possible. For example, the angle of rotation and/or the axis of rotation could be set
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-7
by class methods. The behavior class could be further customizable with a method for setting a specific
key, or set of keys, that it will respond to.
Another definite improvement in the class would prevent overflow of the angle variable. In the current
class, the value of angle could grow without bound even though values of 0.0 to 2 are all that is
necessary. Although unlikely, it is possible for this variable to overflow and cause a run time exception.
Programming Pitfalls of Writing Behavior Classes
In the three steps of the custom behavior class recipe, the two most likely programming mistakes are:
forgetting to set and reset the behavior trigger, and
not returning from the behavior class methods.
Obviously, if an initial trigger is not set in the initialization method, the behavior will never be invoked. A
little less obvious is that the trigger must be set again in the processStimulus method if a repeat behavior is
desired.
Since both the initialization and processStimulus methods are called by the Java 3D system, they must
return to allow the rendering to continue. For example, if a spinning behavior were desired, the angle and
the TransformGroup would need to be updated periodically. If your behavior implemented this behavior
without spawning a thread, nothing further would be rendered. Also, there is a much better way to achieve
this type of behavior
1
.
4.2.2 Using a Behavior Class
Finding or writing the appropriate behavior class for your application is the beginning of writing an
interactive Java 3D program. This section covers the programming issues in adding behavior objects to
programs.
The first step in adding a behavior involves making sure the scene graph makes provisions for the behavior.
For example, to use the SimpleBehavior class from the previous section there must be a TransformGroup
in the scene graph above the object(s) to be rotated. Many behaviors need only a single TransformGroup
object; however, scene graph requirements for a behavior is application and behavior dependent and may be
more complex.
Having established the support for a behavior, an instance of the class must be added to the scene graph.
Without being a part of a live scene graph, there is no way a behavior can be initialized. In fact, a behavior
object that is not part of the scene graph will become garbage and be eliminated on the next garbage
collection.
The last step for adding a behavior is to provide a scheduling bounds for the behavior. To improve
efficiency, Java 3D uses the scheduling bounds to perform execution culling. Behavior is only active when
its scheduling bounds intersects a ViewPlatform's activation volume. Only active behaviors are eligible to
receive stimuli. In this way, stimuli can be ignored for some behaviors. The programmer has control over
the execution culling through the selection of the scheduling bounds of the behavior.
Figure 4-3 summarizes the steps for using a behavior object in a recipe.
1
A behavior based on time alone is an animation, and as such is discussed in Chapter 5.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-8
1. prepare the scene graph (by adding a TransformGroup or other necessary objects)
2. insert behavior object in the scene graph, referencing the object of change
3. specify a scheduling bounds (or SchedulingBoundingLeaf)
4. set write (and read) capabilities for the target object (as appropriate)
Figure 4-3 Recipe for Using a Behavior Class
The following code fragment, Code Fragment 4-2, is annotated with the step numbers from the recipe.
This code fragment is an except from the SimpleBehaviorApp example program found in the
examples/Interaction directory. In this same application the SimpleBehavior class, found in Code
Fragment 4-2, is defined. Code Fragment 4-2 continues where Code Fragment 4-1 ended and the line
numbers are sequential for the two code fragments.
37. public BranchGroup createSceneGraph() {
38. // Create the root of the branch graph
39. BranchGroup objRoot = new BranchGroup();
40.
41. TransformGroup objRotate = new TransformGroup();
42. O objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
43. O
44. objRoot.addChild(objRotate);
45. objRotate.addChild(new ColorCube(0.4));
46.
47. SimpleBehavior myRotationBehavior = new SimpleBehavior(objRotate);
48. O myRotationBehavior.setSchedulingBounds(new BoundingSphere());
49. O objRoot.addChild(myRotationBehavior);
50.
51. // Let Java 3D perform optimizations on this scene graph.
52. objRoot.compile();
53.
54. return objRoot;
55. } // end of CreateSceneGraph method of SimpleBehaviorApp
Code Fragment 4-2 CreateSceneGraph Method in SimpleBehaviorApp.java
Very little code is needed to complete the program started in Code Fragment 4-1 and 4-2. The complete
program, SimpleBehaviorApp, is found in the examples/Interaction directory. The
complete application renders a ColorCube object in a static scene until a keyboard key is pressed. In
response to any key press, the ColorCube rotates 0.1 radians (about 6). Figure 4-4 shows the scene graph
diagram for the content branch graph of this application.
BG
TG
B
ColorCube
objRoot
objRotate
myRotationBehavior
Figure 4-4 Scene Graph Diagram of the Content Branch Graph Created in SimpleBehaviorApp.java.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-9
The above scene graph diagram clearly shows the relationship between the behavior object and the object
of change, the TransformGroup object. The example rotates a ColorCube, but the behavior class is not
limited to this. It can rotate any visual object, or portion of a scene graph that is a child of a
TransformGroup object.
This simple example is not intended to demonstrate all of the possibilities of behaviors; it is only a starting
point in the exploration of behaviors. Section 4.2.3 presents the Behavior class API. Other behavior class
programming considerations are discussed before that.
Programming Pitfalls of Using Behavior Objects
In the three steps of the using a behavior class recipe, the two most likely programming mistakes are:
not specifying a scheduling bounds (correctly), and
not adding a behavior to the scene graph.
The intersection of the scheduling bounds of a behavior with the activation volume of a view determines
whether or not Java 3D even considers the trigger stimulus for the behavior. Java 3D will not warn you of
a missing scheduling bounds - the behavior will never be triggered. Also, keep the scheduling bounds of
each behavior object as small as possible for the best overall performance.
As mentioned above, a behavior object that is not part of the scene graph will be considered garbage and
eliminated on the next garbage collection cycle. This, too, will happen without error or warning.
Where in the Scene Graph Should a Behavior Object Go?
Behaviors can be placed anywhere in the scene graph. The issues in picking a scene graph location for a
behavior object are 1) the effect on the scheduling bounds, and 2) code maintenance.
The bounds object referenced by a behavior object is subject to the local coordinate system of the behavior
object's position in the scene graph. In the scene graph created in SimpleBehaviorApp, the SimpleBehavior
object and the ColorCube are not subject to the same local coordinate system. In the example application
this does not create a problem. The TransformGroup object of the example only rotates the ColorCube so
that the scheduling bounds for the myRotationBehavior object always encloses the ColorCube object
allowing interaction with the ColorCube when it is visible
2
.
However, if the TransformGroup object were used to translate the ColorCube object, it would be possible
to move the ColorCube out of the view. Since the bounds object stays with the behavior object in this
scene, the user would be able to continue to translate the object. As long as the activation volume of a view
still intersects the scheduling bounds for the behavior, the behavior is still active.
Being able to interact with a visual object that is not in the view is not bad (if that is what you want). The
problem lies in that if the view were to change such that the activation volume no longer intersects the
scheduling bounds of the behavior, even to include the visual object, the behavior is inactive. So the visual
object you want to interact with may be in your view but not active. Most users will consider this a
problem (even if it is intentional).
There two solutions to this problem. One is to change the scene graph to keep the scheduling bounds of the
behavior with the visual object. This is easily accomplished as demonstrated in Figure 4-5. The alternative
2
The typical graphical application allows a user to interact with visible objects (visual objects that are in the view).
If you want a different semantic, that is fine.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-10
solution uses a BoundingLeaf object for the scheduling bounds. Consult Section 3.7 or the Java 3D API
Specification for information on the BoundingLeaf class.
BG
TG
B
ColorCube
objRoot
objRotate
myRotationBehavior
Figure 4-5 An Alternative Scene Graph Placement for the Behavior Object in SimpleBehaviorApp.
Behavior Class Design Recommendations
The mechanics of writing a custom behavior are simple. However, you should be aware that a poorly
written behavior can degrade rendering performance
3
. While there are other considerations in writing a
behavior, two things to avoid are: memory burn and unnecessary trigger conditions.
'Memory burn' is the term for unnecessarily creating objects in Java. Excessive memory burn will cause
garbage collections. Occasional pauses in rendering is typical of memory burn since during the garbage
collection, the rendering will stop
45
.
Behavior class methods are often responsible for creating memory burn problems. For example, in Code
Fragment 4-1 the processStimulus uses a 'new' in the invocation of wakeupOn (line 24). This causes a
new object to be created each time the method is invoked. That object becomes garbage each time the
behavior is triggered.
Potential memory burn problems are normally easy to identify and avoid. Look for any use of 'new' in the
code to find the source of memory burn problems. Whenever possible, replace the use of the new with code
that reuses an object.
Later, in Section 4.3,the classes and methods used in setting the trigger conditions for a behavior object are
discussed. In that section, you will see it is possible to set a trigger condition that will wake a behavior
every frame of the rendering. If there is nothing for the behavior to do, this is an unnecessary waste of
processor power invoking the behavior's processStimulus method. Not to say that there isn't a good reason
to trigger a behavior on every frame, just make sure you have the reason.
4.2.3 Behavior Class API
This section presents the detail of the Behavior class API. Figure 4-6 shows the Java 3D API class
hierarchy including the Behavior class. As an abstract class, Behavior must be extended before a behavior
3
The amount of performance degradation depends heavily on the execution environment. If you plan to distribute
your applications, consider users with software rendering environments.
4
How often and how regular the pause depends on the execution environment.
5
You can diagnose a memory burn problem by invoking the Java virtual machine with the -verbose:gc command
line option. If memory burn is the cause for rendering pauses, then the garbage collection report produced to the
console will coinside with the pauses.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-11
object can be instantiated. Of course, you can write your own custom behavior classes. In addition, there
are many existing behaviors in the Java 3D API utility packages. As an extension of Leaf, instances of
classes that extend Behavior can be children of a group in a scene graph.
java.lang.Object
javax.media.j3d.SceneGraphObject
javax.media.j3d.Node
javax.media.j3d.Leaf
javax.media.j3d.Behavior
Figure 4-6 API Class Hierarchy for Behavior
As documented in Section 4.2.1, the processStimulus and initialize methods provide the interface Java 3D
uses to incorporate behaviors in the virtual universe. The other Behavior class methods are discussed
below. All Behavior class methods are listed in the Behavior Method Summary reference block on the next
page.
The wakeupOn method is used in the initialize and processStimulus methods to set the trigger for the
behavior. The parameter to this method is a WakeupCondition object. WakeupCondition, and related
classes, are presented in Section 4.3.
The postId method allows a behavior to communicate with another method. One of the wakeup conditions
is WakeupOnBehaviorPost. Behavior objects can be coordinated to create complex collaborations using
the postId method in conjunction with appropriate WakeupOnBehaviorPost conditions. See page 4-16 for
information on the WakeupOnBehaviorPost class
The setEnable method provides a way to disable a behavior even when the bounds makes it active. The
default is true (i.e., the behavior object is enabled).
A behavior object is active only when its scheduling bounds intersects the activation volume of a View.
Since it is possible to have multiple views in a virtual universe, a behavior can be made active by more than
one view.
The getView method is useful with behaviors that rely on per-View information (e.g., Billboard, LOD) and
with behaviors in general in regards to scheduling. This method returns a reference to the primary View
object currently associated with the behavior. There is no corresponding setView method. The "primary"
view is defined to be the first View attached to a live ViewPlatform, if there is more than one active View.
So, for instance, Billboard behaviors would be oriented toward this primary view, in the case of multiple
active views into the same scene graph.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-12
Behavior Method Summary
Behavior is an abstract class that contains the framework for all behavioral components in Java 3D.
View getView()
Returns the primary view associated with this behavior.
void initialize()
Initialize this behavior.
void postId(int postId)
Post the specified Id.
void processStimulus(java.util.Enumeration criteria)
Process a stimulus meant for this behavior.
void setEnable(boolean state)
Enables or disables this Behavior.
void setSchedulingBoundingLeaf(BoundingLeaf region)
Set the Behavior's scheduling region to the specified bounding leaf.
void setSchedulingBounds(Bounds region)
Set the Behavior's scheduling region to the specified bounds.
void wakeupOn(WakeupCondition criteria)
Defines this behavior's wakeup criteria.
ViewPlatform API
Behaviors are active (able to be triggered) only when their scheduling bounds (or BoundingLeaf) intersects
the activation volume of a ViewPlatform.
ViewPlatform Method Summary (partial list)
These methods of the ViewPlatform class get and set the activation volume (sphere) radius. Default activation
radius = 62.
float getActivationRadius()
Get the ViewPlatform's activation radius.
void setActivationRadius(float activationRadius)
Set the ViewPlatform's activation radius which defines an activation volume around the view platform.
4.3 Wakeup Conditions: How Behaviors are Triggered
Active behaviors are triggered by the occurrence of a specified one or more wakeup stimuli. The wakeup
stimuli for a behavior are specified using descendants of the WakeupCondition class.
The abstract class, WakeupCondition, is the base of the all the wakeup classes in the Java 3D API
hierarchy. Five classes extend WakeupCondition, one is the abstract class WakeupCriterion, the other four
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-13
allow the composition of multiple wakeup conditions in a single wakeup condition. Figure 4-7 shows the
class hierarchy for these classes.
java.lang.Object
javax.media.j3d.WakeupCondition
WakeupOr
WakeupAnd
WakeupAndOfOrs
WakeupOrOfAnds
WakeupCriterion
WakeupOnActivation
WakeupOnAWTEvent
WakeupOnBehaviorPost
WakeupOnCollisionEntry
WakeupOnCollisionExit
WakeupOnCollisionMovement
WakeupOnDeactivation
WakeupOnElapsedFrames
WakeupOnElapsedTime
WakeupOnSensorEntry
WakeupOnSensorExit
WakeupOnTransformChange
WakeupOnViewPlatformEntry
WakeupOnViewPlatformExit
Figure 4-7 The Java 3D API Class Hierarchy for WakeupCondition and Related Classes.
A behavior object's wakeup condition can be specified as one of the specific wakeup criterion or as a
combination of criteria using the wakeup composition classes. The following sections describe
WakeupCondition and its descendant classes.
4.3.1 WakeupCondition
The WakeupCondition class provides two methods. The first method, allElements, returns the enumeration
list of all wakeup criterion for the WakeupCondition object. The other method, triggeredElements,
enumerates which of the wakeup criterion has caused the behavior to be triggered. This method may be
useful in the processStimulus method of a Behavior object.
WakeupCondition Method Summary
The WakeupCondition abstract class is the base for all wakeup classes. It provides the following two methods.
Enumeration allElements()
Returns an enumeration of all WakeupCriterion objects in this Condition.
Enumeration triggeredElements()
Returns an enumeration of all triggered WakeupCriterion objects in this Condition.
4.3.2 WakeupCriterion
WakeupCriterion is an abstract method for the 14 specific wakeup criterion classes. WakeupCondition
provides only one method: hasTriggered. You probably don't need to use this method as the
triggeredElements method of WakeupCondition performs this operation for you.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-14
WakeupCriterion Method Summary
boolean hasTriggered()
Returns true if this criterion triggered the wakeup.
4.3.3 Specific WakeupCriterion Classes
Table 4-2 presents the 14 specific WakeupCriterion classes. These classes are used to specify the wakeup
conditions for behavior objects. Instances of these classes are used individually or in combinations when
using the wakeup condition composition classes presented in Section 4.3.4.
Table 4-2 The 14 Specific WakeupCriterion Classes
Wakeup Criterion Trigger page
WakeupOnActivation
on first detection of a ViewPlatform's activation volume
intersecting with this object's scheduling region.
4-15
WakeupOnAWTEvent when a specific AWT event occurs 4-15
WakeupOnBehaviorPost when a specific behavior object posts a specific event 4-16
WakeupOnCollisionEntry
on the first detection of the specified object colliding with any
other object in the scene graph
4-17
WakeupOnCollisionExit
when the specified object no longer collides with any other
object in the scene graph
4-19
WakeupOnCollisionMovement
when the specified object moves while in collision with any
other object in the scene graph
4-20
WakeupOnDeactivation
when a ViewPlatform's activation volume no longer intersects
with this object's scheduling region
4-21
WakeupOnElapsedFrames when a specific number of frames have elapsed 4-21
WakeupOnElapsedTime when a specific number of milliseconds have elapsed 4-21
WakeupOnSensorEntry
on first detection of any sensor intersecting the specified
boundary
4-22
WakeupOnSensorExit
when a sensor previously intersecting the specified boundary no
longer intersects the specified boundary
4-22
WakeupOnTransformChange
when the transform within a specified TransformGroup
changes
4-23
WakeupOnViewPlatformEntry
on first detection of a ViewPlatform activation volume
intersecting with the specified boundary
4-23
WakeupOnViewPlatformExit
when a View activation volume no longer intersects the
specified boundary
4-24
Reference blocks for the individual WakeupCriterion classes appear on the next ten pages. Some
WakeupCriterion classes have very simple APIs. For example, the WakeupOnActivation class has just one
constructor. The scheduling region, a parameter of this wakeup condition, is specified in the behavior
object that uses this criterion.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-15
General WakeupCriterion Comments
A number of WakeupCriterion classes trigger on the "first detection" of an event. What this means is the
criterion will trigger only once for the event. For example, a WakeupOnActivation object will trigger the
intersection of the activation volume of a ViewPlatform and the scheduling region of the associated
behavior object is detected. As long as this intersection persists, the WakeupCondition does not trigger
again. The same is true for each of the sequentially following frames. Not until Java 3D detects that the
volumes no longer intersect can this WakeupCondition trigger again.
Also, there are a number of WakeupCriterion classes in matched pairs (Entry/Exit or
Activation/Deactivation). These criteria only trigger in strict alternation beginning with the Entry or
Activation criterion.
WakeupOnActivation
It is possible for a scheduling region to intersect a ViewPlatform's activation volume so briefly that it is not
detected. Consequently, neither the Activation nor Deactivation conditions are triggered. Under these
circumstances, the behavior does not become active either.
WakeupOnActivation Constructor Summary
extends: WakeupCriterion
Class specifying a wakeup on first detection of a ViewPlatform's activation volume intersection with this object's
scheduling region. WakeupOnActivation is paired with WakeupOnDeactivation which appears on page 4-21.
WakeupOnActivation()
Constructs a new WakeupOnActivation criterion.
WakeupOnAWTEvent
Several of the WakeupCriterion classes have trigger dependent constructors and methods. For example,
WakeupOnAWTEvent has two constructors and a method. The constructors allow the specification of
AWT events using AWT class constants. The method returns the array of consecutive AWT events that
caused the trigger.
WakeupOnAWTEvent Constructor Summary
extends: WakeupCriterion
Class that specifies a Behavior wakeup when a specific AWT event occurs. Consult an AWT reference for more
information.
WakeupOnAWTEvent(int AWTId)
Constructs a new WakeupOnAWTEvent object, where AWTId is one of KeyEvent.KEY_TYPED,
KeyEvent.KEY_PRESSED, KeyEvent.KEY_RELEASED, MouseEvent.MOUSE_CLICKED,
MouseEvent.MOUSE_PRESSED, MouseEvent.MOUSE_RELEASED, MouseEvent.MOUSE_MOVED,
MouseEvent.MOUSE_DRAGGED, or one of many other event values.
WakeupOnAWTEvent(long eventMask)
Constructs a new WakeupOnAWTEvent object using ORed EVENT_MASK values. AWT EVENT_MASK values
are: KEY_EVENT_MASK, MOUSE_EVENT_MASK, MOUSE_MOTION_EVENT_MASK, or other values.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-16
WakeupOnAWTEvent Method Summary
AWTEvent[] getAWTEvent()
Retrieves the array of consecutive AWT events that triggered this wakeup.
WakeupOnBehaviorPost
The WakeupOnBehaviorPost condition together with the postID method of the Behavior class provides a
mechanism through which behaviors can coordinate. A Behavior object can post a particular integer ID
value. Another behavior can specify its wakeup condition, using a WakeupOnBehaviorPost, as the posting
of a particular ID from a specific behavior object. This allows for the creation of parenthetical behavior
objects such as having one behavior open a door and different one closing it. For that matter, even more
complex behaviors can be formulated using behaviors and post coordination.
WakeupOnBehaviorPost Constructor Summary
extends: WakeupCriterion
Class that specifies a Behavior wakeup when a specific behavior object posts a specific event.
WakeupOnBehaviorPost(Behavior behavior, int postId)
Constructs a new WakeupOnBehaviorPost criterion.
Since a WakeupCondition can be composed of a number of WakeupCriterion objects, including more than
one WakeupOnBehaviorPost, the methods to determine the specifics of the triggering post are necessary to
interpret a trigger event.
WakeupOnBehaviorPost Method Summary
Behavior getBehavior()
Returns the behavior specified in this object's constructor.
int getPostId()
Retrieve the WakeupCriterion's specified postId
Behavior getTriggeringBehavior()
Returns the behavior that triggered this wakeup.
int getTriggeringPostId()
Returns the postId that caused the behavior to wakeup.
Code Fragment 4-3 and Code Fragment 4-4 show a partial code for an example program of using behavior
posting for coordinated behaviors. The example is that of opening and closing a door. The code fragments
includes one class: OpenBehavior, and code that creates the two behavior objects. The second object is an
instance of CloseBehavior, which is almost and exact duplicate of OpenBehavior. In CloseBehavior, the
condition is swapped in the initialization method (and the opposite behavior performed).
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-17
1. public class OpenBehavior extends Behavior{
2.
3. private TransformGroup targetTG;
4. private WakeupCriterion pairPostCondition;
5. private WakeupCriterion AWTEventCondition;
6.
7. OpenBehavior(TransformGroup targetTG){
8. this.targetTG = targetTG;
9. AWTEventCondition = new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED);
10. }
11.
12. public void setBehaviorObjectPartner(Behavior behaviorObject){
13. pairPostCondition = new WakeupOnBehaviorPost(behaviorObject, 1);
14. }
15.
16. public void initialize(){
17. this.wakeupOn(AWTEventCondition);
18. }
19.
20. public void processStimulus(Enumeration criteria){
21. if (AWTEventCondition.hasTriggered()){
22. // make door open code excluded
23. this.wakeupOn(pairPostCondition);
24. postId(1);
25. } else {
26. this.wakeupOn(AWTEventCondition);
27. }
28. }
29.
30. } // end of class OpenBehavior
Code Fragment 4-3 Outline of OpenBehavior Class, an Example of Coordinated Behavior Classes
1. // inside a method to assemble the scene graph ...
2.
3. // create the relevant objects
4. TransformGroup doorTG = new TransformGroup();
5. OpenBehavior openObject = new OpenBehavior(doorTG);
6. CloseBehavior closeObject = new CloseBehavior(doorTG);
7.
8. //prepare the behavior objects
9. openObject.setBehaviorObjectPartner(closeObject);
10. closeObject.setBehaviorObjectPartner(openObject);
11.
12. // set scheduling bounds for behavior objects code excluded
13.
14. // assemble scene graph code excluded
15.
Code Fragment 4-4 Code using OpenBehavior and CloseBehavior, Coordinated Behavior Classes
Objects of these two classes would respond in strict alternation to key press events. The open behavior
object would trigger in response to the first key press. In its response, it signals the close behavior object
and sets its trigger condition to be a signal from the close object. The open behavior object opens the door
(or whatever) in response to the key press, as well. The close behavior object sets its trigger to be a key
press in response to the signal from the open behavior object. An example program included in the
examples/Interaction subdirectory, DoorApp.java, utilizes an open and close behavior pair.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-18
The next key press triggers the close object. The close object now performs the same functions that the
open object just performed: send a signal and reset its own trigger condition. The close object closes the
door (or whatever) in response to the key press. Back to the initial conditions, the next key press would
begin the process again.
WakeupOnCollisionEntry
Java 3D can detect the collision of objects in the virtual world. There are three WakeupCriterion classes
useful in processing the collision of objects: WakeupOnCollisionEntry, WakeupOnCollisionMovement, and
WakeupOnCollisionExit.
A WakeupOnCollisionEntry criterion will trigger when an object first collides. Then,
WakeupOnCollisionMovement criterion will trigger (potentially multiple triggers) while the two objects are
in collision if there is relative movement between the objects. Finally, a single WakeupOnCollisionExit will
trigger when the collision is over.
Java 3D can handle only one collision for an object at a time. Once a collision is detected for an object,
collisions with other objects are not detected until that first collision is over. Also, it is possible for a
collision to occur so briefly that it is not detected. Consequently, neither the CollisionEntry nor
CollisionExit conditions are triggered.
Collision detection is more complex than this discussion of the collision wakeup conditions. However, this
tutorial does not address collision detection in detail. Refer to the Java 3D API Specification for more
information on collision detection.
WakeupOnCollisionEntry Constructor Summary
extends: WakeupCriterion
Class specifying a wakeup on the first detection of a specified object colliding with any other object in the scene
graph. See also: WakeupOnCollisionMovement, and WakeupOnCollisionExit.
WakeupOnCollisionEntry(Bounds armingBounds)
Constructs a new WakeupOnCollisionEntry criterion.
WakeupOnCollisionEntry(Node armingNode)
Constructs a new WakeupOnCollisionEntry criterion.
WakeupOnCollisionEntry(Node armingNode, int speedHint)
Constructs a new WakeupOnCollisionEntry criterion, where speedHint is either:
USE_BOUNDS - Use geometric bounds as an approximation in computing collisions.
USE_GEOMETRY - Use geometry in computing collisions.
WakeupOnCollisionEntry(SceneGraphPath armingPath)
Constructs a new WakeupOnCollisionEntry criterion with USE_BOUNDS for a speed hint.
WakeupOnCollisionEntry(SceneGraphPath armingPath, int speedHint)
Constructs a new WakeupOnCollisionEntry criterion, where speedHint is either USE_BOUNDS or
USE_GEOMETRY.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-19
WakeupOnCollisionExit
WakeupOnCollisionExit Constructor Summary
extends: WakeupCriterion
Class specifying a wakeup when the specified object no longer collides with any other object in the scene graph.
See also: WakeupOnCollisionMovement, and WakeupOnCollisionEntry.
WakeupOnCollisionExit(Bounds armingBounds)
Constructs a new WakeupOnCollisionExit criterion.
WakeupOnCollisionExit(Node armingNode)
Constructs a new WakeupOnCollisionExit criterion.
WakeupOnCollisionExit(Node armingNode, int speedHint)
Constructs a new WakeupOnCollisionExit criterion, where speedHint is either:
USE_BOUNDS - Use geometric bounds as an approximation in computing collisions.
USE_GEOMETRY - Use geometry in computing collisions.
WakeupOnCollisionExit(SceneGraphPath armingPath)
Constructs a new WakeupOnCollisionExit criterion.
WakeupOnCollisionExit(SceneGraphPath armingPath, int speedHint)
Constructs a new WakeupOnCollisionExit criterion, where speedHint is either USE_BOUNDS, or
USE_GEOMETRY.
WakeupOnCollisionExit Method Summary
Bounds getArmingBounds()
Returns the bounds object used in specifying the collision condition.
SceneGraphPath getArmingPath()
Returns the path used in specifying the collision condition.
Bounds getTriggeringBounds()
Returns the Bounds object that caused the collision
SceneGraphPath getTriggeringPath()
Returns the path describing the object causing the collision.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-20
WakeupOnCollisionMovement
WakeupOnCollisionMovement Constructor Summary
extends: WakeupCriterion
Class specifying a wakeup when the specified object moves while in collision with any other object in the scene
graph. See also: WakeupOnCollisionEntry, and WakeupOnCollisionExit.
WakeupOnCollisionMovement(Bounds armingBounds)
Constructs a new WakeupOnCollisionMovement criterion.
WakeupOnCollisionMovement(Node armingNode)
Constructs a new WakeupOnCollisionMovement criterion.
WakeupOnCollisionMovement(Node armingNode, int speedHint)
Constructs a new WakeupOnCollisionMovement criterion, where speedHint is either:
USE_BOUNDS - Use geometric bounds as an approximation in computing collisions.
USE_GEOMETRY - Use geometry in computing collisions.
WakeupOnCollisionMovement(SceneGraphPath armingPath)
Constructs a new WakeupOnCollisionMovement criterion.
WakeupOnCollisionMovement(SceneGraphPath armingPath, int speedHint)
Constructs a new WakeupOnCollisionMovement criterion, where speedHint is either USE_BOUNDS, or
USE_GEOMETRY.
WakeupOnCollisionMovement Method Summary
Bounds getArmingBounds()
Returns the bounds object used in specifying the collision condition.
SceneGraphPath getArmingPath()
Returns the path used in specifying the collision condition.
Bounds getTriggeringBounds()
Returns the Bounds object that caused the collision
SceneGraphPath getTriggeringPath()
Returns the path describing the object causing the collision.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-21
WakeupOnDeactivation
WakeupOnDeactivation Constructor Summary
extends: WakeupCriterion
Class specifying a wakeup on first detection of a ViewPlatform's activation volume no longer intersecting with this
object's scheduling region. See also: WakeupOnActivation (page 4-15).
WakeupOnDeactivation()
Constructs a new WakeupOnDeactivation criterion.
WakeupOnElapsedFrames
WakeupOnElapsedFrames object is used to trigger an active object after the specified number of frames
have elapsed. A frameCount of 0 specifies a wakeup on the next frame.
WakeupOnElapsedFrames Constructor Summary
extends: WakeupCriterion
Class specifying a wakeup when a specific number of frames have elapsed.
WakeupOnElapsedFrames(int frameCount)
Constructs a new WakeupOnElapsedFrames criterion.
WakeupOnElapsedFrames Method Summary
int getElapsedFrameCount()
Retrieve the WakeupCriterion's elapsed frame count that was used when constructing this object.
WakeupOnElapsedTime
Java 3D can not guarantee the exact timing of the wakeup trigger for a WakeupOnElapsedTime criterion.
A wakeup will occur at the specified time, or shortly thereafter.
WakeupOnElapsedTime Constructor Summary
extends: WakeupCriterion
Class specifying a wakeup after a specific number of milliseconds have elapsed.
WakeupOnElapsedTime(long milliseconds)
Constructs a new WakeupOnElapsedTime criterion.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-22
WakeupOnElapsedTime Method Summary
long getElapsedFrameTime()
Retrieve the WakeupCriterion's elapsed time value that was used when constructing this object.
WakeupOnSensorEntry
In Java 3D, any input devices other than the keyboard or mouse is a sensor. A sensor is an abstract
concept of an input device. Each sensor has a hotspot defined in the sensor's coordinate system. The
intersection of a sensor's hotspot with a region can be detected with the WakeupOnSensorEntry and
WakeupOnSensorExit classes.
It is possible for a sensor to enter and exit an armed region so quickly that neither the SensorEntry nor
SensorExit conditions are triggered.
WakeupOnSensorEntry Constructor Summary
extends: WakeupCriterion
Class specifying a wakeup on first detection of the intersection of any sensor with the specified boundary.
WakeupOnSensorEntry(Bounds region)
Constructs a new WakeupOnEntry criterion.
WakeupOnSensorEntry Method Summary
Bounds getBounds()
Returns this object's bounds specification
WakeupOnSensorExit
WakeupOnSensorExit Constructor Summary
extends: WakeupCriterion
Class specifying a wakeup on first detection of a sensor previously intersecting the specified boundary no longer
intersecting the specified boundary. See also: WakeupOnSensorEntry.
WakeupOnSensorExit(Bounds region)
Constructs a new WakeupOnExit criterion.
WakeupOnSensorExit Method Summary
Bounds getBounds()
Returns this object's bounds specification
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-23
WakeupOnTransformChange
The WakeupOnTransformChange criterion is useful for detecting changes in position or orientation of
visual objects in the scene graph. This criterion offers an alternative to using the postId method for
creating coordinated behaviors. This is especially useful when the behavior with which you want to
coordinate is already written, such as the behavior utilities presented in sections 4.4 and 4.5.
WakeupOnTransformChange Constructor Summary
extends: WakeupCriterion
Class specifying a wakeup when the transform within a specified TransformGroup changes
WakeupOnTransformChange(TransformGroup node)
Constructs a new WakeupOnTransformChange criterion.
WakeupOnTransformChange Method Summary
TransformGroup getTransformGroup()
Returns the TransformGroup node used in creating this WakeupCriterion
WakeupOnViewPlatformEntry
The detection of the intersection of the ViewPlatform with a specified region is made possible with the
WakeupOnViewPlatfomEntry and WakeupOnViewPlatformExit criterion classes.
It is possible for the specified boundary to intersect a ViewPlatform's activation volume so briefly that it is
not detected. In this case neither the WakeupOnViewPlatformEntry nor WakeupOnViewPlatformExit
conditions are triggered.
WakeupOnViewPlatformEntry Constructor Summary
extends: WakeupCriterion
Class specifying a wakeup on first ViewPlatform intersection with the specified boundary.
WakeupOnViewPlatformEntry(Bounds region)
Constructs a new WakeupOnEntry criterion.
WakeupOnViewPlatformEntry Method Summary
Bounds getBounds()
Returns this object's bounds specification
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-24
WakeupOnViewPlatformExit
WakeupOnViewPlatformExit Constructor Summary
extends: WakeupCriterion
Class specifying a wakeup on first detection of a Viewplatform no longer intersecting the specified boundary. See
also WakeupOnViewPlatformEntry.
WakeupOnViewPlatformExit(Bounds region)
Constructs a new WakeupOnExit criterion.
WakeupOnViewPlatformExit Method Summary
Bounds getBounds()
Returns this object's bounds specification
4.3.4 WakeupCondition Composition
Multiple WakeupCriteron objects can be composed into a single WakeupCondition using the four classes
presented in this section. The first two classes allow the composition of a WakeupCondition from a
collection WakeupCriterion objects that are logically ANDed or ORed together, respectively. The third and
forth allow compositions of instances of the first two classes into more complex WakeupCondition objects.
WakeupAnd
WakeupAnd Constructor Summary
extends: WakeupCondition
Class specifying any number of wakeup criterion logically ANDed together.
WakeupAnd(WakeupCriterion[] conditions)
Constructs a new WakeupAnd condition.
WakeupOr
WakeupOr Constructor Summary
extends: WakeupCondition
Class specifying any number of wakeup criterion logically ORed together.
WakeupAnd(WakeupCriterion[] conditions)
Constructs a new WakeupOr condition.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-25
WakeupAndOfOrs
WakeupAndOfOrs Constructor Summary
extends: WakeupCondition
Class specifying any number of WakeupOr condition logically ANDed together.
WakeupAndOfOrs(WakeupOr[] conditions)
Constructs a new WakeupAndOfOrs condition.
WakeupOrOfAnds
WakeupOrOfAnds Constructor Summary
extends: WakeupCondition
Class specifying any number of WakeupAnd condition logically ORed together.
WakeupOrsOfAnds(WakeupAnd[] conditions)
Constructs a new WakeupOrOfAnds condition.
4.4 Behavior Utility Classes for Keyboard Navigation
To this point in the tutorial, the viewer has been in a fixed location with a fixed orientation. Being able to
move the viewer is an important capability in many 3D graphics applications. Java 3D is capable of
moving the viewer. In fact there are Java 3D utility classes which implement this functionality.
Figure 4-8 shows the basic view branch graph for a Java 3D virtual universe. In this figure, the view
platform transform is seen. If the transform is changed, the effect is to move, or re-orient, or both, the
viewer. From this, you can see that the basic design of keyboard navigation is simple: have a behavior
object change the view platform transform in response to key strokes.
This simple design is exactly how the Java 3D keyboard utility classes work. Of course you could build
your own keyboard navigation behavior. The rest of this section explains how to use the Java 3D keyboard
navigation classes.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-26
BG
TG
ViewPlatform Transform
View Platform
View Canvas3D Screen3D
Physical Body Physical Environment
content
branch graph
Figure 4-8 The Basic View Branch Graph Showing the View Platform Transform
How to Navigate in a SimpleUniverse
You might be thinking that needing access to the view platform transform group object means abandoning
the SimpleUniverse utility. However, the SimpleUniverse, and related classes, provide a combination of
method to retrieve the ViewPlatformTransform object. Therefore, you can have your SimpleUniverse and
navigate in it too!
Specifically, the following line of code retrieves the ViewPlatformTransform from a SimpleUniverse object,
su.
TransformGroup vpt =
su.getViewingPlatform().getViewPlatformTransform();
4.4.1 Simple KeyNavigatorBehavior Example Program
It is easy to use the KeyNavigatorBehavior utility class in a Java 3D program. This section demonstrates
using the class in the KeyNavigatorApp example program found in the examples/Interaction
subdirectory. In this program you can see that the steps involved in using the KeyNavigatorBehavior class
are essentially identical to those of using any behavior class (as discussed in section 4.2.2 on page 4-7).
The steps for using KeyNavigatorBehavior are summarized in Figure 4-9.
1. create a KeyNavigatorBehavior object, setting the transform group
2. add the KeyNavigatorBehavior object to the scene graph
3. provide a bounds (or BoundingLeaf) for the KeyNavigatorBehavior object
Figure 4-9Recipe for Using the KeyNavigatorBehavior Utility Class
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-27
Like any programming problem, there are a variety of ways to implement the steps of this recipe. One
approach is to incorporate these steps in the createSceneGraph method
6
. Code Fragment 4-5 shows the
steps of the recipe as implemented for the KeyNavigatorApp example program found in the
examples/Interaction subdirectory. The code fragment is annotated with the step numbers from
the recipe. Like many of the other recipes, the exact ordering of all steps is not critical.
1. public BranchGroup createSceneGraph(SimpleUniverse su) {
2. // Create the root of the branch graph
3. TransformGroup vpTrans = null;
4.
5. BranchGroup objRoot = new BranchGroup();
6.
7. objRoot.addChild(createLand());
8.
9. // create other scene graph content
10.
11.
12. vpTrans = su.getViewingPlatform().getViewPlatformTransform();
13. translate.set( 0.0f, 0.3f, 0.0f); // 3 meter elevation
14. T3D.setTranslation(translate); // set as translation
15. vpTrans.setTransform(T3D); // used for initial position
16. O KeyNavigatorBehavior keyNavBeh = new KeyNavigatorBehavior(vpTrans);
17. O keyNavBeh.setSchedulingBounds(new BoundingSphere(
18. new Point3d(),1000.0));
19. O objRoot.addChild(keyNavBeh);
20.
21. // Let Java 3D perform optimizations on this scene graph.
22. objRoot.compile();
23.
24. return objRoot;
25. } // end of CreateSceneGraph method of KeyNavigatorApp
Code Fragment 4-5 Using the KeyNavigatorBehavior Class (part 1)
Performing step 1 of the recipe in the createSceneGraph method requires access to the ViewPlatform
transform group. This implementation passes the SimpleUniverse object (line 34 of Code Fragment 4-6) to
the createSceneGraph method making it available to access the ViewPlatform transform (line 12 of Code
Fragment 4-5).
Passing the SimpleUniverse object to the createSceneGraph method makes it possible to gain access to
other view branch graph features of the SimpleUniverse, such as PlatformGeometry, ViewerAvatar, or
adding a BoundingLeaf to the view branch graph.
Lines 13 through 15 of Code Fragment 4-5 provide an initial position for the viewer. In this case, the
viewer is translated to a position 0.3 meters above the origin of the virtual world. This is only an initial
position, and in no way limits the viewer's future position or orientation.
6
In this tutorial, createSceneGraph() is a standard method of the main class of a Java 3D program.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-28
26. public KeyNavigatorApp() {
27. setLayout(new BorderLayout());
28. Canvas3D canvas3D = new Canvas3D(null);
29. add("Center", canvas3D);
30.
31. // SimpleUniverse is a Convenience Utility class
32. SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
33.
34. BranchGroup scene = createSceneGraph(simpleU);
35.
36. simpleU.addBranchGraph(scene);
37. } // end of KeyNavigatorApp (constructor)
Code Fragment 4-6 Using the KeyNavigatorBehavior Class (part 2)
How to make Universal Application of a Behavior
As with any behavior object, the KeyNavigtorBehavior object is only active when its scheduling bounds
intersects the activation volume of a ViewPlatform. This can be particularly limiting for a navigation
behavior, where the behavior should always be on. Chapter 3 discusses a solution to this problem using a
BoundingLeaf. Refer to the BoundingLeaf section of Chapter 3 for more information.
4.4.2 KeyNavigatorBehavior and KeyNavigator Classes
The keyboard navigation utility is implemented as two classes. At run time there are two objects. The first
object is the KeyNavigatorBehavior object, the second is a KeyNavigator object. The second class is not
documented here since neither the programmer nor the user need to know that the second class or object
exists.
The KeyNavigatorBehavior object performs all the typical functions of a behavior class, except that it calls
on the KeyNavigator object to perform the processStimulus function. The KeyNavigator class takes the
AWTEvent and processes it down to the individual key stroke level. Table 4-3 shows the effect of the
individual key strokes. KeyNavigator implements motion with acceleration.
Table 4-3 KeyNavigatorBehavior Movements
Key movement Alt-key movement
rotate left lateral translate left
rotate right lateral translate right
^ move forward
+ move backward
PgUp rotate up translation up
PgDn rotate down translation down
+ restore back clip distance
(and return to the origin)
- reduce back clip distance
= return to center of universe
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-29
The following reference blocks show the API for the KeyNavigatorBehavior utility class.
KeyNavigatorBehavior Constructor Summary
Package: com.sun.j3d.utils.behaviors.keyboard
Extends: Behavior
This class is a simple behavior that invokes the KeyNavigator to modify the view platform transform.
KeyNavigatorBehavior(TransformGroup targetTG)
Constructs a new key navigator behavior node that operates on the specified transform group.
KeyNavigatorBehavior Method Summary
void initialize()
Override Behavior's initialize method to setup wakeup criteria.
void processStimulus(java.util.Enumeration criteria)
Override Behavior's stimulus method to handle the event.
4.5 Utility Classes for Mouse Interaction
the mouse utility behavior package (com.sun.j3d.utils.behaviors.mouse) contains behavior
classes in which the mouse is used as input for interaction with visual objects. Included are classes for
translating (moving in a plane parallel to the image plate), zooming (moving forward and back), and
rotating visual objects in response to mouse movements.
Table 4-4 summarizes the three specific mouse behavior classes included in the package. In addition to
these three classes, there is the abstract MouseBehavior class, and MouseCallback Interface in the mouse
behavior package. This abstract class and the interface are used in the creation of the specific mouse
behavior classes and are useful for creating custom mouse behaviors.
Table 4-4 Summary of Specific MouseBehavior Classes
MouseBehavior class Action in Response to Mouse Action Mouse Action
MouseRotate rotate visual object in place
left-button held with
mouse movement
MouseTranslate
translate the visual object in a plane parallel to the image
plate
right-button held with
mouse movement
MouseZoom
translate the visual object in a plane orthogonal to the
image plate
middle-button held
with mouse movement
4.5.1 Using the Mouse Behavior Classes
The specific mouse behavior classes are easy to use. Usage of these class is essentially the same as using
any other behavior class. Figure 4-10 presents the recipe for using Mouse Behavior classes.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-30
1. provide read and write capabilities for the target transform group
2. create a MouseBehavior object
3. set the target transform group
4. provide a bounds (or BoundingLeaf) for the MouseBehavior object
5. add the MouseBehavior object to the scene graph
Figure 4-10 Recipe for Using Mouse Behavior Classes
As with some other recipes, the steps don't have to be performed strictly in the given order. Step two must
be performed before three, four, and five; the other steps can be performed in any order. Also, steps two
and three can be combined using a different constructor.
Code Fragment 4-7 presents the createSceneGraph method from the MouseRotateApp example
program included in the examples/Interaction subdirectory. The scene graph includes ColorCube
object. The user can rotate the ColorCube using the mouse due to the inclusion of a MouseRotate object in
the scene graph. Code Fragment 4-7 is annotated with the step numbers from the recipe of Figure 4-10.
1. public class MouseRotateApp extends Applet {
2.
3. public BranchGroup createSceneGraph() {
4. // Create the root of the branch graph
5. BranchGroup objRoot = new BranchGroup();
6.
7. TransformGroup objRotate = new TransformGroup();
8. O objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
9. O objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
10.
11. objRoot.addChild(objRotate);
12. objRotate.addChild(new ColorCube(0.4));
13.
14. O MouseRotate myMouseRotate = new MouseRotate();
15. O myMouseRotate.setTransformGroup(objRotate);
16. O myMouseRotate.setSchedulingBounds(new BoundingSphere());
17. O objRoot.addChild(myMouseRotate);
18.
19. // Let Java 3D perform optimizations on this scene graph.
20. objRoot.compile();
21.
22. return objRoot;
23. } // end of CreateSceneGraph method of MouseRotateApp
Code Fragment 4-7 Using the MouseRotate Utility Class
The same recipe will work for the other two mouse behavior classes. In fact all three behaviors can be used
in the same application operating on the same visual object. Since each of the mouse behaviors reads the
target transform before writing to it, only one TransformGroup object is needed even with three mouse
behaviors. The MouseBehaviorApp example program does just that. You can find this example program
in the examples/Interaction subdirectory.
The next example shows how two mouse behaviors work in a single virtual world. The example program
MouseRotate2App creates a scene graph with two ColorCube objects near each other in the virtual
world. Each of the ColorCubes has a MouseRotate object associated with it. Since both mouse behavior
objects are active, when the user clicks and moves the mouse, both ColorCubes rotate.
If you didn't want both objects to rotate, there are two solutions: 1) change the viewer's position, or change
the behavior scheduling bounds, so that only one behavior is active, or 2) use a picking mechanism to
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-31
isolate the behavior. Picking is discussed in section 4.6. In that section you will find classes that combine
the mouse behaviors described in this section with picking, allowing the user to interact with one visual
object at a time.
4.5.2 Mouse Behavior Foundation
The specific mouse behavior classes (MouseRotate, MouseTranslate, and MouseZoom) are extensions of
the MouseBehavior abstract class and implement the MouseCallback Interface.
Mouse Behavior Abstract Class
This abstract is presented here in the event you want to extend it to write a custom mouse behavior class.
The setTransformGroup() method is probably the only method users of an instance of MouseBehavior will
use. The other methods are intended for the authors of custom mouse behavior classes.
MouseBehavior Method Summary
Base class for all mouse manipulators (see MouseRotate and MouseZoom for examples of how to extend this base
class).
void initialize()
Initializes the behavior.
void processMouseEvent(java.awt.event.MouseEvent evt)
Handles mouse events.
void processStimulus(java.util.Enumeration criteria)
All mouse manipulators must implement this method of Behavior (respond to stimuli).
void setTransformGroup(TransformGroup transformGroup)
Set the target TransformGroup for the behavior.
void wakeup()
Manually wake up the behavior.
MouseCallback Interface
A class implementing this interface provides the transformChanged method which will be called when the
target transform changes in the specified way. Each of the three specific mouse behavior classes implement
this class. A programmer can simply override the transformChanged method of one of those classes to
specify a method to be called when the transform is changed.
Interface MouseBehaviorCallback Method Summary
Package: com.sun.j3d.utils.behaviors.mouse
void transformChanged(int type, Transform3D transform)
Classes implementing this interface that are registered with one of the MouseBehaviors will be called every time
the behavior updates the Transform. The type is one of MouseCallback.ROTATE,
MouseCallback.TRANSLATE, or MouseCallback.ZOOM.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-32
4.5.3 Specific Mouse Behavior Classes
Mouse Rotate
A scene graph that includes a MouseRotate object allows the user to rotate visual objects in the virtual
world. The use of this class is explained in section 4.5.1. The example programs MouseRotateApp,
MouseRotate2App, and MouseBehaviorApp demonstrate the use of this class.
MouseRotate Constructor Summary
Package: com.sun.j3d.utils.behaviors.mouse
Extends: MouseBehavior
MouseRotate is a Java3D behavior object that lets users control the rotation of an object via a mouse left-button
drag. To use this utility, first create a transform group that this rotate behavior will operate on. The user can
rotate any child object of the target TransformGroup.
MouseRotate()
Creates a default mouse rotate behavior.
MouseRotate(TransformGroup transformGroup)
Creates a rotate behavior given the transform group.
MouseRotate(int flags)
Creates a rotate behavior with flags set, where the flags are:
MouseBehavior.INVERT_INPUT Set this flag if you want to invert the inputs.
MouseBehavior.MANUAL_WAKEUP Set this flag if you want to manually wakeup the behavior.
MouseRotate Method Summary
void setFactor(double factor)
Set the x-axis and y-axis movement multiplier with factor.
void setFactor(double xFactor, double yFactor)
Set the x-axis and y-axis movement multiplier with xFactor and yFactor respectively.
void setupCallback(MouseBehaviorCallback callback)
The transformChanged method in the callback class will be called every time the transform is updated
void transformChanged(Transform3D transform)
Users can overload this method which is called every time the Behavior updates the transform. The default
implementation does nothing.
MouseTranslate
A scene graph that includes a MouseTranslate object allows the user to move visual objects in a plane
parallel to the image plate in the virtual world. The use of this class is explained in section 4.5.1. The
example program MouseBehaviorApp demonstrates the use of this class.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-33
MouseTranslate Constructor Summary
Package: com.sun.j3d.utils.behaviors.mouse
Extends: MouseBehavior
MouseTranslate is a Java3D behavior object that lets users control the translation (X, Y) of an object via a mouse
drag motion with the right mouse button.
MouseTranslate()
Creates a default translate behavior.
MouseTranslate(TransformGroup transformGroup)
Creates a mouse translate behavior given the transform group.
MouseTranslate(int flags)
Creates a translate behavior with flags set, where the flags are:
MouseBehavior.INVERT_INPUT Set this flag if you want to invert the inputs.
MouseBehavior.MANUAL_WAKEUP Set this flag if you want to manually wakeup the behavior.
MouseTranslate Method Summary
void setFactor(double factor)
Set the x-axis and y-axis movement multiplier with factor.
void setFactor(double xFactor, double yFactor)
Set the x-axis and y-axis movement multiplier with xFactor and yFactor respectively.
void setupCallback(MouseBehaviorCallback callback)
The transformChanged method in the callback class will be called every time the transform is updated
void transformChanged(Transform3D transform)
Users can overload this method which is called every time the Behavior updates the transform. The default
implementation does nothing.
MouseZoom
A scene graph that includes a MouseZoom object allows the user to move visual objects in a plane
orthogonal to the image plate in the virtual world. The use of this class is explained in section 4.5.1. The
example program MouseBehaviorApp demonstrates the use of this class.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-34
MouseZoom Constructor Summary
Package: com.sun.j3d.utils.behaviors.mouse
Extends: MouseBehavior
MouseZoom is a Java3D behavior object that lets users control the Z axis translation of an object via a mouse drag
motion with the second middle button (alt-click on PC with two-button mouse). See MouseRotate for similar usage
info.
MouseZoom()
Creates a default mouse zoom behavior.
MouseZoom(TransformGroup transformGroup)
Creates a zoom behavior given the transform group.
MouseZoom(int flags)
Creates a zoom behavior with flags set, where the flags are:
MouseBehavior.INVERT_INPUT Set this flag if you want to invert the inputs.
MouseBehavior.MANUAL_WAKEUP Set this flag if you want to manually wakeup the behavior.
MouseZoom Method Summary
void setFactor(double factor)
Set the z-axis movement multiplier with factor.
void setupCallback(MouseBehaviorCallback callback)
The transformChanged method in the callback class will be called every time the transform is updated
void transformChanged(Transform3D transform)
Users can overload this method which is called every time the Behavior updates the transform. The default
implementation does nothing.
4.5.4 Mouse Navigation
The three specific mouse behavior classes can be used to create a virtual universe in which the mouse is
used for navigation. Each of the specific mouse behavior classes has a constructor that takes a single int
flags parameter. When the MouseBehavior.INVERT_INPUTS is used as the argument to this
constructor, the mouse behavior responds in the opposite direction. This reverse behavior is appropriate
for changing the ViewPlatform transform. In other words, the mouse behavior classes can be used for
navigational control.
The example program MouseNavigatorApp uses instances of the three specific mouse behavior
classes for navigational interaction. The complete source for this example program is in the
examples/Interaction subdirectory. Code Fragment 4-8 shows the createSceneGraph method
from this example program.
The target TransformGroup for each of the mouse behavior objects is the ViewPlatform transform. The
SimpleUniverse object is an argument to the createSceneGraph method so that the ViewPlatform transform
object can be accessed.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-35
1. public BranchGroup createSceneGraph(SimpleUniverse su) {
2. // Create the root of the branch graph
3. BranchGroup objRoot = new BranchGroup();
4. TransformGroup vpTrans = null;
5. BoundingSphere mouseBounds = null;
6.
7. vpTrans = su.getViewingPlatform().getViewPlatformTransform();
8.
9. objRoot.addChild(new ColorCube(0.4));
10. objRoot.addChild(new Axis());
11.
12. mouseBounds = new BoundingSphere(new Point3d(), 1000.0);
13.
14. MouseRotate myMouseRotate = new
MouseRotate(MouseBehavior.INVERT_INPUT);
15. myMouseRotate.setTransformGroup(vpTrans);
16. myMouseRotate.setSchedulingBounds(mouseBounds);
17. objRoot.addChild(myMouseRotate);
18.
19. MouseTranslate myMouseTranslate = new
MouseTranslate(MouseBehavior.INVERT_INPUT);
20. myMouseTranslate.setTransformGroup(vpTrans);
21. myMouseTranslate.setSchedulingBounds(mouseBounds);
22. objRoot.addChild(myMouseTranslate);
23.
24. MouseZoom myMouseZoom = new MouseZoom(MouseBehavior.INVERT_INPUT);
25. myMouseZoom.setTransformGroup(vpTrans);
26. myMouseZoom.setSchedulingBounds(mouseBounds);
27. objRoot.addChild(myMouseZoom);
28.
29. // Let Java 3D perform optimizations on this scene graph.
30. objRoot.compile();
31.
32. return objRoot;
33. } // end of createSceneGraph method of MouseNavigatorApp
Code Fragment 4-8 Using Mouse Behavior Classes for Interactive Navigation of the Virtual World.
The bounds object for the mouse behavior objects is specified as a BoundingSphere with a radius of 1000
meters. If the viewer moves beyond this sphere, the behavior objects will no longer be active.
4.6 Picking
In the MouseRotate2App example program, both ColorCube objects rotated in response to the actions of
the user. In that application, there is no way to manipulate the cubes separately. Picking gives the user a
way to interact with individual visual objects in the scene.
Picking is implemented by a behavior typically triggered by mouse button events. In picking a visual
object, the user places the mouse pointer over the visual object of choice and presses the mouse button.
The behavior object is triggered by this button press and begins the picking operation. A ray is projected
into the virtual world from the position of the mouse pointer parallel with the projection. Intersection of
this ray with the objects of the virtual world is computed. The visual object intersecting closest to the
image plate is selected for interaction
7
. Figure 4-1 shows a pick ray projected in a virtual world.
7
While interacting with the closest visual object is the most common picking application, picking operations are
not limited to selecting the closest visual object. Some picking operations produce a list of all intersected objects.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-36
image plate
visual
object
mouse pointer pick ray
Figure 4-11 Projection of PickRay in the Virtual World
In some cases the interaction is not directly with the selected object, but with an object along the scene
graph path to the object. For example, in picking a ColorCube object for rotation, the ColorCube object is
not manipulated; the TransformGroup object above the ColorCube in the scene graph path to the
ColorCube is. On the other hand, if the pick operation selects a visual object for which a color change is
intended, then the visual object selected is indeed required.
The determination of the object for further processing is not always easy. If a cubic visual object that is to
be rotated is composed of six individual Shape3D objects arranged by six TransformGroup objects, as in
the scene graph diagram of Figure 4-12, it is not the TransformGroup object above the intersected
Shape3D object that needs to be modified. The 'cube' is rotated by manipulation of the TransformGroup
object that is the child of the BranchGroup object in the scene graph. For this reason, the result of some
picking operations is to return the scene graph path for further processing.
BG
S
TG
S
TG
S
TG
S
TG
S
TG
S
TG
TG
Figure 4-12 Scene Graph Diagram for a Cube Composed of Discrete Shape3D Plane Objects.
Intersection testing is computationally expensive. Therefore, picking is computationally expensive and is
more expensive with increasing complexity of the scene. The Java 3D API provides a number of ways that
a programmer can limit the amount of computation done in picking. One important way is through the
capabilities and attributes of scene graph nodes. Whether or not a scene graph node is pickable is set with
the setPickable() method of the class. A node with setPickable() set to false is not
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-37
pickable and neither are any of its children. Consequently, these nodes are not considered when calculating
intersections.
Another pick related feature of the Node class is the ENABLE_PICK_REPORTING capability. This
capability applies only to Group nodes. When set for a Group, that group object will always be included in
the scene graph path returned by a pick operation. Group nodes not needed for uniqueness in a scene graph
path will be excluded when the capability is not set. Not having the right settings for scene graph nodes is
a common source of frustration in developing applications utilizing picking operations.
The following two reference blocks list Node methods and capabilities, respectively.
Node Method (partial list)
extends: SceneGraphObject
subclasses: Group, Leaf
The Node class provides an abstract class for all Group and Leaf Nodes. It provides a common framework for
constructing a Java 3D scene graph, specifically bounding volumes, picking and collision capabilities.
void setBounds(Bounds bounds)
Sets the geometric bounds of a node.
void setBoundsAutoCompute(boolean autoCompute)
Turns the automatic calcuation of geometric bounds of a node on/off.
setPickable(boolean pickable)
When set to true this Node can be Picked. Setting to false indicates that this node and it's children are ALL
unpickable.
Node Capabilities Summary (partial list)
ENABLE_PICK_REPORTING
Specifies that this Node will be reported in the pick SceneGraphPath if a pick occurs. This capability is only
specifiable for Group nodes; it is ignored for leaf nodes. The default for Group nodes is false. Interior nodes not
needed for uniqueness in a SceneGraphPath that don't have ENABLE_PICK_REPORTING set will be excluded
from the SceneGraphPath.
ALLOW_BOUNDS_READ | WRITE
Specifies that this Node allows read (write) access to its bounds information.
ALLOW_PICKABLE_READ | WRITE
Specifies that this Node allows reading (writing) its pickability state.
Another way a programmer can reduce the computation of picking is to use bounds intersection testing
instead of geometric intersection testing. Several of the pick related classes have constructors and/or
methods have a parameter, which is set to one of: USE_BOUNDS or USE_GEOMETRY. When the
USE_BOUNDS option is selected, the pick is determined using the bounds of the visual objects, not the
actual geometry. The determination of a pick using the bounds is significantly easier (computationally) for
all but the simplest geometric shapes and therefore, results in better performance. Of course, the drawback
is the picking is not as precise when using bounds pick determination.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-38
A third programming technique for reducing the computational cost of picking is to limit the scope of the
pick testing to the relevant portion of the scene graph. In each picking utility class a node of the scene
graph is set as the root of the graph for pick testing. This node is not necessarily the root of the content
branch graph. On the contrary, the node passed should be the root of the content subgraph that only
contains pickable objects, if possible. This consideration may be a major factor in determining the
construction of the scene graph for some applications.
4.6.1 Using Picking Utility Classes
There are two basic approaches to using the picking features of Java 3D: use objects of picking classes, or
create custom picking classes and use instances of these custom classes. The picking package includes
classes for pick/rotate, pick/translate, and pick/zoom. That is, a user can pick and rotate an object by
pressing the mouse button when the mouse pointer is over the desired object and then dragging the mouse
(while holding the button down). Each of the picking classes uses a different mouse button making it
possible to use objects of all three picking class in the same application simultaneously.
Section 4.6.4 presents the PickRotateBehavior, PickTranslateBehavior, and
PickZoomBehavior utility classes. Section 4.6.2 presents classes useful for creating custom picking
classes. This section presents a complete programming example using the PickRotate class.
Since a picking behavior object will operate on any scene graph object (with the appropriate capabilities),
only one picking behavior object is necessary to provide picking. The following two lines of code is just
about all that is needed to include picking via the picking utility classes in a Java 3D program:
PickRotateBehavior behavior = new PickRotateBehavior(root, canvas, bounds);
root.addChild(behavior);
The above behavior object will monitor for any picking events on the scene graph (below root node)
and handle mouse drags on pick hits. The root provides the portion of the scene graph to be checked for
picking, the canvas is the place where the mouse is, and the bounds is the scheduling bounds of the
picking behavior object.
Figure 4-13 shows the simple recipe for using the mouse picking utility classes.
1. Create your scene graph.
2. Create a picking behavior object with root, canvas, and bounds specification.
3. Add the behavior object to the scene graph.
4. Enable the appropriate capabilities for scene graph objects
Figure 4-13 Recipe for Using Mouse Picking Utility Classes
Programming Pitfalls when Using Picking Objects
Using the picking behavior classes leads to the same programming pitfalls as using other behavior classes.
Common problems include: forgetting to include the behavior object in the scene graph, and not setting an
appropriate bounds for the behavior object. See "Programming Pitfalls of Using Behavior Objects" on
page 4-9 for more details.
There are pitfalls specific to picking in addition to the pitfalls common to using behavior objects. The most
common problem is not setting the proper capabilities for scene graph objects. Two other possible
problems are less likely, however you should check for these if your picking application is not working.
One is not setting the root of the scene graph properly. Another potential problem is not setting the canvas
properly. None of these programming mistakes will generate an error or warning message.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-39
MousePickApp Example Program
Code Fragment 4-9 shows the createSceneGraph method of MousePickApp. The complete
source code for this example program is included in the examples/Interaction subdirectory of the
example programs jar. This program uses a PickRotate object to provide interaction. This code is
annotated with the step numbers from the recipe of Figure 4-13.
Note that since the construction of the picking object requires the Canvas3D object, the createSceneGraph
method differs from earlier versions by the inclusion of the canvas parameter. Of course, the invocation of
createSceneGraph changes correspondingly.
1. public BranchGroup createSceneGraph(Canvas3D canvas) {
2. // Create the root of the branch graph
3. BranchGroup objRoot = new BranchGroup();
4.
5. TransformGroup objRotate = null;
6. PickRotateBehavior pickRotate = null;
7. Transform3D transform = new Transform3D();
8. BoundingSphere behaveBounds = new BoundingSphere();
9.
10. // create ColorCube and PickRotateBehavior objects
11. transform.setTranslation(new Vector3f(-0.6f, 0.0f, -0.6f));
12. objRotate = new TransformGroup(transform);
13. objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
14. O objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
15. objRotate.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
16.
17. objRoot.addChild(objRotate);
18. objRotate.addChild(new ColorCube(0.4));
19.
20. O pickRotate = new PickRotateBehavior(objRoot,canvas, behaveBounds);
21. O objRoot.addChild(pickRotate);
22.
23. // add a second ColorCube object to the scene graph
24. transform.setTranslation(new Vector3f( 0.6f, 0.0f, -0.6f));
25. objRotate = new TransformGroup(transform);
26. objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
27. O objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
28. objRotate.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
29.
30. objRoot.addChild(objRotate);
31. objRotate.addChild(new ColorCube(0.4));
32.
33. // Let Java 3D perform optimizations on this scene graph.
34. objRoot.compile();
35.
36. return objRoot;
37. } // end of createSceneGraph method of MousePickApp
Code Fragment 4-9 The createSceneGraph Method of the MousePickApp Example Program.
This code is similar to that of MouseRotate2App, but is different in some very distinct ways. Primarily,
there is only one behavior object used in this program, where the MouseRotate2App used two behavior
objects one per visual object. While the code is similar, the behavior is very different. This program
allows the user to pick an object to interact with. MouseRotate2App rotates both objects or neither object.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-40
4.6.2 Java 3D API Core Picking Classes
There are three 'levels' of picking classes provided in Java 3D. The Java 3D API core provides the lowest
level functionality. The picking utility package provides general picking behavior classes, suitable for
customization. The picking utility package also provides specific picking behavior classes which can be
used directly in Java 3D programs.
The core classes include PickShape and SceneGraphPath classes, and methods of BranchGroup and
Locale. These classes provide the mechanisms for specifying a shape used in testing for intersection with
visual objects. This section presents the API of the PickShape and SceneGraphPath classes, and related
classes and methods.
The general picking utility package classes combine basic picking operations in behavior objects. The
specific picking utility classes use the general classes to implement specific picking behaviors.
PickShape classes
This abstract class provides neither constructors nor methods. It provides abstraction for four subclasses:
PickBounds, PickRay, PickSegment, and PickPoint.
PickShape
Known Subclasses: PickBounds, PickRay, PickSegment, and PickPoint
A general class for describing a pick shape which can be used with the BranchGroup and Locale pick methods.
PickBounds
PickBounds objects represent a bounds for pick testing. As a subclass of PickShape, PickBounds objects
are used with BranchGroup and Locale pick testing as well as picking package classes.
PickBounds Constructor Summary
extends: PickShape
A bounds to supply to the BranchGroup and Locale pick methods
PickBounds()
Create a PickBounds.
PickBounds(Bounds boundsObject)
Create a PickBounds with the specified bounds.
Method Summary
Bounds get()
Get the boundsObject from this PickBounds.
void set(Bounds boundsObject)
Set the boundsObject into this PickBounds.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-41
PickPoint
PickPoint objects represent a point for picking. As a subclass of PickShape, PickPoint objects are used
with BranchGroup and Locale pick testing as well as picking package classes.
PickPoint Constructor Summary
extends: PickShape
A point to supply to the BranchGroup and Locale pick methods
PickPoint()
Create a PickPoint at (0, 0, 0).
PickPoint(Point3d location)
Create a PickPoint at location.
PickPoint Method Summary
void set(Point3d location)
Set the position of this PickPoint. There is a matching get method.
PickRay
PickRay objects represent a ray (a point and a direction) for picking. As a subclass of PickShape, PickRay
objects are used with BranchGroup and Locale pick testing as well as picking package classes.
PickRay Constructor Summary
extends: PickShape
PickRay is an encapsulation of a ray for passing to the pick methods in BranchGroup and Locale
PickRay()
Create a PickRay with origin and direction of (0, 0, 0).
PickRay(Point3d origin, Vector3d direction)
Create a ray cast from origin in direction direction.
PickRay Method Summary
void set(Point3d origin, Vector3d direction)
Set the ray to point from origin in direction direction. There is a matching get method.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-42
PickSegment
PickSegment objects represent a line segment (defined by two points) for picking. As a subclass of
PickShape, PickSegment objects are used with BranchGroup and Locale pick testing as well as picking
package classes.
PickSegment Constructor Summary
extends: PickShape
PickRay is an encapsulation of ray for passing to the pick methods in BranchGroup and Locale
PickSegment()
Create a PickSegment.
PickSegment(Point3d start, Point3d end)
Create a pick segment from start point to end point.
PickSegment Method Summary
void set(Point3d start, Point3d end)
Set the pick segment from start point to end point. There is a matching get method.
SceneGraphPath
The class SceneGraphPath is used in most picking applications. This is because picking usually involves
finding a scene graph path that the picked object lies in to allow manipulation of the object or a
TransformGroup object in the path.
A SceneGraphPath object represents the scene graph path to the picked object allowing manipulation of the
object or a TransformGroup object in the path to the object. SceneGraphPath is used in the picking
package as well as Java 3D core
SceneGraphPath Overview
A SceneGraphPath object represents the path from a Locale to a terminal node in the scene graph. This path
consists of a Locale, a terminal node, and an array of internal nodes that are in the path from the Locale to the
terminal node. The terminal node may be either a Leaf node or a Group node. A valid SceneGraphPath must
uniquely identify a specific instance of the terminal node. For nodes that are not under a SharedGroup, the
minimal SceneGraphPath consists of the Locale and the terminal node itself. For nodes that are under a
SharedGroup, the minimal SceneGraphPath consists of the Locale, the terminal node, and a list of all Link nodes
in the path from the Locale to the terminal node. A SceneGraphPath may optionally contain other interior nodes
that are in the path. A SceneGraphPath is verified for correctness and uniqueness when it is sent as an argument to
other methods of Java 3D.
In the array of internal nodes, the node at index 0 is the node closest to the Locale. The indices increase along the
path to the terminal node, with the node at index length-1 being the node closest to the terminal node. The array of
nodes does not contain either the Locale (which is not a node) or the terminal node.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-43
SceneGraphPath Constructor Summary
When a SceneGraphPath is returned from the picking or collision methods of Java 3D, it will also contain the
value of the LocalToVworld transform of the terminal node that was in effect at the time the pick or collision
occurred. Note that ENABLE_PICK_REPORTING and ENABLE_COLLISION_REPORTING are disabled by
default. This means that the picking and collision methods will return the minimal SceneGraphPath by default.
SceneGraphPath()
Constructs a SceneGraphPath object with default parameters.
SceneGraphPath(Locale root, Node object)
Constructs a new SceneGraphPath object.
SceneGraphPath(Locale root, Node[] nodes, Node object)
Constructs a new SceneGraphPath object.
SceneGraphPath Method Summary (partial list)
boolean equals(java.lang.Object o1)
Returns true if the Object o1 is of type SceneGraphPath and all of the data members of o1 are equal to the
corresponding data members in this SceneGraphPath and if the values of the transforms is equal.
Transform3D getTransform()
Returns a copy of the transform associated with this SceneGraphPath; returns null if there is no transform.
int hashCode()
Returns a hash number based on the data values in this object.
boolean isSamePath(SceneGraphPath testPath)
Determines whether two SceneGraphPath objects represent the same path in the scene graph; either object might
include a different subset of internal nodes; only the internal link nodes, Locale, and the Node itself are compared.
int nodeCount()
Retrieves the number of nodes in this path.
void set(SceneGraphPath newPath)
Sets this path's values to that of the specified path.
void setLocale(Locale newLocale)
Sets this path's Locale to the specified Locale.
void setNode(int index, Node newNode)
Replaces the node at the specified index with newNode.
void setNodes(Node[] nodes)
Sets this path's node objects to the specified node objects.
void setObject(Node object)
Sets this path's terminal node to the specified node object.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-44
SceneGraphPath Method Summary (partial list - continued)
void setTransform(Transform3D trans)
Sets the transform component of this SceneGraphPath to the value of the passed transform.
java.lang.String toString()
Returns a string representation of this object; the string contains the class names of all Nodes in the
SceneGraphPath, the toString() method of any associated user, and also prints out the transform if it is not null.
BranchGroup and Local Picking Methods
Presented in the following reference block are methods of the BranchGroup and Local classes for
intersection testing with PickShape objects. This is the lowest level pick computation provided by the Java
3D API.
BranchGroup and Locale picking methods for use with PickShape
SceneGraphPath[] pickAll(PickShape pickShape)
Returns an array referencing all the items that are pickable below this BranchGroup that intersect with PickShape.
The resultant array is unordered.
SceneGraphPath[] pickAllSorted(PickShape pickShape)
Returns a sorted array of references to all the Pickable items that intersect with the pickShape. Element [0]
references the item closest to origin of PickShape, with successive array elements further from the origin. Note: If
pickShape is of type PickBounds, the resultant array is unordered.
SceneGraphPath pickClosest(PickShape pickShape)
Returns a SceneGraphPath which references the pickable item which is closest to the origin of pickShape. Note: If
pickShape is of type PickBounds, the return is any pickable node below this BranchGroup.
SceneGraphPath pickAny(PickShape pickShape)
Returns a reference to any item that is Pickable below this BranchGroup which intersects with pickShape.
4.6.3 General Picking Package Classes
Included in the com.sun.j3d.utils.behaviors.picking package are general and specific pick
behavior classes. The general picking classes are useful in creating new picking behaviors. The general
picking classes include PickMouseBehavior, PickObject, and PickCallback. The specific
mouse behavior classes, presented in the next section, are subclasses of the PickMouseBehavior
class.
PickMouseBehavior Class
This is the base class for the specific picking behaviors provided in the package. It is also useful for
extending to custom picking behavior classes.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-45
PickMouseBehavior Method Summary
Package: com.sun.j3d.utils.behaviors.picking
Extends: Behavior
Base class that allows programmers to add picking and mouse manipulation to a scene graph (see
PickDragBehavior for an example of how to extend this base class).
void initialize()
This method should be overridden to provide initial state and the initial trigger condition.
void processStimulus(java.util.Enumeration criteria)
This method should be overridden to provide the behavior in response to a wakeup condition.
void updateScene(int xpos, int ypos)
Subclasses shall implement this update function
PickObject Class
The PickObject class provides methods for determining which object was selected by a user pick operation.
A wide variety of methods provide results in various formats for various possible picking applications. It
is useful in creating custom picking classes.
PickObject Constructor Summary
package: com.sun.j3d.utils.behaviors.picking
extends: java.lang.Object
Contains methods to aid in picking. A PickObject is created for a given Canvas3D and a BranchGroup.
SceneGraphObjects under the specified BranchGroup can then be checked to determine if they have been picked.
PickObject(Canvas3D c, BranchGroup root)
Creates a PickObject.
PickObject Method Summary (partial list)
PickObject has numerous method for computing the intersection of a pickRay with scene graph objects. Some of
the methods differ by only one parameter. For example, the second pickAll method (not listed) exists with the
method signature of: SceneGraphPath[] pickAll(int xpos, int ypos, int flag), where flag
is one of: PickObject.USE_BOUNDS, or PickObject.USE_GEOMETRY.
This list has been shortened by excluding the methods with the flag parameter. These methods are identical to
methods included in this list with the difference of the flag parameter. These methods are: pickAll ,
pickSorted, pickAny, and pickClosest.
PickShape generatePickRay(int xpos, int ypos)
Creates a PickRay that starts at the viewer position and points into the scene in the direction of (xpos, ypos)
specified in window space.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-46
PickObject Method Summary (partial list - continued)
SceneGraphPath[] pickAll(int xpos, int ypos)
Returns an array referencing all the items that are pickable below the BranchGroup (specified in the PickObject
constructor) that intersect with a ray that starts at the viewer position and points into the scene in the direction of
(xpos, ypos) specified in window space.
SceneGraphPath[] pickAllSorted(int xpos, int ypos)
Returns a sorted array of references to all the Pickable items below the BranchGroup (specified in the PickObject
constructor) that intersect with the ray that starts at the viewer position and points into the scene in the direction of
(xpos, ypos) in the window space.
SceneGraphPath pickAny(int xpos, int ypos)
Returns a reference to any item that is Pickable below the specified BranchGroup (specified in the PickObject
constructor) which intersects with the ray that starts at the viewer position and points into the scene in the direction
of (xpos, ypos) in window space.
SceneGraphPath pickClosest(int xpos, int ypos)
Returns a reference to the item that is closest to the viewer and is Pickable below the BranchGroup (specified in the
PickObject constructor) which intersects with the ray that starts at the viewer position and points into the scene in
the direction of (xpos, ypos) in the window space.
Node pickNode(SceneGraphPath sgPath, int node_types)
Returns a reference to a Pickable Node that is of the specified type that is contained in the specified
SceneGraphPath. Where node_types is the logical OR of one or more of: PickObject.BRANCH_GROUP,
PickObject.GROUP, PickObject.LINK, PickObject.MORPH, PickObject.PRIMITIVE,
PickObject.SHAPE3D, PickObject.SWITCH, PickObject.TRANSFORM_GROUP.
Node pickNode(SceneGraphPath sgPath, int node_types, int occurrence)
Returns a reference to a Pickable Node that is of the specified type that is contained in the specified
SceneGraphPath. Where node_types is as defined for the above method. The occurrence parameter indicates
which object to return.
PickingCallback Interface
The PickingCallback Interface provides a framework for extending an existing picking class. In particular,
each of the specific pick classes (in Section 4.6.4) implements this interface allowing the programmer to
provide a method to be called when a pick operation takes place.
Interface PickingCallback Method Summary
package: com.sun.j3d.utils.behaviors.picking
void transformChanged(int type, TransformGroup tg)
Called by the Pick Behavior with which this callback is registered each time the pick is attempted. Valid values for
type are: ROTATE, TRANSLATE, ZOOM or NO_PICK (the user made a selection but nothing was actually
picked).
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-47
Intersect Class
The Intersect Class provides a number of methods for testing for the intersection of a PickShape (core
class) object and geometry primitives. This class is useful in creating custom picking classes.
Intersect Constructor Summary
package: com.sun.j3d.utils.behaviors.picking
extends: java.lang.Object
Contains static methods to aid in the intersection test between various PickShape classes and geometry primitives
(such as quad, triangle, line and point).
Intersect()
Create an intersect object.
Intersect Method Summary (partial list)
The Intersect class has numerous intersection methods, some of which only differ by one parameter type. For
example, the method: boolean pointAndPoint(PickPoint point, Point3f pnt) differs from the
second listed method here by only the type of the pnt parameter. Most of the methods listed here with a parameter
of type Point3d have a corresponding method with a parameter of type Point3f.
boolean pointAndLine(PickPoint point, Point3d[] coordinates, int index)
Return true if the PickPoint and Line objects intersect. coordinates[index] and coordinates[index+1] define the line
boolean pointAndPoint(PickPoint point, Point3d pnt)
Return true if the PickPoint and Point3d objects intersect.
boolean rayAndLine(PickRay ray, Point3d[] coordinates, int index,
double[] dist)
Return true if the PickRay and Line objects intersect. coordinates[index] and coordinates[index+1] define the line.
boolean rayAndPoint(PickRay ray, Point3d pnt, double[] dist)
Return true if the PickRay and Point3d objects intersect.
boolean rayAndQuad(PickRay ray, Point3d[] coordinates, int index,
double[] dist)
Return true if the PickRay and quadrilateral objects intersect.
boolean rayAndTriangle(PickRay ray, Point3d[] coordinates, int index,
double[] dist)
Return true if triangle intersects with ray and the distance, from the origin of ray to the intersection point, is stored
in dist[0]. coordinates[index], coordinates[index+1], and coordinates[index+2] define the triangle.
boolean segmentAndLine(PickSegment segment, Point3d[] coordinates, int index,
double[] dist)
Return true if line intersects with segment; the distance from the start of segment to the intersection point is stored
in dist[0]. coordinates[index] and coordinates[index+1] define the line.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-48
Intersect Method Summary (partial list - continued)
boolean segmentAndPoint(PickSegment segment, Point3d pnt, double[] dist)
Return true if the PickSegment and Point3d objects intersect.
boolean segmentAndQuad(PickSegment segment, Point3d[] coordinates, int index,
double[] dist)
Return true if quad intersects with segment; the distance from the start of segment to the intersection point is
stored in dist[0].
boolean segmentAndTriangle(PickSegment segment, Point3d[] coordinates,
int index, double[] dist)
Return true if triangle intersects with segment; the distance from the start of segment to the intersection point is
stored in dist[0].
4.6.4 Specific Picking Behavior Classes
Included in the com.sun.j3d.utils.behaviors.picking package are specific pick behavior
classes: PickRotateBehavior, PickTranslateBehavior, and PickZoomBehavior.
These classes allow the user to interact with a picked object with the mouse. The individual behaviors
respond to different mouse buttons (left=rotate, right=translate, middle=zoom). All three specific mouse
behavior classes are subclasses of the PickMouseBehavior class.
Objects of these classes can be incorporated in Java 3D virtual worlds to provide interaction by following
the recipe provided in Figure 4-13. Since each of these classes implements the PickingCallback Interface,
the operation of the picking can be augmented with a call to a user defined method. Refer to the
PickingCallback Interface documentation in 4.6.2 for more information.
PickRotateBehavior
The PickRotateBehavior allows the user to interactively pick and rotate visual objects. The user uses the
left mouse button for pick selection and rotation. An instance of PickRotateBehavior can be used in
conjunction with other specific picking classes.
PickRotateBehavior Constructor Summary
package: com.sun.j3d.utils.behaviors.picking
extends: PickMouseBehavior
implements: PickingCallback
A mouse behavior that allows user to pick and rotate scene graph objects; expandable through a callback.
PickRotateBehavior(BranchGroup root, Canvas3D canvas, Bounds bounds)
Creates a pick/rotate behavior that waits for user mouse events for the scene graph.
PickRotateBehavior(BranchGroup root, Canvas3D canvas, Bounds bounds,
int pickMode)
Creates a pick/rotate behavior that waits for user mouse events for the scene graph. The pickMode parameter is
specified as one of PickObject.USE_BOUNDS or PickObject.USE_GEOMETRY. Note: If pickMode is
set to PickObject.USE_GEOMETRY, all geometry objects in the scene graph intended to be available for
picking must have their ALLOW_INTERSECT bit set.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-49
PickRotateBehavior Method Summary
void setPickMode(int pickMode)
Sets the pickMode component of this PickRotateBehavior to one of PickObject.USE_BOUNDS or
PickObject.USE_GEOMETRY. Note: If pickMode is set to PickObject.USE_GEOMETRY, all geometry
objects in the scene graph intended to be available for picking must have their ALLOW_INTERSECT bit set.
void setupCallback(PickingCallback callback)
Register the class callback to be called each time the picked object moves.
void transformChanged(int type, Transform3D transform)
Callback method from MouseRotate. This is used when the Picking callback is enabled.
void updateScene(int xpos, int ypos)
Update the scene to manipulate any nodes.
PickTranslateBehavior
The PickTranslateBehavior allows the user to interactively pick and translate visual objects. The user uses
the right mouse button for pick selection and translation. An instance of PickTranslateBehavior can be
used in conjunction with other specific picking classes.
PickTranslateBehavior Constructor Summary
package: com.sun.j3d.utils.behaviors.picking
extends: PickMouseBehavior
implements: PickingCallback
A mouse behavior that allows user to pick and translate scene graph objects. The behavior is expandable through a
callback.
PickTranslateBehavior(BranchGroup root, Canvas3D canvas, Bounds bounds)
Creates a pick/translate behavior that waits for user mouse events for the scene graph.
PickTranslateBehavior(BranchGroup root, Canvas3D canvas, Bounds bounds,
int pickMode)
Creates a pick/translate behavior that waits for user mouse events for the scene graph. . The pickMode parameter is
specified as one of PickObject.USE_BOUNDS or PickObject.USE_GEOMETRY. Note: If pickMode is
set to PickObject.USE_GEOMETRY, all geometry objects in the scene graph intended to be available for
picking must have their ALLOW_INTERSECT bit set.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-50
PickTranslateBehavior Method Summary
void setPickMode(int pickMode)
Sets the pickMode component of this PickTranslateBehavior to the value of the passed pickMode.
void setupCallback(PickingCallback callback)
Register the class callback to be called each time the picked object moves.
void transformChanged(int type, Transform3D transform)
Callback method from MouseTranslate. This is used when the Picking callback is enabled.
void updateScene(int xpos, int ypos)
Update the scene to manipulate any nodes.
PickZoomBehavior
The PickZoomBehavior allows the user to interactively pick and zoom visual objects. The user uses the
middle mouse button for pick selection and zooming. An instance of PickZoomBehavior can be used in
conjunction with other specific picking classes.
PickZoomBehavior Constructor Summary
package: com.sun.j3d.utils.behaviors.picking
extends: PickMouseBehavior
implements: PickingCallback
A mouse behavior that allows user to pick and zoom scene graph objects. The behavior is expandable through a
callback.
PickZoomBehavior(BranchGroup root, Canvas3D canvas, Bounds bounds)
Creates a pick/zoom behavior that waits for user mouse events for the scene graph.
PickZoomBehavior(BranchGroup root, Canvas3D canvas, Bounds bounds,
int pickMode)
Creates a pick/zoom behavior that waits for user mouse events for the scene graph. The pickMode parameter is
specified as one of PickObject.USE_BOUNDS or PickObject.USE_GEOMETRY. Note: If pickMode is
set to PickObject.USE_GEOMETRY, all geometry objects in the scene graph intended to be available for
picking must have their ALLOW_INTERSECT bit set.
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-51
PickZoomBehavior Method Summary
void setPickMode(int pickMode)
Sets the pickMode component of this PickZoomBehavior to the value of the passed pickMode.
void setupCallback(PickingCallback callback)
Register the class callback to be called each time the picked object moves.
void transformChanged(int type, Transform3D transform)
Callback method from MouseZoom. This is used when the Picking callback is enabled.
void updateScene(int xpos, int ypos)
Update the scene to manipulate any nodes.
4.7 Chapter Summary
This chapter begins by explaining the significance of the Behavior class in providing interaction and
animation in the Java 3D virtual universe. This chapter provides a comprehensive view of Java 3D core
and utility classes used in providing interaction for viewer navigation of the virtual world, picking and
interacting with individual visual objects, and how to create new interactive behavior classes.
Section 4.2 shows how custom behavior classes are written and then shows how to incorporate behavior
objects to provide interaction in a Java 3D virtual world. Section 4.3 discusses the various classes used in
the specification of behavior trigger conditions. Section 4.4 discusses the KeyNavigatorBehavior class
which is used for view navigation through key strokes. Section 4.5 presents mouse interaction classes.
Section 4.6 presents the topic of picking in general and discusses utility classes used to provide picking
interaction.
4.8 Self Test
1. Write a custom behavior application that moves visual objects to the left and right when a the left and
right arrow keys are pressed, respectively. Then use the class in an application similar to
SimpleBehaviorApp.java. Of course, you can use SimpleBehaviorApp.java as a starting point for both
the custom behavior class and the application. What happens as the ColorCube object moves out of
the view? How do you fix the problem?
2. In SimpleBehaviorApp, the rotation is computed using an angle variable of type double. The angle
variable is used to set the rotation of a Transform3D object which sets the transform of the
TransformGroup. An alternative would eliminate the angle variable using only a Transform3D object
to control the angle increment. There are two variations on this approach: one would read the current
transform of the TransformGroup and then multiply, another would store the transform in a local
Transform3D object. In either case, the new rotation is found by multiplying the previous
Transform3D with the Transform3D that holds the rotation increment. What problem may occur with
this alternative? What improvement can be made to this approach?
3. Change the trigger condition in the SimpleBehavior class to new ElapsedFrame(0). Compile and
run the modified program. Note the result. Change the code to remove the memory burn problem from
the class. Then recompile and run the fixed program.
4. Change the scheduling bounds for the KeyNavigatorBehavior object to something smaller (e.g., a
bounding sphere with a radius of 10), then run the application again. What happens when you move
Module2: Interaction and Animation Chapter 4. Interaction
The Java 3D Tutorial 4-52
beyond the new bounds? Convert the scheduling bounds for KeyNavigatorApp to a universal
application so that you can't get stuck at the edge of the world. See Chapter 3 for more information on
BoundingLeaf nodes.
5. Use the KeyNavigatorBehavior with a TransformGroup above a visual object in the content branch
graph. What is the effect?
6. Extend the picking behavior in the MousePickApp by providing a callback. You can start by simply
writing a text string (e.g., "picking") to the console. You can also get more ambitious and read the
user data from the target transform group or report the translation and/or rotations of the target
transform group. With the proper capabilities, you can also access the children of the TransformGroup
object.
Tutorial version 1.5 (Java 3D API v 1.1.2)
Getting Started with
the Java 3D
API
Chapter 5
Animation
Dennis J Bouvier
K Computing
Module2: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial
1999 Sun Microsystems, Inc.
2550 Garcia Avenue, Mountain View, California 94043-1100 U.S.A
All Rights Reserved.
The information contained in this document is subject to change without notice.
SUN MICROSYSTEMS PROVIDES THIS MATERIAL "AS IS" AND MAKES NO WARRANTY OF ANY KIND,
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS SHALL NOT BE
LIABLE FOR ERRORS CONTAINED HEREIN OR FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES
(INCLUDING LOST PROFITS IN CONNECTION WITH THE FURNISHING, PERFORMANCE OR USE OF
THIS MATERIAL, WHETHER BASED ON WARRANTY, CONTRACT, OR OTHER LEGAL THEORY).
THIS DOCUMENT COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE
PERIODICALLY MADE TO THE INFORMATION HEREIN; THESE CHANGES WILL BE INCORPORATED IN NEW
EDITIONS OF THE PUBLICATION. SUN MICROSYSTEMS, INC. MAY MAKE IMPROVEMENTS AND/OR CHANGES
IN THE PRODUCT(S) AND/OR PROGRAM(S) DESCRIBED IN THIS PUBLICATION AT ANY TIME.
Some states do not allow the exclusion of implied warranties or the limitations or exclusion of liability for incidental or
consequential damages, so the above limitations and exclusion may not apply to you. This warranty gives you specific legal
rights, and you also may have other rights which vary from state to state.
Permission to use, copy, modify, and distribute this documentation for NON-COMMERCIAL purposes and without fee is
hereby granted provided that this copyright notice appears in all copies.
This documentation was prepared for Sun Microsystems by K Computing (530 Showers Drive, Suite 7-225, Mountain View,
CA 94040, 770-982-7881, www.kcomputing.com). For further information about course development or course delivery,
please contact either Sun Microsystems or K Computing.
Java, JavaScript, Java 3D, HotJava, Sun, Sun Microsystems, and the Sun logo are trademarks or registered trademarks of Sun
Microsystems, Inc. All other product names mentioned herein are the trademarks of their respective owners.
Module 2: Interaction and Animation
The Java 3D Tutorial 5-i Last saved on 10/16/99 2:49 AM
Table of Contents
Chapter 5
Animation.............................................................................................................................................5-1
5.1 Animations................................................................................................................................5-1
5.2 Interpolators and Alpha Object Provide Time-based Animations.................................................5-2
5.2.1 Alpha.................................................................................................................................5-2
5.2.2 Using Interpolator and Alpha Objects.................................................................................5-4
5.2.3 Example Using Alpha and RotationInterpolator ..................................................................5-4
5.2.4 Alpha API .........................................................................................................................5-8
5.2.5 Interpolator Behavior Classes...........................................................................................5-10
5.2.6 Core Interpolator API ......................................................................................................5-12
5.2.7 Path Interpolator Classes..................................................................................................5-20
5.3 Billboard Class........................................................................................................................5-24
5.3.1 Using a Billboard Object ..................................................................................................5-24
5.3.2 Example Billboard Program.............................................................................................5-25
5.3.3 Billboard API ..................................................................................................................5-26
5.4 Level of Detail (LOD) Animations ...........................................................................................5-28
5.4.1 Using a DistanceLOD Object ...........................................................................................5-29
5.4.2 Example Usage of DistanceLOD......................................................................................5-29
5.4.3 DistanceLOD API............................................................................................................5-31
5.4.4 LOD (Level of Detail) API...............................................................................................5-32
5.5 Morph.....................................................................................................................................5-33
5.5.1 Using a Morph Object......................................................................................................5-34
5.5.2 Example Morph Application: Walking..............................................................................5-34
5.5.3 Morph API ......................................................................................................................5-37
5.6 Chapter Summary....................................................................................................................5-38
5.7 Self Test..................................................................................................................................5-38
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-ii
List of Figures
Figure 5-1 Some Classes used in Java 3D Animations............................................................................5-2
Figure 5-2 Phases of the Alpha Waveform.............................................................................................5-3
Figure 5-3 Some Basic Waveforms Easily Made with an Alpha Object. .................................................5-4
Figure 5-4 Recipe for Using an Interpolator and Alpha Objects for Animation........................................5-4
Figure 5-5 Scene Rendered at 4:30 by the ClockApp Example Program. ................................................5-6
Figure 5-6 Smoothing of the Waveform Produced by Alpha...................................................................5-7
Figure 5-7 Four Scenes Rendered by AlphaApp Showing the Effect of IncreasingAlphaRampDuration. .5-7
Figure 5-8 Java 3D Core and Utility (shaded boxes) Interpolator Classes Hierarchy. ............................5-10
Figure 5-9 Two Scenes from InterpolatorApp Showing Various Interpolators.......................................5-11
Figure 5-10 Partial Scene Graph Diagram of a ColorInterpolator Object and its Target Material
NodeComponent Object...............................................................................................................5-13
Figure 5-11The Relationship Between Knots and Alpha Value for a 2D Position Example. ..................5-20
Figure 5-12 Recipe for Using a Path Interpolator Object ......................................................................5-21
Figure 5-13A Scene Rendered by RotPosPathApp Showing the Interpolation of the Rotation and Position
of the Color Cube. The Red Dots Show the Knots Positions of the Example Application..............5-22
Figure 5-14 Recipe for Using a Billboard Object to Provide Animation. ...............................................5-24
Figure 5-15 Diagram of Scene Graph Using a Billboard Object as Created in Code Fragment 5-3. .......5-26
Figure 5-16 Image of BillboardApp with all 2D 'Trees' Facing the Viewer............................................5-26
Figure 5-17 Recipe for Using a DistanceLOD Object to Provide Animation. ........................................5-29
Figure 5-18 Partial Scene Graph Diagram for DistanceLODApp Example Program. ............................5-30
Figure 5-19 Two Scenes Rendered from DistanceLODApp..................................................................5-31
Figure 5-20 Recipe for Using a Morph Object. ....................................................................................5-34
Figure 5-21 Key Frame Images from MorphApp with the Trace of One Vertex. ...................................5-36
Figure 5-22 A Scene Rendered from Morph3App Showing the Animations of Three Alternative Behavior
Classes (not all are good).............................................................................................................5-37
List of Code Fragments
Code Fragment 5-1 Using a RotationInterpolator and Alpha to Spin a Clock (from ClockApp)...............5-5
Code Fragment 5-2 An Excerpt from the CreateSceneGraph Method of RotPosPathApp.java...............5-21
Code Fragment 5-3 Except From the createSceneGraph Method of BillboardApp.java. ........................5-26
Code Fragment 5-4 Excerpt from createSceneGraph Method in DistanceLODApp. ..............................5-30
Code Fragment 5-5 MorphBehavior Class from MorphApp. ................................................................5-35
Code Fragment 5-6 An Excerpt from the createSceneGraph Method of MorphApp. .............................5-36
List of Tables
Table 5-1 Summary of Core Interpolator Classes.................................................................................5-11
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-iii
List of Reference Blocks
Alpha Constructor Summary.................................................................................................................5-8
Alpha Method Summary (partial list) ....................................................................................................5-9
Interpolator Method Summary (partial list)..........................................................................................5-12
ColorInterpolator Constructor Summary..............................................................................................5-13
ColorInterpolator Method Summary (partial list) .................................................................................5-14
PositionInterpolator Constructor Summary..........................................................................................5-14
PositionInterpolator Method Summary (partial list)..............................................................................5-15
RotationInterpolator Constructor Summary .........................................................................................5-15
RotationInterpolator Method Summary (partial list).............................................................................5-16
ScaleInterpolator Constructor Summary..............................................................................................5-16
ScaleInterpolator Method Summary.....................................................................................................5-17
SwitchValueInterpolator Constructor Summary...................................................................................5-17
SwitchValueInterpolator Method Summary (partial list) ......................................................................5-18
Switch Constructor Summary..............................................................................................................5-18
Switch Method Summary (partial list) .................................................................................................5-19
Switch Capability Summary................................................................................................................5-19
TransparencyInterpolator Constructor Summary..................................................................................5-19
TransparencyInterpolator Method Summary........................................................................................5-20
PathInterpolator ..................................................................................................................................5-23
PathInterpolator Method Summary (partial list) ...................................................................................5-23
RotPosPathInterpolator Constructor Summary ....................................................................................5-23
RotPosPathInterpolator Method Summary...........................................................................................5-24
Billboard Constructor Summary..........................................................................................................5-27
Billboard Method Summary (partial list) .............................................................................................5-28
DistanceLOD Constructor Summary...................................................................................................5-32
DistanceLOD Method Summary..........................................................................................................5-32
LOD Constructor Summary ................................................................................................................5-32
LOD Method Summary.......................................................................................................................5-33
Morph Constructor Summary..............................................................................................................5-37
Morph Method Summary (partial list) .................................................................................................5-38
Morph Capabilities Summary..............................................................................................................5-38
Preface to Chapter 5
This document is one part of a tutorial on using the Java 3D API. You should be familiar with Java 3D
API basics to fully appreciate the material presented in this Chapter. Additional chapters and the full
preface to this material are presented in the Module 0 document available at:
http://java.sun.com/products/javamedia/3d/collateral
Cover Image
The cover image represents the key frame animation possible using a Morph object and the appropriate
behavior. Section 5.5 presents an example program utilizing a Morph object, an Alpha object, and a
Behavior object to animate a stick man.
Module 2: Interaction and Animation
The Java 3D Tutorial 5-1
5
Animation
Chapter Objectives
After reading this chapter, youll be able to:
use Alpha and Interpolator classes to add simple animations
use LOD and Billboard to provide computation saving animations
use Morph objects with custom behaviors to provide key frame animations
Certain visual objects change independent of user actions. For example, a clock in the virtual world
should keep on ticking without user interaction. The clock is an example of animation. For the purposes of
this tutorial, animation is defined as changes in the virtual universe that occur without direct user action
1
.
By contrast, changes in the virtual universe as a direct result of user actions are defined as interactions.
Chapter 4 presents interaction classes and programs. This chapter is about animations.
5.1 Animations
As with interaction, animations in Java 3D are implemented using Behavior objects
2
. As you might imagine,
any custom animation can be created using behavior objects. However, the Java 3D API provides a number
of classes useful in creating animations without having to create a new class. It should come as no surprise
that these classes are based on the Behavior class.
One set of animation classes are known as interpolators. An Interpolator object, together with an Alpha
object, manipulates some parameter of a scene graph object to create a time-based animation. The Alpha
object provides the timing. Interpolators and Alpha objects are explained in Section 5.2.
1
The distinction between animation and interaction made in this tutorial is fairly fine (direct is the key word here).
Chapter 4 provides an example to help clarify this distinction (see "Animation versus Interaction" on page 4-3).
2
Chapter 4 presents the Behavior class in detail and the application of Behaviors, in general. The material
presented in Section 4.2 is a prerequisite for this chapter.
CHAPTER
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-2
Another set of animation classes animates visual objects in response to view changes. This set of classes
includes the billboard and Level of Detail (LOD) behaviors which are driven not by the passage of time, but
on the position or orientation of the view. Classes for both of these behaviors are provided in the Java 3D
core and presented in Sections 5.3 and 5.4, respectively. Figure 5-1 shows the high level class hierarchy for
animation classes.
Behavior
Billboard
Interpolator
LOD
DistanceLOD
ColorInterpolator
RotPosPathScaleInterpolator
Figure 5-1 Some Classes used in Java 3D Animations
Section 5.5 presents the Morph class. The Morph class is used in both animation or interpolator
applications.
5.2 Interpolators and Alpha Object Provide Time-based Animations
3
An Alpha object produces a value between zero and one, inclusive, depending on the time and the
parameters of the Alpha object. Interpolators are customized behavior objects that use an Alpha object to
provide animations of visual objects. Interpolator actions include changing the location, orientation, size,
color, or transparency of a visual object. All interpolator behaviors could be implemented by creating a
custom behavior class; however, using an interpolator makes creating these animations much easier.
Interpolator classes exist for other actions, including some combinations of these actions. The
RotationInterpolator class is used in an example program in Section 5.2.3.
5.2.1 Alpha
An alpha object produces a value, called the alpha value, between 0.0 and 1.0, inclusive. The alpha value
changes over time as specified by the parameters of the alpha object. For specific parameter values at any
particular time, there is only one alpha value the alpha object will produce. Plotting the alpha value over
time shows the waveform that the alpha object produces.
The alpha object waveform has four phases: increasing alpha, alpha at one, decreasing alpha, and alpha at
zero. The collection of all four phases is one cycle of the alpha waveform. These four phases correspond
with four parameters of the Alpha object. The duration of the four phases is specified by an integer value
expressing the duration in milliseconds of time. Figure 5-2 shows the four phases of the alpha waveform.
All alpha timings are relative to the start time for the Alpha object. The start time for all Alpha object is
taken from the system start time. Consequently, Alpha objects created at different times will have the same
3
Section 1.9 introduced the RotationInterpolator and Alpha classes. You may want to read that section
first. Also, the Java 3D API Specification covers Alpha in detail.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-3
start time. As a result, all interpolator objects, even those based on different Alpha objects, are
synchronized.
Alpha objects can have their waveforms begin at different times. The beginning of an alpha object's first
waveform cycle may be delayed by either or both of two other parameters: TriggerTime and
PhaseDelayDuration. The TriggerTime parameter specifies a time after the StartTime to begin operation of
the Alpha object. For a time specified by the PhaseDelayDuration parameter after the TriggerTime, the first
cycle of the waveform begins
4
. Figure 5-2 shows the StartTime, TriggerTime and PhaseDelayDuration.
An alpha waveform may cycle once, repeat a specific number of times, or cycle continuously. The number
of cycles is specified by the loopCount parameter. When the loopCount is positive, it specifies the number
of cycles. A loopCount of 1 specifies continuous looping. When the alpha waveform cycles more than
once, only the four cycles repeat. The phase delay is not repeated.
4 Phases of Alpha Waveform
1. increasingAlphaDuration
2. alphaAtOneDuration
3. decreasingAlphaDuration
4. alphaAtZeroDuration
duration of one cycle duration of second cycle
a
l
p
h
a
v
a
l
u
e 1.0
0.0
program start time
trigger time
phase delay
time
Figure 5-2 Phases of the Alpha Waveform.
An alpha waveform does not always use all four phases. An alpha waveform can be formed from one, two,
three, or four phases of the Alpha waveform. Figure 5-3 shows waveforms created using one, two, or three
phases of the Alpha waveform. Six of the 15 possible phase combinations are shown in the figure.
4
Either startTime or phaseDelayDuration can be used for the same purpose. It is a rare application that requires the
use of both parameters.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-4
basic waveforms of
INCREASING_ENABLE
mode
basic waveforms of
DECREASING_ENABLE
mode
some other
waveforms
Figure 5-3 Some Basic Waveforms Easily Made with an Alpha Object.
The alpha object has two modes which specify a subset of phases are used. The INCREASING_ENABLE
mode indicates the increasing alpha and alpha at one phases are used. The DECREASING_ENABLE mode
indicates the decreasing alpha and alpha at zero phases are used. A third mode is the combination of these
two modes indicating that all four phases are used.
The mode specification overrides the duration parameter settings. For example, when the mode is
INCREASING_ENABLE, the DecreasingAlphaDuration, DecreasingAlphaRampDuration
5
, and
AlphaAtZeroDuration parameters are ignored. While any waveform may be specified by setting the
duration of unwanted phases to zero, the proper specification of the mode increases the efficiency of the
Alpha object.
5.2.2 Using Interpolator and Alpha Objects
The recipe for using Interpolator and Alpha objects is very similar to using any behavior object. The major
difference from the behavior usage recipe (given in Section 4.2.2) is to include the Alpha object. Figure 5-4
gives the basic interpolator and alpha object usage recipe
6
.
1. create the target object with the appropriate capability
2. create the Alpha object
3. create the Interpolator object referencing the Alpha object and target object
4. add scheduling bounds to the Interpolator object
5. add Interpolator object to the scene graph
Figure 5-4 Recipe for Using an Interpolator and Alpha Objects for Animation.
5.2.3 Example Using Alpha and RotationInterpolator
ClockApp.java is an example use of the RotationInterpolator class. The scene is of a clock face. The
clock is rotated by a RotationInterpolator and Alpha objects once per minute. The complete code for this
example is included in the examples/Animation subdirectory of the examples jar
7
.
5
The ramp parameters are discussed in the 'Smoothing of the Alpha Waveform' Section on page 5-6
6
This is the same recipe as given in Section 1.9.4.
7
The examples jar contains all of the source code for the examples in The Java 3D Tutorial; available for download
from The Java 3D website.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-5
In this application, the target object is a TransformGroup object. The ALLOW_TRANSFORM_WRITE
capability is required for the TransformGroup target object. Some other interpolators act upon different
target objects. For example, the target of a ColorInterpolator object is a Material object. An interpolator
object sets the value of its target object based on the alpha value and values that the interpolator object
holds.
The interpolator defines the end points of the animation. In the case of the RotationInterpolator, the object
specifies the start and end angles of rotation. The alpha controls the animation with respect to the timing
and how the interpolator will move from one defined point to the other by the specification of the phases of
the alpha waveform.
This application uses the default RotationInterpolator settings of a start angle of zero and an end angle of
2 (one complete rotation). The default axis of rotation is the y-axis. The alpha object is set to
continuously rotate (loopCount = -1) with a period of one minute (60,000 milliseconds). The combination
of these two objects will cause the visual object to rotate one full rotation every minute. The cycle
continuously and immediately repeats. The result looks like the clock is continuously spinning, not that the
clock spins once and starts over.
Code Fragment 5-1 shows the createSceneGraph method from ClockApp.java. This code
fragment is annotated with the steps from the recipe of Figure 5-4.
1. public BranchGroup createSceneGraph() {
2. // Create the root of the branch graph
3. BranchGroup objRoot = new BranchGroup();
4.
5. // create target TransformGroup with Capabilities
6. TransformGroup objSpin = new TransformGroup();
7. objSpin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
8.
9. // create Alpha that continuously rotates with a period of 1 minute
10. Alpha alpha = new Alpha (-1, 60000);
11.
12. // create interpolator object; by default: full rotation about y-axis
13. RotationInterpolator rotInt = new RotationInterpolator(alpha, objSpin);
14. rotInt.setSchedulingBounds(new BoundingSphere());
15.
16. //assemble scene graph
17. objRoot.addChild(objSpin);
18. objSpin.addChild(new Clock());
19. objRoot.addChild(rotInt);
20.
21. // Let Java 3D perform optimizations on this scene graph.
22. objRoot.compile();
23.
24. return objRoot;
25. } // end of CreateSceneGraph method of ClockApp
Code Fragment 5-1 Using a RotationInterpolator and Alpha to Spin a Clock (from ClockApp).
Figure 5-5 is of a scene rendered by ClockApp at 4:30. The clock face is oblique to the viewer since the
entire clock face is rotating.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-6
Figure 5-5 Scene Rendered at 4:30 by the ClockApp Example Program.
The ClockApp program shows a simple application of the RotationInterpolator. The Clock object, defined
in Clock.java available in the examples/Animation subdirectory, shows a more advanced
application of the RotationInterpolator object. The clock object in the program uses one
RotationInterpolator object to animate each hand of the clock
8
. However, only one alpha object is used in
the clock. It is not necessary to use one Alpha object to coordinate the hands; as noted above, all Alpha
objects are synchronized on the program start time. However, sharing one Alpha object saves system
memory.
Some of the potentially interesting features of the Clock Class are:
the setting of the start and end angles for the hands,
the setting of the axes of rotation, and
the setting of the polygonal culling for the various components of the clock.
The source code for the clock is in Clock.java, also available in the examples/Animation
subdirectory. The study of the Clock class is left to the reader.
Smoothing of the Alpha Waveform
In addition to the duration of the four phases, the programmer can specify a ramp duration for the increasing
alpha and decreasing alpha phases. During the ramp duration, the alpha value changes gradually. In the
case of motion interpolators, it will appear as though the visual object is accelerating and decelerating in a
more natural, real world, manner.
The ramp duration value is used for both the beginning and ending portions of the phase and therefore the
ramp duration is limited to half of the duration of the phase. Figure 5-6 shows an Alpha waveform with
both IncreasingAlphaRampDuration and a DecreasingAlphaRampDuration. Note that the alpha value
changes linearly between the two ramp periods.
8
Since the clock has front and back facing hands, there are four hands and four RotationInterpolator objects.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-7
IncreasingAlphaRampDuration DecreasingAlphaRampDuration
IncreasingAlphaDuration DecreasingAlphaDuration
Figure 5-6 Smoothing of the Waveform Produced by Alpha
9
An example program, AlphaApp.java, demonstrates the effect of an IncreasingAlphaRampDuration on
an Alpha waveform. In this program there are three car visual objects. The three cars start at the same time
from the same x coordinate and travel parallel. The upper car has no ramp (ramp duration = 0), the bottom
car has maximum ramp duration (half of the duration of the increasing or decreasing alpha duration), and
the middle car has half the maximum ramp duration (one quarter of the duration of the increasing or
decreasing alpha duration). Each car takes two seconds to cross the view. In Figure 5-7 shows four scenes
rendered from this application.
ramp
duration
time ~ 0.4s time ~ 0.8s time ~ 1.2s time ~ 1.6s
none
full
Figure 5-7 Four Scenes Rendered by AlphaApp Showing the Effect of IncreasingAlphaRampDuration.
At about 0.4 seconds after the cars start, the first (left) image of Figure 5-7 was captured showing the
positions of the cars. The top car, which will proceed at a constant rate in the absence of a ramp, has
traveled the most distance in the first frame. The other two cars begin more slowly and accelerate. At one
second (not shown), all the cars have traveled the same distance. The relative positions reverse during the
second half of the phase. At the end of the two second phase, each of the cars have traveled the same
distance.
The source for AlphaApp is available in the examples/Animation subdirectory.
9
Justin Couch provided the inspiration and most of the artwork for this figure.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-8
5.2.4 Alpha API
The API of the Alpha class is straightforward. Four constructors cover the most common alpha
applications. A plethora of methods, listed in the next reference block, make easy work of customizing an
Alpha object to fit any application.
Alpha Constructor Summary
extends: Object
The alpha class converts a time value into an alpha value (a value in the range 0 to 1, inclusive). The Alpha object
is effectively a function of time that generates values in the range [0,1]. A common use of the Alpha provides alpha
values for Interpolator behaviors. The characteristics of the Alpha object are determined by user-definable
parameters. Refer to Figure 5-2, Figure 5-6, and the text accompanying these figures for more information.
Alpha()
Constructs an Alpha object with mode = INCREASING_ENABLE, loopCount = -1, increasingAlphaDuration =
1000, all other parameters = 0, except StartTime. StartTime is set as the start time of the program.
Alpha(int loopCount, long increasingAlphaDuration)
This constructor takes only the loopCount and increasingAlphaDuration as parameters, sets the mode to
INCREASING_ENABLE and assigns 0 to all of the other parameters (except StartTime).
Alpha(int loopCount, long triggerTime, long phaseDelayDuration,
long increasingAlphaDuration, long increasingAlphaRampDuration,
long alphaAtOneDuration)
Constructs a new Alpha object and sets the mode to INCREASING_ENABLE.
Alpha(int loopCount, int mode, long triggerTime, long phaseDelayDuration,
long increasingAlphaDuration, long increasingAlphaRampDuration,
long alphaAtOneDuration, long decreasingAlphaDuration,
long decreasingAlphaRampDuration, long alphaAtZeroDuration)
This constructor takes all of the Alpha user-definable parameters.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-9
Alpha Method Summary (partial list)
Refer to Figure 5-2, Figure 5-6, and the text accompanying these figures for more information. Each of the set-
methods has a matching parameterless get-method which returns the a value of the type that corresponds to the
parameter of the set-method.
boolean finished()
Query to test if this alpha object has finished all its activity.
void setAlphaAtOneDuration(long alphaAtOneDuration)
Set this alpha's alphaAtOneDuration to the specified value.
void setAlphaAtZeroDuration(long alphaAtZeroDuration)
Set this alpha's alphaAtZeroDuration to the specified value.
void setDecreasingAlphaDuration(long decreasingAlphaDuration)
Set this alpha's decreasingAlphaDuration to the specified value.
void setDecreasingAlphaRampDuration(long decreasingAlphaRampDuration)
Set this alpha's decreasingAlphaRampDuration to the specified value.
void setIncreasingAlphaDuration(long increasingAlphaDuration)
Set this alpha's increasingAlphaDuration to the specified value.
void setIncreasingAlphaRampDuration(long increasingAlphaRampDuration)
Set this alpha's increasingAlphaRampDuration to the specified value.
void setLoopCount(int loopCount)
Set this alpha's loopCount to the specified value.
void setMode(int mode)
Set this alpha's mode to that specified in the argument. This can be set to INCREASING_ENABLE,
DECREASING_ENABLE, or the OR-ed value of the two.
DECREASING_ENABLE - Specifies that phases 3 and 4 are used
INCREASING_ENABLE - Specifies that phases 1 and 2 are used.
void setPhaseDelayDuration(long phaseDelayDuration)
Set this alpha's phaseDelayDuration to that specified in the argument.
void setStartTime(long startTime)
Sets this alpha's startTime to that specified in the argument; startTime sets the base (or zero) for all relative time
computations; the default value for startTime is the system start time.
void setTriggerTime(long triggerTime)
Set this alpha's triggerTime to that specified in the argument.
float value()
This function returns a value between 0.0 and 1.0 inclusive, based on the current time and the time-to-alpha
parameters established for this alpha.
float value(long atTime)
This function returns a value between 0.0 and 1.0 inclusive, based on the specified time and the time-to-alpha
parameters established for this alpha.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-10
5.2.5 Interpolator Behavior Classes
Figure 5-8 shows the Interpolator classes in the core and utility packages. In this figure, you can see there
are over 10 interpolator classes, and that they are all subclasses of the Interpolator class. Also, the
Interpolator class is an extension of Behavior. The two shaded boxes represent utility interpolator classes,
the other boxes represent core interpolator classes.
java.lang.Object
SceneGraphObject
Node
Leaf
Behavior
Interpolator
ColorInterpolator
PathInterpolator
PositionInterpolator
ScaleInterpolator
RotationInterpolator
SwitchValueInterpolator
TransparencyInterpolator
PositionPathInterpolator
RotationPathInterpolator
RotPosScalePathInterpolator
RotPosPathInterpolator
TCBSplinePathInterpolator RotPosScaleSplinePathInterpolator
Figure 5-8 Java 3D Core and Utility (shaded boxes) Interpolator Classes Hierarchy.
Each interpolator is a custom behavior with a trigger to wake each frame. In the processStimulus method,
an interpolator object checks its associated alpha object for the current alpha value, adjusts the target based
on the alpha value, then resets its trigger to wake next frame (unless the alpha is finished). Some of this
functionality is provided in the Interpolator class. Most of this behavior is implemented in each individual
interpolator class.
Most interpolator objects store two values that are used as the end points for the interpolated action. For
example, the RotationInterpolator stores two angles that are the extremes of the rotation provided by this
interpolator. For each frame, the interpolator object checks the alpha value of its Alpha object and makes
the appropriate rotational adjustment to its target TransformGroup object. If the alpha value is 0, then one
of the values is used; if the alpha value is 1, the other value is used. For alpha values between 0 and 1, the
interpolator linearly interpolates between the two values based on the alpha value and uses the resulting
value for the target object adjustment.
This general interpolator description does not describe the SwitchValueInterpolator nor PathInterpolator
classes well. The SwitchValueInterpolator chooses one among the children of the Switch group target node
based on the alpha value; therefore, no interpolation is done in this class.
The PathInterpolator class, and its subclasses, are described in Section 5.2.7 on page 5-20.
While the various interpolator classes are similar, they also differ in some details. In summarizing the seven
core subclasses of the Interpolator class, Table 5-1 shows some of the differences among interpolator
classes.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-11
Table 5-1 Summary of Core Interpolator Classes
Interpolator class used to target object type page
ColorInterpolator
change the diffuse color of an
object(s)
Material 5-12
PathInterpolator
10
abstract class TransformGroup 5-20
PositionInterpolator
change the position of an
object(s)
TransformGroup 5-14
RotationInterpolator
change the rotation
(orientation) of an object(s)
TransformGroup 5-15
ScaleInterpolator
change the size of an object(s) TransformGroup 5-16
SwitchValueInterpolator
choose one of (switch) among
a collection of objects
Switch 5-17
TransparencyInterpolator
change the transparency of an
object(s)
TransparencyAttributes 5-19
An example program, InterpolatorApp.java, demonstrates six non-abstract interpolator classes of
Table 5-1. In this program, each interpolator object is driven by a single Alpha object. Figure 5-9 shows
two scenes rendered by InterpolatorApp. Changes in position, rotation, scale, color, transparency, and
visual object (top to bottom) are made by PositionInterpolator, RotationInterpolator, ScaleInterpolator,
ColorInterpolator, TransparencyInterpolator, and SwitchValueInterpolator objects, respectively. The
complete source code for InterpolatorApp is available in the examples/Animation subdirectory of the
examples distribution.
Position
Rotation
Scale
Color
Transparency
SwitchValue
Figure 5-9 Two Scenes from InterpolatorApp Showing Various Interpolators.
10
The PathInterpolator class is an abstract class and does not have a target object, but each of the known extensions
of this interpolator have a TransformGroup target object. See Section 5.2.7 for more information.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-12
Interpolator Programming Pitfalls
Interpolator objects are derived from, and closely related to, behavior objects. Consequently, using
interpolator objects give rise to the same programming pitfalls as using behavior objects (see Programming
Pitfalls of Using Behavior Objects on page 4-9). In addition to these, there are general Interpolator
programming pitfalls, and specific pitfalls for some interpolator classes. Two general pitfalls are listed here
while the interpolator class specific ones are listed with the appropriate class' reference blocks in the next
section.
One potential interpolator programming pitfall is not realizing that interpolator objects clobber the value of
its target objects. You might think that the TransformGroup target of a RotationInterpolator can be used to
translate the visual object in addition to the rotation provided by the interpolator. This is not true. The
transform set in the target TransformGroup object is re-written on each frame the Alpha object is active.
This also means that two interpolators can not have the same target object
11
.
Another general interpolator pitfall is not setting the appropriate capability for the target object. Failing to
do so will result in a runtime error.
5.2.6 Core Interpolator API
As an abstract class, Interpolator is only used when creating a new subclass. The Interpolator class
provides only one method for users of Interpolator subclasses. Methods useful in writing subclasses are not
listed here. The majority of the information needed for writing a subclass of interpolator can be gleaned
from Chapter 4.
Interpolator Method Summary (partial list)
extends: Behavior
known subclasses: ColorInterpolator, PathInterpolator, PositionInterpolator,
RotationInterpolator, ScaleInterpolator, SwitchValueInterpolator,
TCBSplinePathInterpolator, TransparencyInterpolator
The Interpolation behavior is an abstract class that provides the building blocks used by its various interpolation
specializations.
void setAlpha(Alpha alpha)
Set this interpolator's alpha to the alpha object specified.
ColorInterpolator
A ColorInterpolator object has a Material object as its target. This interpolator changes the diffuse color
component of the target material. This makes the ColorInterpolator both powerful and limited. The power
comes from the ability of having more than one visual object share the same Material object. So, one
ColorInterpolator with one Material target can affect more than one visual object. The limitation is that
visual objects with a Material NodeComponent are only visible when lit.
The majority of the potential programming pitfalls are the result of the complexity of shaded (lit) scenes.
Lighting is sufficiently complex that it is the subject of an entire chapter, Chapter 6. For example, the color
of a shaded visual object is the combination of specular, diffuse, and ambient components. The
ColorInterpolator only changes one of three components, the diffuse color, so in certain situations it is
11
There is nothing preventing this, but only one of the interpolator objects will affect the target with the effect of the
others being overwritten.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-13
entirely possible for it to appear that the ColorInterpolator had no affect on the visual object (see Self Test
question 2). Rather than get into a detailed analysis of this and other potential lighting problems here, the
reader is referred to Chapter 6, specifically Sections 6.1 and 6.4.
Another less exotic potential programming pitfall is failing to add the target Material object to the Shape3D
object. Figure 5-10 shows a partial scene graph diagram of a ColorInterpolator and its target Material
NodeComponent.
BG
I
Geometry
S
Appearance
BoundingSphere
Material
Figure 5-10 Partial Scene Graph Diagram of a ColorInterpolator Object and its Target Material
NodeComponent Object.
The ColorInterpolator is different from other interpolators in the format of its get-methods. The get-methods
of ColorInterpolator are not paramterless as they are with the other interpolators. Consequently, the get-
methods of this class are listed with the set-methods.
ColorInterpolator Constructor Summary
extends: Interpolator
This class defines a behavior that modifies the diffuse color of its target material object by linearly interpolating
between a pair of specified colors (using the value generated by the specified Alpha object).
ColorInterpolator(Alpha alpha, Material target)
Constructs a trivial color interpolator with a specified target, a starting color of black, an ending color of white.
ColorInterpolator(Alpha alpha, Material target, Color3f startColor,
Color3f endColor)
Constructs a color interpolator with the specified target, starting color, and ending color.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-14
ColorInterpolator Method Summary (partial list)
The get-methods do not follow the convention of other interpolators. They are listed here.
void setEndColor(Color3f color)
Sets the endColor for this interpolator.
matching get-method: void getEndColor(Color3f color)
void setStartColor(Color3f color)
Sets the startColor for this interpolator.
matching get-method: void getStartColor(Color3f color)
void setTarget(Material target)
Sets the target material component object for this interpolator.
matching get-method: Material getTarget()
PositionInterpolator
The PositionInterpolator varies the position of a visual object(s) along an axis. The specification of the end
points of interpolation is made with two floating point values and an axis of translation. The default axis of
translation is the x-axis.
PositionInterpolator Constructor Summary
extends: Interpolator
This class defines a behavior that modifies the translational component of its target TransformGroup by linearly
interpolating between a pair of specified positions (using the value generated by the specified Alpha object). The
interpolated position is used to generate a translation transform along the local X-axis (or the specified axis of
translation) of this interpolator.
PositionInterpolator(Alpha alpha, TransformGroup target)
Constructs a trivial position interpolator with a specified target, with the default axis of translation (X), a
startPosition of 0.0f, and an endPosition of 1.0f.
PositionInterpolator(Alpha alpha, TransformGroup target,
Transform3D axisOfTranslation, float startPosition, float endPosition)
Constructs a new position interpolator that varies the target TransformGroup's translational component
(startPosition and endPosition) along the specified axis of translation.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-15
PositionInterpolator Method Summary (partial list)
Each of the set-methods has a matching parameterless get-method which returns a value of the type corresponding
to the parameter of the set-method.
void setAxisOfTranslation(Transform3D axisOfTranslation)
Sets the axis of translation for this interpolator.
void setEndPosition(float position)
Sets the endPosition for this interpolator.
void setStartPosition(float position)
Sets the startPosition for this interpolator.
void setTarget(TransformGroup target)
Sets the target for this interpolator.
RotationInterpolator
The RotationInterpolator varies the rotational orientation of a visual object(s) about an axis. The
specification of the end points of interpolation is made with two floating point angle values and an axis of
rotation. The default axis of rotation is the positive y-axis.
RotationInterpolator Constructor Summary
extends: Interpolator
This class defines a behavior that modifies the rotational component of its target TransformGroup by linearly
interpolating between a pair of specified angles (using the value generated by the specified Alpha object). The
interpolated angle is used to generate a rotation transform about the local Y-axis of this interpolator, or the specified
axis of rotation.
RotationInterpolator(Alpha alpha, TransformGroup target)
Constructs a trivial rotation interpolator with a specified target, the default axis of rotation is used (+Y), a minimum
angle of 0.0f, and a maximum angle of 2*pi radians.
RotationInterpolator(Alpha alpha, TransformGroup target,
Transform3D axisOfRotation, float minimumAngle, float maximumAngle)
Constructs a new rotation interpolator that varies the target transform node's rotational component.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-16
RotationInterpolator Method Summary (partial list)
Each of the set-methods has a matching parameterless get-method which returns a value of the type corresponding
to the parameter of the set-method.
void setAxisOfRotation(Transform3D axisOfRotation)
Sets the axis of rotation for this interpolator, in radians.
void setMaximumAngle(float angle)
Sets the maximumAngle for this interpolator, in radians.
void setMinimumAngle(float angle)
Sets the minimumAngle for this interpolator, in radians.
void setTarget(TransformGroup target)
Sets the target TransformGroup node for this interpolator.
ScaleInterpolator
The ScaleInterpolator varies the size of a visual object(s). The specification of the end points of
interpolation is made with two floating point values.
ScaleInterpolator Constructor Summary
extends: Interpolator
Scale interpolation behavior. This class defines a behavior that modifies the uniform scale component of its target
TransformGroup by linearly interpolating between a pair of specified scale values (using the value generated by the
specified Alpha object). The interpolated scale value is used to generate a scale transform in the local coordinate
system of this interpolator.
ScaleInterpolator(Alpha alpha, TransformGroup target)
Constructs a trivial scale interpolator that varies its target TransformGroup node between the two specified alpha
values using the specified alpha, an identity matrix, a minimum scale = 0.1f, and a maximum scale = 1.0f.
ScaleInterpolator(Alpha alpha, TransformGroup target, Transform3D axisOfScale,
float minimumScale, float maximumScale)
Constructs a new scaleInterpolator object that varies its target TransformGroup node's scale component between two
scale values (minimumScale and maximumScale).
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-17
ScaleInterpolator Method Summary
Each of the set-methods has a matching parameterless get-method which returns a value of the type corresponding
to the parameter of the set-method.
void setAxisOfScale(Transform3D axisOfScale)
Sets the AxisOfScale transform for this interpolator.
void setMaximumScale(float scale)
Sets the maximumScale for this interpolator.
void setMinimumScale(float scale)
Sets the minimumScale for this interpolator.
void setTarget(TransformGroup target)
Sets the target TransformGroup for this interpolator.
SwitchValueInterpolator
The SwitchValueInterpolator doesnt interpolate between values as other interpolators do. It selects one of
the children of a Switch object for rendering. The threshold values for switching to a different child are
determined by evenly dividing the 0.0 to 1.0 range by the number of children the Switch object has.
Reference blocks for the Switch class have been included in the next section.
One potential programming pitfall specific to the SwitchValueInterpolator lies in the fact that the
interpolator is not updated when the number of children changes in the Switch object. More importantly, the
switching threshold values are determined when the SwitchValueInterpolator object is created. So, if the
switch has no children before the interpolator is created, or if the number of children changes after the
interpolator object is created, then number of children in the interpolator object must be updated. The
advantage is that you can specify a subset of indices to be used by an interpolator. The subset is limited to a
sequential set of indices.
SwitchValueInterpolator Constructor Summary
extends: Interpolator
This class defines a behavior that modifies the selected child of the target switch node by linearly interpolating
between a pair of specified child index values (using the value generated by the specified Alpha object).
SwitchValueInterpolator(Alpha alpha, Switch target)
Constructs a SwitchValueInterpolator behavior that varies its target Switch node's child index between 0 and n-1,
where n is the number of children in the target Switch node.
SwitchValueInterpolator(Alpha alpha, Switch target, int firstChildIndex,
int lastChildIndex)
Constructs a SwitchValueInterpolator behavior that varies its target Switch node's child index between the two
values provided.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-18
SwitchValueInterpolator Method Summary (partial list)
Each of the set-methods has a matching parameterless get-method which returns a value of the type corresponding
to the parameter of the set-method.
void setFirstChildIndex(int firstIndex)
Sets the firstChildIndex for this interpolator.
void setLastChildIndex(int lastIndex)
Sets the lastChildIndex for this interpolator.
void setTarget(Switch target)
Sets the target for this interpolator.
Switch
The switch class is listed here because it is used in the SwitchValueInterpolator (and later in the
DistanceLOD). Switch is derived from Group and is the parent zero or more scene graph sub branches. A
Switch object can select zero, one, or more, including all, of its children to be rendered. Of course a Switch
object can be used without an interpolator or LOD object. The most commonly used method is the
addChild() method derived from the Group Class.
Switch Constructor Summary
extends: Group
The Switch node controls which of its children will be rendered. It defines a child selection value (a switch value)
that can either select a single child, or it can select 0 or more children using a mask to indicate which children are
selected for rendering.
Switch()
Constructs a Switch node with default parameters.
Switch(int whichChild)
Constructs and initializes a Switch node using the specified child selection index.
CHILD_ALL all children are rendered
CHILD_MASK the childMask BitSet is used to select which children are rendered
CHILD_NONE no children are rendered
Switch(int whichChild, java.util.BitSet childMask)
Constructs and initializes a Switch node using the specified child selection index and mask.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-19
Switch Method Summary (partial list)
Each of the set-methods has a matching parameterless get-method which returns a value of the type corresponding
to the parameter of the set-method.
void setChildMask(java.util.BitSet childMask)
Sets the child selection mask.
void setWhichChild(int child)
Sets the child selection index that specifies which child is rendered.
Switch Capability Summary
ALLOW_SWITCH_READ | WRITE
Specifies that this node allows reading its child selection and mask values and its current child.
TransparencyInterpolator
A TransparencyInterpolator object has a TransparencyAttributes NodeComponent as its target. This
interpolator changes the transparency value of the target object. More than one visual object may share one
TransparencyAttributes object. So, one TransparencyInterpolator can affect more than one visual object.
Also, be aware that the various transparency modes may affect the rendering performance and appearance
of the visual object. Refer to the Java 3D API Specification for more information on the
TransparencyAttributes Class.
A potential programming pitfall specific to the TransparencyInterpolator is failing to add the target
TransparencyAttributes object to the appearance bundle of the visual object(s). This is similar to a potential
ColorInterpolator problem. See Figure 5-10 for an illustration of a visual object with an appearance bundle.
TransparencyInterpolator Constructor Summary
extends: Interpolator
This class defines a behavior that modifies the transparency of its target TransparencyAttributes object by linearly
interpolating between a pair of specified transparency values (using the value generated by the specified Alpha
object).
TransparencyInterpolator(Alpha alpha, TransparencyAttributes target)
Constructs a trivial transparency interpolator with a specified target, a minimum transparency of 0.0f and a
maximum transparency of 1.0f.
TransparencyInterpolator(Alpha alpha, TransparencyAttributes target,
float minimumTransparency, float maximumTransparency)
Constructs a new transparency interpolator that varies the target material's transparency between the two
transparency values.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-20
TransparencyInterpolator Method Summary
Each of the set-methods has a matching parameterless get-method which returns a value of the type corresponding
to the parameter of the set-method.
void setMaximumTransparency(float transparency)
Sets the maximumTransparency for this interpolator.
void setMinimumTransparency(float transparency)
Sets the minimumTransparency for this interpolator.
void setTarget(TransparencyAttributes target)
Sets the target TransparencyAttributes object for this interpolator.
5.2.7 Path Interpolator Classes
Path interpolator classes differ from the other interpolators in that they may store two or more values for
interpolation. The Java 3D core provides path interpolator classes for position interpolation, rotation
interpolation, position and rotation interpolation, and position, rotation, and scale interpolation. The target
of a path interpolator object is a TransformGroup object which changes the position, orientation, and scale,
as appropriate, for its child objects.
Path interpolator objects store a set of values, or knots, that are used two at a time for interpolation. The
alpha value determines which two knot values are used. The knot values are in the range of 0.0 to 1.0
inclusive, which corresponds to the range of values of the alpha object. The first knot must have a value of
0.0 and the last knot must have a value of 1.0. The remaining knots must be stored in increasing order in the
path interpolator object.
The knot values correspond with values for the variable parameter(s) (e.g., position or rotation) used in
interpolation. There is one parameter value specified for each knot value. The knot with the largest value
equal or less than the alpha value, and the next knot, are used. The knots are specified in order, so as the
alpha value changes, the knots are used in adjacent pairs.
The left panel of Figure 5-11 shows the knot values for a position path interpolator. For illustrative
purposes, only 2D positions are used. The center panel of the figure maps the position of the visual object
over the alpha values, 0.0 to 1.0. The right panel of the figure shows the knot values used for the various
alpha values of this example. The combination of knot values and alpha parameters determines the
animation.
X,Y position for various alpha
values knot
knot value position(x, y, z)
0 0.0 (0.0, 0.0, 0.0)
1 0.2 (1.0, 2.0, 0.0)
2 0.4 (2.0, 3.0, 0.0)
3 0.5 (1.0, 1.0, 0.0)
4 0.8 (2.0, 0.0, 0.0)
5 1.0 (3.0, 3.0, 0.0)
0.1
1.0
0.8
0.5
0.4
0.2
X
Y
alpha value (a) knots used
0.0 0
0.0 < a < 0.2 0, 1
0.2 1
0.2 < a < 0.4 1, 2
0.4 2
0.4 < a < 0.5 2, 3
0.5 3
0.5 < a < 0.8 3, 4
0.8 4
0.8 < a < 1.0 4, 5
1.0 5
0.6
0.7
0.9
0.3
0.0
Figure 5-11The Relationship Between Knots and Alpha Value for a 2D Position Example.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-21
PathInterpolator Example Application
Using a path interpolator object follows the same recipe as other interpolator objects. The only difference is
in the number of values used to initialize the path interpolator object. Figure 5-12 presents the path
interpolator recipe.
1. create the target object with the appropriate capability
2. create the Alpha object
3. create arrays of knot and other values
4. create the path interpolator object referencing the Alpha object, target object, and arrays of settings
5. add scheduling bounds to the Interpolator object
6. add path interpolator object to the scene graph
Figure 5-12 Recipe for Using a Path Interpolator Object
The RotPosPathApp.java example program uses an RotPosPathInterpolator object to animate a
ColorCube object through a number of position and rotation values. The RotPosPathInterpolator stores sets
of rotations (as an array of Quat4f), positions (as an array of Point3f), and knot values (as an array of
float). The complete source for RotPosPathApp.java is available in the examples/Animation
subdirectory. Code Fragment 5-2 shows an excerpt from the example annotated with the recipe step
numbers.
1. public BranchGroup createSceneGraph() {
2. BranchGroup objRoot = new BranchGroup();
3.
4. TransformGroup target = new TransformGroup();
5. Alpha alpha = new Alpha(-1, 10000);
6. Transform3D axisOfRotPos = new Transform3D();
7. float[] knots = {0.0f, 0.3f, 0.6f ,1.0f};
8. Quat4f[] quats = new Quat4f[4];
9. Point3f[] positions = new Point3f[4];
10.
11. target.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
12.
13. AxisAngle4f axis = new AxisAngle4f(1.0f,0.0f,0.0f,0.0f);
14. axisOfRotPos.set(axis);
15.
16. quats[0] = new Quat4f(0.0f, 1.0f, 1.0f, 0.0f);
17. quats[1] = new Quat4f(1.0f, 0.0f, 0.0f, 0.0f);
18. quats[2] = new Quat4f(0.0f, 1.0f, 0.0f, 0.0f);
19.
20. positions[0]= new Point3f( 0.0f, 0.0f, -1.0f);
21. positions[1]= new Point3f( 1.0f, -1.0f, -2.0f);
22. positions[2]= new Point3f( -1.0f, 1.0f, -3.0f);
23.
24. RotPosPathInterpolator rotPosPath = new RotPosPathInterpolator(
25. alpha, target, axisOfRotPos, knots, quats, positions);
26. rotPosPath.setSchedulingBounds(new BoundingSphere());
27.
28. objRoot.addChild(target);
29. objRoot.addChild(rotPosPath);
30. target.addChild(new ColorCube(0.4));
31.
32. return objRoot;
33. } // end of createSceneGraph method of RotPosPathApp
Code Fragment 5-2 An Excerpt from the CreateSceneGraph Method of RotPosPathApp.java.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-22
Code Fragment 5-2 is based on the createSceneGraph method in RotPosPathApp.java. The
difference is in the number of knots shown in the code fragment and used in the example program.
RotPosPathApp.java defines nine knots while Code Fragment 5-2 only shows three. Figure 5-13
shows an image from RotPosPathApp. In the application, a red point is displayed for each of the nine knot
positions. One position is reused, thus the eight red dots in the figure.
Figure 5-13A Scene Rendered by RotPosPathApp Showing the Interpolation of the Rotation and
Position of the Color Cube. The Red Dots Show the Knots Positions of the Example Application.
When the RotPosPathApp example program is run, ColorCube moves from knot position to knot position
while rotating to achieve the various knot rotations. As with all interpolators, the resulting animation
depends on the combination of interpolator values and the Alpha parameters used.
As mentioned before, there are a variety of subclasses of the PathInterpolator Class. In addition to these
subclasses in the Java 3D core, there are a couple of related classes in the utility package. The
TCBPathSplineInterpolator Class is a class similar to PathInterpolator. It has one subclass in the utility
package. Refer back to Figure 5-8 to see the relationships among the interpolator classes.
In the RotPosPathApp example, the animation does not appear natural mainly due to the combination of
knot positions chosen. The ColorCube moves to each knot position specified and as soon as that position is
reached, the motion suddenly changes to achieve the next position. This does not appear natural as this type
of action does not happen in the real world where all objects have some inertia.
TCBPathSplineInterpolator is a utility class that provides behavior and functionality similar to that of the
PathInterpolator Class, but smooths the path of the visual object into that of a spline based on the knot
position. The spline path mimics the real world motion of objects. On the spline motion path, the visual
object may not pass through all (or any) of the specified knot positions. An example program using this
class, SplineAnim.java, is distributed with the Java 3D API examples and can be found in the
jdk1.2/demo/java3d/SplineAnim subdirectory.
PathInterpolator
PathInterpolator is an abstract class providing the basic interface and functionality of its subclasses.
PathInterpolator objects store the knot values and calculates the index of knot values to be used based on the
current alpha value.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-23
PathInterpolator
extends: Interpolator
Direct Known Subclasses: PositionPathInterpolator, RotationPathInterpolator,
RotPosPathInterpolator, RotPosScalePathInterpolator
This abstract class defines the base class for all Path Interpolators. Subclasses have access to the method to compute
the currentInterpolationValue given the current time and alpha. The method also computes the currentKnotIndex,
which is based on the currentInterpolationValue. The currentInterpolationValue is calculated by linearly
interpolating among a series of predefined knots (using the value generated by the specified Alpha object).
The first knot must have a value of 0.0 and the last knot must have a value of 1.0. An intermediate knot with index
k must have a value strictly greater than any knot with index less than k.
PathInterpolator Method Summary (partial list)
int getArrayLengths()
This method retrieves the length of the knots array.
void setKnot(int index, float knot)
This method sets the knot at the specified index for this interpolator.
RotPosPathInterpolator
A RotPosPathInterpolator object varies the rotation and position of a visual object based on a set of knot
values. The constructor is the most important of the API features of this class. In the constructor all of the
values and related objects are specified. Be aware that each of the arrays must be the same length in this
and all PathInterpolator objects.
RotPosPathInterpolator Constructor Summary
extends PathInterpolator
RotPosPathInterpolator behavior. This class defines a behavior that modifies the rotational and translational
components of its target TransformGroup by linearly interpolating among a series of predefined knot/position and
knot/orientation pairs (using the value generated by the specified Alpha object). The interpolated position and
orientation are used to generate a transform in the local coordinate system of this interpolator.
RotPosPathInterpolator(Alpha alpha, TransformGroup target,
Transform3D axisOfRotPos, float[] knots, Quat4f[] quats,
Point3f[] positions)
Constructs a new interpolator that varies the rotation and translation of the target TransformGroup's transform.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-24
RotPosPathInterpolator Method Summary
void setAxisOfRotPos(Transform3D axisOfRotPos)
Sets the axis of RotPos value for this interpolator.
void setPosition(int index, Point3f position)
Sets the position at the specified index for this interpolator.
void setQuat(int index, Quat4f quat)
Sets the quaternion at the specified index for this interpolator.
void setTarget(TransformGroup target)
Sets the target TransformGroup for this interpolator.
5.3 Billboard Class
The term "billboard" used in computer graphics context refers to the technique of automatically rotating a
planar visual object such that it is always facing the viewer. The original motivation for the billboard
behavior was to enable using a textured plane as a low cost replacement for complex geometry
12
. Billboard
behavior is still commonly used for this application, but is also used for other purposes, such as keeping
textual information visible from any angle in the virtual environment. In Java 3D, the billboard technique is
implemented in a subclass of the Behavior Class, thus the phrase "billboard behavior" used in Java 3D
literature.
The classic example application of the billboard behavior is to represent trees as 2D textures. Of course, if
the textures are statically oriented, as the viewer moves, the 2D nature of the textures is revealed. However,
if the trees reorient themselves such that they are always viewed parallel to their surface normal, they appear
as 3D objects. This is especially true if the trees are in the background of a scene or viewed at a distance.
5.3.1 Using a Billboard Object
The billboard behavior works for trees because trees look basically the same when viewed from the front,
from the back, or from any angle. Since the billboard behavior makes a visual object appear exactly the
same when viewed from any angle, it is appropriate to use billboards and 2D images to represent 3D objects
that are geometrically symmetric about the y-axis such as cylindrical buildings, grain silos, water towers, or
any cylindrical object. Billboard behavior can also be used for non-symmetric objects when viewed from
sufficient distance as to hide the details of the 2D model.
Using a billboard object is similar to using an interpolator except there is no Alpha object to drive the
animation. The animation of the Billboard object is driven by its relative position to the viewer in the virtual
world. Figure 5-14 shows the steps in the Billboard usage recipe.
1. create a target TransformGroup with ALLOW_TRANSFORM_WRITE capability
2. create a Billboard object referencing the target TransformGroup
3. supply a scheduling bounds (or bounding leaf) for the Billboard object
4. assemble the scene graph
Figure 5-14 Recipe for Using a Billboard Object to Provide Animation.
12
"Cost" here refers to rendering cost, or the computational cost of rendering.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-25
Billboard Programming Pitfalls
Even though the usage of a Billboard object is straightforward, there are a couple of potential programming
mistakes. The first thing to realize it that the target TransformGroup is clobbered in each time it is updated.
Consequently, this TransformGroup can not be used to position the visual object. If you attempt to use the
target for placement, the billboard will work, but on the first update of rotation, the position information in
the target will be lost and the visual object will appear at the origin.
Without the ALLOW_TRANSFORM_WRITE capability set for the target, a runtime error will be the
result. Also, if the bounds is not set, or not set properly, the Billboard object will not animate the visual
object. The scheduling bounds is typically specified by BoundingSphere with a radius great enough to
enclose the visual object. Just like other behavior objects, leaving the Billboard object out of the scene
graph will eliminate it from the virtual world without error or warning.
There is one problem with the Billboard Class that can not be overcome. In applications with more than one
view, each Billboard object will animate properly for only one of the views. This is a limitation in the design
of Java 3D and will be addressed in a subsequent version.
5.3.2 Example Billboard Program
The BillboardApp example program creates a virtual world with billboard behavior trees. Even though the
trees are crudely created (from a triangle fan) they do not appear as 2D objects in the background
13
.
There are two TransformGroup objects for each tree in this example. One TransformGroup, TGT, simply
translates the tree into the position for the application. The TGT transform is not changed at runtime. The
second TransformGroup, TGR, provides the rotation for the tree. The TGR is the target of Billboard. Code
Fragment 5-3 is annotated with the steps of the recipe from Figure 5-14.
1. public BranchGroup createSceneGraph(SimpleUniverse su) {
2. BranchGroup objRoot = new BranchGroup();
3.
4. Vector3f translate = new Vector3f();
5. Transform3D T3D = new Transform3D();
6. TransformGroup TGT = new TransformGroup();
7. TransformGroup TGR = new TransformGroup();
8. Billboard billboard = null;
9. BoundingSphere bSphere = new BoundingSphere();
10.
11. translate.set(new Point3f(1.0f, 1.0f, 0.0f));
12. T3D.setTranslation(translate);
13. TGT.set(T3D);
14.
15. // set up for billboard behavior
16. TGR.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
17. billboard = new Billboard(TGR);
18. billboard.setSchedulingBounds(bSphere);
19.
20. // assemble scene graph
21. objRoot.addChild(TGT);
22. objRoot.addChild(billboard);
23. TGT.addChild(TGR);
24. TGR.addChild(createTree());
25.
13
Better trees could be created from transparent textures. Textures are covered in Chapter 7.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-26
26. // add KeyNavigatorBehavior(vpTrans) code removed;
27.
28. return objRoot;
29. } // end of CreateSceneGraph method of BillboardApp
Code Fragment 5-3 Except From the createSceneGraph Method of BillboardApp.java.
Figure 5-15 shows the scene graph diagram of the objects assembled in Code Fragment 5-3.
BG
Billboard
BoundingSphere
TG
TG
tree
Figure 5-15 Diagram of Scene Graph Using a Billboard Object as Created in Code Fragment 5-3.
Figure 5-16 shows an image rendered from the BillboardApp example program. Code Fragment 5-3 shows
the code for placing one Billboard animated tree in a virtual world. The BillboardApp program places
several trees on the virtual landscape which is why four trees are visible in Figure 5-16.
Figure 5-16 Image of BillboardApp with all 2D 'Trees' Facing the Viewer.
The BillboardApp example program provides a KeyNavigatorBehavior so that the user can move around
and observe the trees from various positions and orientations. See Section 4.4.2, or all of Chapter 4, for
more information on the KeyNavigatorBehavior class.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-27
5.3.3 Billboard API
The example shows using the default mode of the Billboard object, which is to rotate about an axis. In this
default mode, the visual object will be rotated about the y-axis only. So, if the trees in the BillboardApp
program are viewed from above or below, their 2D geometry would be revealed.
The alternative mode is to rotate about a point. In this mode, the rotation would be about a point such that
the visual object is always viewed orthogonally from any viewing position. In other words, it will never be
obvious that the visual object is two dimensional. One possible application is to represent the moon, or
other distant spherical objects as a circle. Spherical objects appear as a circle when viewed from any angle.
More information on the two modes of the Billboard accompanies the summaries of constructors and
methods in the next two reference blocks.
Billboard Constructor Summary
extends: Behavior
The Billboard behavior node operates on the TransformGroup node to cause the local +z axis of the
TransformGroup to point at the viewer's eye position. This is done regardless of the transforms above the specified
TransformGroup node in the scene graph. Billboard nodes provide the most benefit for complex, roughly-
symmetric objects. A typical use might consist of a quadrilateral textured with the image of a tree.
Billboard()
Constructs a Billboard node with default parameters: mode = ROTATE_ABOUT_AXIS, axis =(0,1,0).
Billboard(TransformGroup tg)
Constructs a Billboard node with default parameters that operates on the specified TransformGroup node.
Billboard(TransformGroup tg, int mode, Vector3f axis)
Constructs a Billboard node with the specified axis and mode that operates on the specified TransformGroup node.
See setMode() method for an explanation of the mode parameter.
Billboard(TransformGroup tg, int mode, Point3f point)
Constructs a Billboard node with the specified rotation point and mode that operates on the specified
TransformGroup node. See setMode() method for an explanation of the mode parameter.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-28
Billboard Method Summary (partial list)
void setAlignmentAxis(Vector3f axis)
Sets the alignment axis.
void setAlignmentAxis(float x, float y, float z)
Sets the alignment axis.
void setAlignmentMode(int mode)
Sets the alignment mode, where mode is one of:
ROTATE_ABOUT_AXIS - Specifies that rotation should be about the specified axis.
ROTATE_ABOUT_POINT - Specifies that rotation should be about the specified point and that the
children's Y-axis should match the view object's Y-axis.
void setRotationPoint(Point3f point)
Sets the rotation point.
void setRotationPoint(float x, float y, float z)
Sets the rotate point.
void setTarget(TransformGroup tg)
Sets the target TransformGroup object for this Billboard object.
5.4 Level of Detail (LOD) Animations
Level of Detail (LOD) is a general term for a technique that varies the amount of detail in a visual object
based on some value from the virtual world. The typical application is to vary the level of detail based on
the distance to the viewer. As the distance to a visual object increases, the fewer details will appear in the
rendering. So, reducing the complexity of the visual object may not affect the visual result. However,
decreasing the amount of detail in the visual object when it is far from the viewer reduces the amount of
rendering computation. If it is done well, a significant computational savings can be made without visual
loss of content.
The DistanceLOD Class provides LOD behavior based on distance to the viewer. Other possible LOD
applications include varying the level of detail based on the rendering speed (frames per second) in hopes of
maintaining a minimum frame rate, the speed of the visual object, or the level of detail could be controlled
by user settings.
Each LOD object has one or more Switch objects as a target. As mentioned before, a Switch object is a
special group that includes zero, one, or more, of its children in the scene graph for rendering (see "Switch"
on page 5-18 for more information). With a DistanceLOD object, the selection of the child of the target
Switch object is controlled by the distance of the DistanceLOD object to the view based on a set of threshold
distances.
The threshold distances are specified in an array beginning with the maximum distance the first child of the
switch target(s) will be used. The first child is typically the most detailed visual object. When the distance
from the DistanceLOD object to the view is greater than this first threshold, the second child of the switch is
used. Each subsequent distance threshold must be greater than the previous and specifies the distance at
which the next child of the target switch is used. Thus, there are one fewer threshold distances than there
are children of the switch target(s).
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-29
If more than one Switch is added as a target of the LOD object, then each Switch target is used in parallel.
That is, the child of the same index is selected simultaneously for each of the Switch targets. In this way, a
complex visual object can be represented by multiple geometric objects which are children of different
switch nodes.
5.4.1 Using a DistanceLOD Object
Using a DistanceLOD object is similar to using an interpolator except there is no Alpha object to drive the
animation. The animation of the LOD object is driven by its relative distance to the view in the virtual
world; in this way using a DistanceLOD object is very similar to using a Billboard object. Using a
DistanceLOD object also requires setting the threshold distances. Figure 5-17 shows the steps in the LOD
usage recipe.
1. create a target Switch object(s) with ALLOW_SWITCH_WRITE capability
2. create list of distance thresholds array for the DistanceLOD object
3. create DistanceLOD object using the distance thresholds array
4. set the target switch object for the DistanceLOD object
5. supply a scheduling bounds (or bounding leaf) for the DistanceLOD object
6. assemble the scene graph, including adding children to target Switch object(s)
Figure 5-17 Recipe for Using a DistanceLOD Object to Provide Animation.
LOD Programming Pitfalls
Even thought the usage of a LOD object is straightforward, there are a couple of potential programming
mistakes. The most common mistake is to fail to include the target switch object(s) in the scene graph.
Setting the switch object(s) as the target(s) of the DistanceLOD object does not automatically include them
in the scene graph.
Without the ALLOW_SWITCH_WRITE capability set for the target switch object(s), a runtime error will
result. Also, if the bounds is not set, or not set properly, the LOD object will not animate the visual object.
The scheduling bounds is typically specified by a BoundingSphere with a radius great enough to enclose the
visual object. Just like other behavior objects, leaving the Billboard object out of the scene graph will
eliminate it from the virtual world without error or warning.
There is one problem with the LOD classes that can not be overcome. Just like with Billboard applications,
in applications that have more than one view, the LOD object will only animate properly for one of the
views.
5.4.2 Example Usage of DistanceLOD
Code Fragment 5-4 shows an excerpt from the createSceneGraph method in the DistanceLODApp. The
program can be found in the examples/Animation subdirectory in the examples jar distribution as
DistanceLODApp.java. The code of Code Fragment 5-4 is annotated with the steps from the recipe
of Figure 5-17.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-30
1. public BranchGroup createSceneGraph() {
2. BranchGroup objRoot = new BranchGroup();
3. BoundingSphere bounds = new BoundingSphere();
4.
5. // create target TransformGroup with Capabilities
6. TransformGroup objMove = new TransformGroup();
7.
8. // create DistanceLOD target object
9. Switch targetSwitch = new Switch();
10. targetSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
11.
12. // add visual objects to the target switch
13. targetSwitch.addChild(new Sphere(.40f, 0, 25));
14. targetSwitch.addChild(new Sphere(.40f, 0, 15));
15. targetSwitch.addChild(new Sphere(.40f, 0, 10));
16. targetSwitch.addChild(new Sphere(.40f, 0, 4));
17.
18. // create DistanceLOD object
19. float[] distances = { 5.0f, 10.0f, 20.0f};
20. DistanceLOD dLOD = new DistanceLOD(distances, new Point3f());
21. dLOD.addSwitch(targetSwitch);
22. dLOD.setSchedulingBounds(bounds);
23.
24. // assemble scene graph
25. objRoot.addChild(objMove);
26. objMove.addChild(dLOD); // make the bounds move with object
27. objMove.addChild(targetSwitch); // must add switch to scene graph
28.
29. return objRoot;
30. } // end of CreateSceneGraph method of DistanceLODApp
Code Fragment 5-4 Excerpt from createSceneGraph Method in DistanceLODApp.
Figure 5-18 shows the scene graph diagram for the scene graph created in Code Fragment 5-4. Note that the
target Switch object is both a child of a TransformGroup object and referenced by the DistanceLOD object.
Both relationships are required.
BG
LOD
BoundingSphere
TG
S
Sphere0 Sphere1 Sphere2 Sphere3
Figure 5-18 Partial Scene Graph Diagram for DistanceLODApp Example Program.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-31
Figure 5-19 shows two scenes rendered by DistanceLODApp. Each scene has two static spheres and one
sphere that moves. (In the right scene, the leftmost sphere is occluded.) The moving sphere is represented
by a DistanceLOD object with four spheres of varying geometric complexity. The small green sphere is the
most detailed sphere used by the DistanceLOD object at the maximum distance. The large red sphere is the
least detailed sphere of the DistanceLOD object at the minimum distance. The two static spheres are
included for comparison purposes.
In this application the DistanceLOD object is represented by different color spheres to illustrate the
switching. Normally each visual object used by a LOD object would look as much alike as appropriate.
A PositionInterpolator is used to move the DistanceLOD object forward and back in the scene. As the
DistanceLOD object moves further from the view, it switches visual objects. Without the color change in
this application, it would not be easy to tell when the switching occurs.
Figure 5-19 Two Scenes Rendered from DistanceLODApp.
In practice, you typically need to experiment with the threshold distances and various representations to
achieve the desired visual and computational results.
5.4.3 DistanceLOD API
In Java 3D, the LOD Class provides the basic functionality for all LOD applications. The DistanceLOD
Class extends the LOD Class to add the 'switch on distance to viewer' computations. Several methods of the
LOD Class are necessary in the use of a DistanceLOD object. The API for the LOD Class is presented
following the DistanceLOD reference blocks.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-32
DistanceLOD Constructor Summary
This class defines a distance-based LOD behavior node that operates on a Switch group node to select one of the
children of that Switch node based on the distance of this LOD node from the viewer. An array of n monotonically
increasing distance values is specified, such that distances[0] is associated with the highest level of detail and
distances[n-1] is associated with the lowest level of detail. Based on the actual distance from the viewer to this
DistanceLOD node, these n distance values [0, n-1] select from among n+1 levels of detail [0, n]. If d is the distance
from the viewer to the LOD node, then the equation for determining which level of detail (child of the Switch node)
is selected is:
0, if d <= distances[0]
i, if distances[i-1] < d <= distances[i]
n, if d > distances[n-1]
Note that both the position and the array of distances are specified in the local coordinate system of this node.
DistanceLOD()
Constructs and initializes a DistanceLOD node with default values.
DistanceLOD(float[] distances)
Constructs and initializes a DistanceLOD node with the specified array of distances and a default position of (0,0,0).
DistanceLOD(float[] distances, Point3f position)
Constructs and initializes a DistanceLOD node with the specified array of distances and the specified position.
DistanceLOD Method Summary
int numDistances()
Returns a count of the number of LOD distance cut-off parameters.
void setDistance(int whichDistance, double distance)
Sets a particular LOD cut-off distance.
void setPosition(Point3f position)
Sets the position of this LOD node.
5.4.4 LOD (Level of Detail) API
As an abstract class, the LOD Class is not directly used in Java 3D programs. Methods of the LOD Class
are used to manage the target Switch object(s) of a DistanceLOD object. Also, other LOD applications
could be created by extending this class as appropriate.
LOD Constructor Summary
An LOD leaf node is an abstract behavior class that operates on a list of Switch group nodes to select one of the
children of the Switch nodes. The LOD class is extended to implement various selection criteria.
LOD()
Constructs and initializes an LOD node.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-33
LOD Method Summary
void addSwitch(Switch switchNode)
Appends the specified switch node to this LOD's list of switches.
java.util.Enumeration getAllSwitches()
Returns the enumeration object of all switches.
void insertSwitch(Switch switchNode, int index)
Inserts the specified switch node at specified index.
int numSwitches()
Returns a count of this LOD's switches.
void removeSwitch(int index)
Removes the switch node at specified index.
void setSwitch(Switch switchNode, int index)
Replaces the specified switch node with the switch node provided.
5.5 Morph
Interpolator classes change various visual attributes in the virtual world. However, there is no interpolator
to change the geometry of a visual object. This is exactly what the Morph Class does. A Morph object
creates the geometry for a visual object through interpolating from a set of GeometryArray objects
14
. In this
way the Morph Class is like the interpolator classes. But, Morph is not an interpolator; it isn't even an
extension of the Behavior class. The Morph Class extends Node.
Chapter 4 explains that all changes to a live scene graph or the objects in a live scene graph are normally
made through the processStimulus method of Behavior objects. Since there is no specific behavior class for
use with a Morph object, a custom behavior class must be written for a Morph application. Whether the
Morph class is considered an animation or interaction class depends on the stimulus for the behavior driving
the Morph object. Before getting into the details of using the Morph class, a little discussion of Morph
applications is in order.
Morph objects can be used to turn pyramids into cubes, cats into dogs, or change any geometry into any
other geometry. The only limitation is that the geometry objects used for interpolation are the same class,
each a subclass of GeometryArray, with the same number of vertices. The restriction on the number of
vertices is not as limiting as it first seems. An example program that changes a pyramid into a cube,
Pyramid2Cube.java, is distributed with the Java 3D API.
Morph objects can also be used to animate a visual object (e.g., to make a person walk, or to make a hand
grasp). An example program that animates a hand, Morphing.java, is also distributed with the Java
3D API examples. A third Morph example which makes a stick figure walk is the subject of the next
section.
14
The GeometryArray Class and related classes are covered in Chapter 2.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-34
5.5.1 Using a Morph Object
To understand the usage of the Morph object requires knowing how the Morph object functions.
Fortunately, a Morph object is not very complex. A Morph object stores an array of GeometryArray
objects. You may recall from Chapter 2 that GeometryArray is the superclass of TriangleArray,
QuadStripArray, IndexedLineStripArray, and TriangleFanArray (just to name a few).
The individual GeometryArray objects each completely defines one complete geometric specification for the
visual object including color, normals, and texture coordinates. The GeometryArray objects can be thought
of as key frames in an animation, or more properly, as constants in an equation to create a new
GeometryArray object.
In addition to the array of GeometryArray objects, a Morph object has an array of weight values these are
the variables in the equation. Using the GeometryArray objects and the weights, a Morph object constructs
a new geometry array object using the weighted average of the coordinate, color, normals, and texture
coordinate information from the GeometryArray objects. Changing the weights changes the resulting
geometry.
All that is required to use a Morph object is to create the array of GeometryArray objects and set the
weighting values. Figure 5-17 summarizes the steps to use a Morph object.
1. create an array of GeometryArray objects
2. create a Morph object with ALLOW_WEIGHTS_WRITE
3. assemble the scene graph, including adding children to target Switch object(s)
Figure 5-20 Recipe for Using a Morph Object.
As you can see, using a morph object is not hard; however, these steps provide neither animation nor
interaction. Animation or interaction is provided through a behavior object. Consequently, using a Morph
object usually means writing a behavior class. Writing a custom Behavior Class is covered in Section
4.2.1., so the general details of this task are not covered here. Of course, a Morph object can be used
without a behavior, but then it would not be animated. Section 5.5.2 presents a simple morph behavior class
useful in creating key frame animations.
A Morph object can refer to an appearance bundle. The appearance bundle is used with the GeometryArray
object created by the Morph object. Be aware that the Morph object always makes a GeometryArray object
with per-vertex-colors. As a consequence, a ColoringAttributes color and Material diffuse color
specifications are ignored. See Chapter 6 for more information on coloring and shading of visual objects.
Morph Programming Pitfalls
Even as simple as Morph usage is, there is an associated potential programming pitfall (not yet mentioned).
Weights that do not sum to 1.0 results in a runtime error. I have already mentioned the appearance
limitation.
5.5.2 Example Morph Application: Walking
This Morph application uses a custom behavior object to provide animation. The first step in this
development is to write the custom behavior.
In a behavior used to animate a Morph object, the processStimulus method changes the weights of the
Morph object. This process is only as complex as necessary to achieve the desired animation or interaction
effect. In this program, The processStimulus method sets the weights values based on the alpha value from
an alpha object. This happens on each frame of rendering where the trigger condition has been satisfied.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-35
Code Fragment 5-5 shows the code for the custom behavior of the MorphApp program. In this code, only
the processStimulus method is interesting.
1. public class MorphBehavior extends Behavior{
2.
3. private Morph targetMorph;
4. private Alpha alpha;
5. // the following two members are here for efficiency
6. private double[] weights = {0, 0, 0, 0};
7. private WakeupCondition trigger = new WakeupOnElapsedFrames(0);
8.
9. // create MorphBehavior
10. MorphBehavior(Morph targetMorph, Alpha alpha){
11. this.targetMorph = targetMorph;
12. this.alpha = alpha;
13. }
14.
15. public void initialize(){
16. // set initial wakeup condition
17. this.wakeupOn(trigger);
18. }
19.
20. public void processStimulus(Enumeration criteria){
21. // don't need to decode event since there is only one trigger
22. weights[0] = 0; weights[1] = 0; weights[2] = 0; weights[3] = 0;
23.
24. float alphaValue = 4f * alpha.value(); // get alpha
25. int alphaIndex = (int) alphaValue; // which Geom obj
26. weights[alphaIndex] = (double) alphaValue - (double)alphaIndex;
27. if(alphaIndex < 3) // which other obj
28. weights[alphaIndex + 1] = 1.0 - weights[alphaIndex];
29. else
30. weights[0] = 1.0 - weights[alphaIndex];
31.
32. targetMorph.setWeights(weights);
33.
34. this.wakeupOn(trigger); // set next wakeup condition
35. }
36. } // end of class MorphBehavior
Code Fragment 5-5 MorphBehavior Class from MorphApp.
The MorphBehavior class does a key frame animation using the GeometryArray objects two at a time in a
cyclical pattern. This class is suitable for any morph animation of four key frames and can be easily
changed to accommodate other numbers of key frames.
With the custom behavior written, all that remains is to develop the key frames for the animation. Figure
5-21 shows the hand drawings used as the key frames for this example application. Better key frames could
have been made using some 3D package.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-36
frame0 frame1 frame2 frame3 frame0 (repeated)
Figure 5-21 Key Frame Images from MorphApp with the Trace of One Vertex.
The black figures may look like two key frames, each repeated once, but in actuality, they are four unique
key frames. The difference is in the order the vertices are specified.
Code Fragment 5-6 shows and excerpt from the createSceneGraph method of MorphApp.java annotated
with the steps of the recipe in Figure 5-20. In this method, a MorphBehavior object, Alpha object, and a
Morph object are created and assembled into the scene graph. The key frame GeometryArray objects are
created using some other methods (not shown here). The complete code is distributed in the examples jar.
1. public BranchGroup createSceneGraph() {
2. // Create the root of the branch graph
3. BranchGroup objRoot = new BranchGroup();
4.
5. Transform3D t3d = new Transform3D();
6. t3d.set(new Vector3f(0f, -0.5f, 0f));
7. TransformGroup translate = new TransformGroup(t3d);
8.
9. // create GeometryArray[] (array of GeometryArray objects)
10. GeometryArray[] geomArray = new GeometryArray[4];
11. geomArray[0] = createGeomArray0();
12. geomArray[1] = createGeomArray1();
13. geomArray[2] = createGeomArray2();
14. geomArray[3] = createGeomArray3();
15.
16. // create morph object
17. Morph morphObj = new Morph(geomArray);
18. morphObj.setCapability(Morph.ALLOW_WEIGHTS_WRITE);
19.
20. // create alpha object
21. Alpha alpha = new Alpha(-1, 2000); // continuous 2 sec. period
22. alpha.setIncreasingAlphaRampDuration(100);
23.
24. // create morph driving behavior
25. MorphBehavior morphBehav = new MorphBehavior(morphObj, alpha);
26. morphBehav.setSchedulingBounds(new BoundingSphere());
27.
28. //assemble scene graph
29. objRoot.addChild(translate);
30. translate.addChild(morphObj);
31. objRoot.addChild(morphBehav);
32.
33. return objRoot;
34. } // end of CreateSceneGraph method of MorphApp
Code Fragment 5-6 An Excerpt from the createSceneGraph Method of MorphApp.
It is interesting to note that a variety of animations are possible using the key frames created for this
example application with different behavior classes. Figure 5-22 shows a scene rendered by Morph3App.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-37
In this program, three other behavior classes create animations based on some, or all, of the GeometryArray
objects of MorphApp. They are called (left to right in the figure) "In Place", "Tango", and "Broken". Not
all of the animations are good. Of course, to truly appreciate the animations, you have to run the program.
The source is included in the examples jar.
Figure 5-22 A Scene Rendered from Morph3App Showing the Animations of Three Alternative
Behavior Classes (not all are good).
5.5.3 Morph API
With the simplicity of the usage recipe (Figure 5-20), you would expect a relatively simple API and it is.
The API is summarized in the next three reference blocks.
Morph Constructor Summary
extends: Node
Morph objects create a new GeometryArray object using the weighted average of the GeometryArray objects. If an
appearance object is provided, it is used with the resulting geometry. The weights are specified with the
setWeights method. A Morph object is usually used with a custom behavior object to adjust the weights at
runtime to provide animation (or interaction).
Morph(GeometryArray[] geometryArrays)
Constructs and initializes a Morph object with the specified array of GeometryArray objects and a null Appearance
object.
Morph(GeometryArray[] geometryArrays, Appearance appearance)
Constructs and initializes a Morph object with the specified array of GeometryArray objects and the specified
appearance object.
Module 3: Interaction and Animation Chapter 5. Animation
The Java 3D Tutorial 5-38
Morph Method Summary (partial list)
void setAppearance(Appearance appearance)
Sets the appearance component of this Morph node.
void setGeometryArrays(GeometryArray[] geometryArrays)
Sets the geometryArrays component of the Morph node.
void setWeights(double[] weights)
Sets this Morph node's morph weight vector.
Morph Capabilities Summary
ALLOW_APPEARANCE_READ | WRITE
Specifies that the node allows read/write access to its appearance information.
ALLOW_GEOMETRY_ARRAY_READ | WRITE
Specifies that the node allows read/write access to its geometry information.
ALLOW_WEIGHTS_READ | WRITE
Specifies that the node allows read/write access to its morph weight vector.
5.6 Chapter Summary
After Section 5.1 introduces animations in Java 3D, Section 5.2 explains the application of interpolator
classes with an Alpha object to add time based animations to a Java 3D virtual world. This section explains
many of the various interpolator classes in detail. Sections 5.3 and 5.4 explain the Billboard and
DistanceLOD classes, respectively, which are useful in creating animations for the purpose of reducing the
rendering cost of visual objects. In Section 5.5 the Morph class is introduced. That section also presents a
complete example using a Morph object to create a key frame animation.
5.7 Self Test
1. The InterpolatorApp example program uses six different interpolator objects. Each of the interpolator
objects refers to the same Alpha object. The result is to coordinate all the interpolators. What would be the
result if each interpolator object had its own Alpha object? How could you change the timing?
2. If the light in InterpolatorApp is changed to Vector3f(-0.7f,-0.7f,0.0f) what happens?
Why?
3. Why are there fewer distances than visual objects specified for a DistanceLOD object?
4. In MorphApp there are four frames of which two look like duplicates of the other two. Why are four
frames necessary? Asked another way, what would the animation look like with just two frames?
5. In using a morph object, the same number of vertices are used. How can you accommodate geometric
models of differing numbers of vertices?
tutorial v1.5 (Java 3D API v1.1.2)
Getting Started with
the Java 3D
API
Chapter 6
Lights
Dennis J Bouvier
K Computing
Getting Started with Java 3D Chapter 6. Lights
1999 Sun Microsystems, Inc.
2550 Garcia Avenue, Mountain View, California 94043-1100 U.S.A
All Rights Reserved.
The information contained in this document is subject to change without notice.
SUN MICROSYSTEMS PROVIDES THIS MATERIAL "AS IS" AND MAKES NO WARRANTY OF ANY
KIND, EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS SHALL
NOT BE LIABLE FOR ERRORS CONTAINED HEREIN OR FOR INCIDENTAL OR CONSEQUENTIAL
DAMAGES (INCLUDING LOST PROFITS IN CONNECTION WITH THE FURNISHING, PERFORMANCE
OR USE OF THIS MATERIAL, WHETHER BASED ON WARRANTY, CONTRACT, OR OTHER LEGAL
THEORY).
THIS DOCUMENT COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS.
CHANGES ARE PERIODICALLY MADE TO THE INFORMATION HEREIN; THESE CHANGES WILL BE
INCORPORATED IN NEW EDITIONS OF THE PUBLICATION. SUN MICROSYSTEMS, INC. MAY MAKE
IMPROVEMENTS AND/OR CHANGES IN THE PRODUCT(S) AND/OR PROGRAM(S) DESCRIBED IN THIS
PUBLICATION AT ANY TIME.
Some states do not allow the exclusion of implied warranties or the limitations or exclusion of liability for
incidental or consequential damages, so the above limitations and exclusion may not apply to you. This warranty
gives you specific legal rights, and you also may have other rights which vary from state to state.
Permission to use, copy, modify, and distribute this documentation for NON-COMMERCIAL purposes and
without fee is hereby granted provided that this copyright notice appears in all copies.
This documentation was prepared for Sun Microsystems by K Computing (530 Showers Drive, Suite 7-225,
Mountain View, CA 94040, 770-982-7881, www.kcomputing.com). For further information about course
development or course delivery, please contact either Sun Microsystems or K Computing.
Java, JavaScript, Java 3D, HotJava, Sun, Sun Microsystems, and the Sun logo are trademarks or registered
trademarks of Sun Microsystems, Inc. All other product names mentioned herein are the trademarks of their
respective owners.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-i
Table of Contents
Chapter 6
Lights ...................................................................................................................................................6-1
6.1 Shading in Java 3D....................................................................................................................6-1
6.2 Recipe for Lit Visual Objects.....................................................................................................6-4
6.2.1 Simple Lights Example.......................................................................................................6-5
6.2.2 Where to Add a Light Object in the Scene Graph ................................................................6-8
6.3 Light Classes.............................................................................................................................6-9
6.3.1 Ambient Light ..................................................................................................................6-11
6.3.2 Directional Light ..............................................................................................................6-11
6.3.3 Point Light .......................................................................................................................6-13
6.3.4 Spot Light ........................................................................................................................6-15
6.3.5 Applications of Light Sources...........................................................................................6-17
6.3.6 Examples of Lighting .......................................................................................................6-17
6.4 Material Object .......................................................................................................................6-20
6.4.1 Simple Material Examples................................................................................................6-22
6.4.2 Geometry color, ColoringAttributes, and Material Properties ............................................6-23
6.5 Surface Normals......................................................................................................................6-24
6.6 Specifying the Influence of Lights ............................................................................................6-25
6.6.1 Influencing Bounds Alternative: BoundingLeaf .................................................................6-26
6.6.2 Scoping Limits Lights' Influence.......................................................................................6-26
6.7 Creating Glow-in-the-Dark Objects, Shadows, and Other Lighting Issues .................................6-29
6.7.1 Glow-in-the-Dark Objects.................................................................................................6-29
6.7.2 Computing Shadows.........................................................................................................6-30
6.7.3 Creating Shadows ............................................................................................................6-30
6.7.4 Shadow Example Program................................................................................................6-31
6.7.5 Advanced Topic: The Role of the View Object in Shading.................................................6-32
6.8 Chapter Summary....................................................................................................................6-34
6.9 Self Test..................................................................................................................................6-34
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-ii
List of Figures
Figure 6-1 Light, Surface Normal, and Eye Vectors used to Shade Vertices. ..........................................6-2
Figure 6-2 Shaded Sphere and Plane......................................................................................................6-2
Figure 6-3 Flat and Gouraud Shaded Spheres. .......................................................................................6-4
Figure 6-4 Items Necessary for Lit Scenes in Java 3D............................................................................6-5
Figure 6-5 Exception When a Visual Object With Material is Missing Normals. ....................................6-5
Figure 6-6 Scene Graph Diagram of Simple Example (Code Fragment 6-1) ...........................................6-7
Figure 6-7 A Sphere with Ambient Light. ..............................................................................................6-7
Figure 6-8 Abbreviated Scene Graph Diagram of Simple Example (Code Fragment 6-1 and 6-2). ..........6-8
Figure 6-9 A Sphere with Ambient and Directional Light Sources. .........................................................6-8
Figure 6-10 BoundingSphere Affected by Transformation......................................................................6-9
Figure 6-11 Java 3D API Class Hierarchy for Light Classes ................................................................6-10
Figure 6-12 Light Vector is Constant for DirectionalLight Source. .......................................................6-12
Figure 6-13 Light Vector Varies for a PointLight Source. ....................................................................6-13
Figure 6-14 Light Intensity Varies with Distance and Orientation for a PointLight Source. ...................6-15
Figure 6-15 Spheres Lit by Two Directional Light Sources ..................................................................6-18
Figure 6-16 Planes Lit by Directional, Point, and Spot Light Sources (best viewed in color). ................6-18
Figure 6-17 Geometry of Lighting Planes with Directional and Point Light Sources..............................6-19
Figure 6-18 A Plane Lit by SpotLights with Different Concentrations and Spread Angles.....................6-19
Figure 6-19 API Hierarchy for Material ..............................................................................................6-21
Figure 6-20 Different Material Properties ............................................................................................6-23
Figure 6-21 Twist Strip with (left) and without (right) Back Face Flip Normals (best viewed in color)..6-25
Figure 6-22 Geometry with Normal Specification Problems .................................................................6-25
Figure 6-23 Moving Light Objects Independently of Their Influence using a BoundingLeaf. .................6-26
Figure 6-24 Two Possible Scene Graphs for the Light Scoping Example. .............................................6-27
Figure 6-25 Light Scoping Example Scene With (left) and Without (right) Scoping of the Lamp Light. 6-28
Figure 6-26 A Glow-in-the-Dark Object Example. ...............................................................................6-30
Figure 6-27 Projecting the Shadow of a Visual Object to a Plane for One Light....................................6-30
Figure 6-28 Scene Produced by ShadowApp.java Demonstrating Automatic Shadowing in Java 3D.....6-32
Figure 6-29 Infinite Eye Versus Local Eye Rendering with Directional and Point Light Sources. ..........6-33
Figure 6-30 Java 3D API Hierarchy for Classes Covered in this Chapter..............................................6-34
List of Tables
Table 6-1 Coloring for Objects when Lighting is Enabled (Material object is referenced)......................6-24
Table 6-2 Coloring for Objects when Lighting is Disabled (no Material object is referenced) ................6-24
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-iii
List of Code Fragments
Code Fragment 6-1 Creating a Scene with a Lit Sphere..........................................................................6-6
Code Fragment 6-2 Adding a Directional Light to the Scene...................................................................6-7
Code Fragment 6-3 Shadow Class for Making Shadow Polygons. ........................................................6-32
List of Reference Blocks
Light Method and Capability Summary (partial list) ............................................................................6-10
Light Capabilities Summary................................................................................................................6-10
AmbientLight Constructor Summary...................................................................................................6-11
DirectionalLight Constructor Summary ...............................................................................................6-12
DirectionalLight Method Summary......................................................................................................6-12
DirectionalLight Capabilities Summary...............................................................................................6-13
PointLight Constructor Summary........................................................................................................6-14
PointLight Method Summary...............................................................................................................6-14
PointLight Capabilities Summary........................................................................................................6-14
SpotLight Constructor Summary.........................................................................................................6-16
SpotLight Method Summary ...............................................................................................................6-16
SpotLight Capabilities Summary.........................................................................................................6-16
Material Constructor Summary ...........................................................................................................6-21
Material Method Summary (partial list)...............................................................................................6-22
Material Capabilities Summary...........................................................................................................6-22
Light Method Summary (partial list)....................................................................................................6-29
View Method Summary (partial list, methods related to shading).........................................................6-33
Preface to Chapter 6
This document is one part of a tutorial on using the Java 3D API. You should be familiar with Java 3D
API basics to fully appreciate the material presented in this Chapter. Additional chapters and the full
preface to this material is presented in the Module 0 document available at:
http://java.sun.com/products/javamedia/3d/collateral
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-1
6
Lights
Chapter Objectives
After reading this chapter, youll be able to:
Understand the Java 3D lighting model
Specify light objects and attributes
Specify visual objects with material properties
Specify the influence of lights in a variety of ways
The images Java 3D renders from the virtual worlds in "Getting Started with the Java 3D API" (Module
1 of this tutorial) lack visual detail. Those images, like "paint by numbers art ", lack the variation in color
and shading present in the real world. This module presents techniques for providing visual detail through
shading and texturing of visual objects. Chapter 6, Lights, explains the lighting model and how to use
lights in Java 3D to achieve shading. Chapter 7, Texturing, shows how to use textures to add detail to a
visual object without adding more geometry.
Java 3D shades visual objects based on the combination of their material properties and the lights in the
virtual universe. Shading results from applying a lighting model to a visual object in the presence of light
sources. Section 6.1 gives an overview of the lighting model used in the Java 3D renderer and how the light
interacts with material properties to provide shading. Each of the subsequent sections explains the Java 3D
API features relevant to the lighting model.
6.1 Shading in Java 3D
The shading of visual objects in Java 3D depends on many factors. This section provides a brief overview
of the Java 3D Lighting Model, Color Model, and Shading Models. The Java 3D API Specification
presents more detailed information on the Java 3D Lighting Model. Since much of the Java 3D lighting
and shading model is based on OpenGL, more information can also be found in OpenGL references.
CHAPTER
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-2
Lighting Model
In the real world, the colors we perceive are a combination of the physical properties of the object, the
characteristics of the light sources, the objects' relative positions to light sources, and the angle from which
the object is viewed. Java 3D uses a lighting model to approximate the physics of the real world. The rest
of this section explains the Java 3D lighting model in general terms. Section E.2 of The Java 3D API
Specification presents the mathematical equations of the Java 3D lighting model.
The lighting model equation depends on three vectors: the surface normal (N), the light direction (L), and
the direction to the viewer's eye (E) in addition to the material properties of the object and the light
characteristics. Figure 6-1 shows the three vectors for two vertices of a spherical surface. The vectors for
each vertex have may different directions depending on scene specifics. When the light and eye vectors
vary, they are computed at rendering time. Therefore, each vertex of the sphere potentially renders as a
different shade.
N L
E
N
L
E
Figure 6-1 Light, Surface Normal, and Eye Vectors used to Shade Vertices.
The lighting model incorporates three kinds of real world lighting reflections: ambient, diffuse, and
specular. Ambient reflection results from ambient light, constant low level light, in a scene. Diffuse
reflection is the normal reflection of a light source from a visual object. Specular reflections are the
highlight reflections of a light source from an object, which occur in certain situations.
Figure 6-2 shows a sphere and a plane rendered by Java 3D. The three types of reflection are seen in the
sphere in Figure 6-2. The darkest part of the sphere exhibits ambient reflection alone. The center of the
sphere is lit by diffuse and ambient light. With a blue sphere and a white light, the diffuse reflection is
blue. The brightest part of the sphere is the result of specular reflection with ambient and diffuse
reflections.
diffuse reflection
(blue)
specular reflection
(white)
ambient reflection
(gray)
no shadow!
no inter-object reflection
Figure 6-2 Shaded Sphere and Plane
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-3
Local Eye versus Infinite Eye Vectors
If each vertex of each visual object in a scene requires a light vector, an eye vector, and shade calculation, a
significant portion of the rendering computation is used in shading vertices. The amount of computation
can be reduced if the light vector, or eye vector, or both vectors are constant. The light vector is constant
when using a directional light (see section 6.3.2 for more information). The eye vector is constant by
default, although you can specify a variable eye vector using a method of the View object (see section
6.7.5).
Inter-object Effects Not Considered
While the lighting model is based on physics, complex physical phenomena are not modeled. Obviously,
the shadow cast by the sphere on the plane is missing from Figure 6-2. Not as obvious, the light reflected
from the sphere onto the plane is also missing. Also missing is the light reflected from the plane onto the
sphere which is reflected back to the plane and so on.
It is often difficult to comprehend the complexity of calculating the action of light. Consider the difficulty
of calculating how each drop of water behaves in a shower. Drops come from the showerhead in a variety
of directions. When they encounter an object, the resulting collision produces many smaller drops
travelling in a variety of directions. The process repeats many times before the water runs down the drain.
The complexity of light interactions with visual objects is similarly complex. Some differences between the
behaviors of water and light are that light has no adhesion (light doesn't stick to visual objects) and the
effect of gravity is negligible for light.
To reduce the complexity of computation, the lighting model considers only one visual object at a time. As
a result, shadows and inter-object reflections are not rendered by the lighting model. Both of these effects
require considering all objects together with their relative positions at rendering time. Significantly more
computation is required to render a single scene with inter-object effects. Java 3D, and all other real time
graphics systems, ignore inter-object effects in rendering. Some of the ignored real world effects can be
added to scenes where necessary. Section 6.7 discusses the complexity of shadows and techniques for
producing shadows in a Java 3D program.
Color Model
The color model is not physics based. Java 3D models the color of lights and materials as the combination
of red, green, and blue. The color white, whether as a light or a material color, is the combination of all
three components at maximum intensity. Each light produces a single color light specified by a RGB tuple.
The lighting model is applied for each of the RGB color components. For example, a red ball in the
presence of a blue light will not be visible since the blue light will not reflect from a red object. In reality,
color is a combination of many wavelengths of light, not just three. The RGB color model represents many
colors, but not all.
Influence of Lights
In Java 3D, the portion of a scene where visual objects are illuminated by a particular light source is called
that light object's region of influence. The simplest region of influence for a light source uses a Bounds
object and the setInfluencingBounds() method of the light. When a light source object's
influencing bounds intersects the bounds of a visual object, the light is used in shading the entire object.
The influencing bounds of a light determines which objects to light, not which portions of objects to light.
Section 6.2.2 explains this concept in more detail. Section 6.6 presents alternative methods for controlling
the influence of lights.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-4
Shading Model
The lighting model shades
1
each vertex of a visual object for each influencing light. The shade of a vertex
is the sum of the shades provided by each light source for the vertex. The rest of a visual object is shaded
based on the shade of the vertices. The Shade Model of a visual object, specified as an attribute in the
Appearance NodeComponent, determines how the shading is done for the rest of the visual object.
The ColoringAttributes NodeComponent specifies the Shade Model for visual objects where the shade
model is specified as one of SHADE_GOURAUD, SHADE_FLAT, FASTEST, NICEST. Refer to
Section 2.6.3 of Module 1 for additional information on the ColoringAttributes class. Be aware the color
set in a ColoringAttributes object is never used in shading.
In Gouraud shading, each pixel is shaded with a value derived from trilinear interpolation of the shade
value of each vertex of its enclosing polygon. In flat shading, all pixels for a polygon are assigned the
shade value from one vertex of the polygon
2
. Figure 6-3 shows one flat shaded sphere and one Gouraud
shaded sphere. The advantage to flat shading is speed in software rendering
3
. Gouraud shading has the
advantage of visual appeal.
Figure 6-3 Flat and Gouraud Shaded Spheres.
One last point before going on to an example; light source objects are not visual objects. Even if a light
source is placed within the view, it is not rendered.
6.2 Recipe for Lit Visual Objects
A number of steps are necessary to enable lighting for visual objects in the virtual universe. In addition to
creating and customizing light objects, each light object must be added to the scene graph and have a
bounds object specified. Each visual object to be shaded must have surface normals and material
properties. Figure 6-4 lists these requirements.
1
The term shade means to calculate the color value for a vertex or pixel in a rendered scene. In this context, shade
has nothing to do with shadows. See the glossary for more information.
2
The selection of the vertex to use for a polygon is implementation dependent and can be neither determined nor
controlled.
3
When using graphics hardware, the difference in rendering time for flat versus Gouraud shading varies
considerably depending on the hardware. Gouraud shading may be faster than flat shading for some hardware.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-5
1. Light Source specification
a. set bounds
b. add to scene graph
2. Visual object
a. normals
b. material properties
Figure 6-4 Items Necessary for Lit Scenes in Java 3D
Missing any one of these items will prevent lighting from being used. The presence of the Material object
in an Appearance bundle of a visual object enables the lighting model for that object. Without the Material
object the visual object will be colored, but not shaded by either the ColoringAttribute or vertex colors of
the Geometry object. If neither is present, then the object will be solid white. Figure 6-5 shows the
exception given when a visual object has a Material object but no surface normals.
javax.media.j3d.IllegalRenderingStateException: Cannot do lighting without
specifying normals in geometry object
Figure 6-5 Exception When a Visual Object With Material is Missing Normals.
Mistakes with light sources may not be as easy to find. There is no warning for leaving light out of a scene
graph. There is no warning for not setting a light source's influencing bounds. In either case, the light
object will have no influence on visual objects in the scene graph. A visual object properly specified for
shading (i.e., one with a Material object) in a live scene graph but outside the influencing bounds of all light
source objects renders black.
It is possible to properly specify a scene in which a visual object with material properties influenced by a
light object that renders black. The relative orientation of the light, the visual object, and the viewing
direction all come into play in rendering. Periodically this chapter addresses rendering issues. In
particular, Sections 6.3.6 and 6.5 present possible programming pitfalls.
6.2.1 Simple Lights Example
As mentioned above, creating shaded renderings involves the proper specification of the light source and
visual objects. Thus far, neither the Light classes nor Material objects have been discussed in any detail.
However, taking advantage of API defaults and features, we can proceed in lighting virtual worlds.
Geometric primitives generate surface normals when requested (refer to Section 2.3.8 of Module 1 for more
information). Material Object defaults specify a reasonable visual object. Light source constructors'
defaults specify usable light sources.
Using the SimpleUniverse class with the two methods of Code Fragment 6-1 produces a virtual universe
including a single sphere with default material properties lit by a single AmbientLight light source object.
The first method of the code fragment assembles a Material object with an Appearance object for the
Sphere. The second method creates a BranchGroup object to serve as the root of the content branch graph,
then adds Sphere and AmbientLight objects to the graph. The Material object in the appearance bundle is
added to the Sphere object in the construction of the Sphere (lines 12 and 13). A default BoundingSphere
provides the region of influence for the AmbientLight object (lines 15 through 17). The scene graph
diagram of this virtual world appears in Figure 6-6.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-6
1. Appearance createAppearance() {
2. Appearance appear = new Appearance();
3. Material material = new Material();
4. appear.setMaterial(material);
5.
6. return appear;
7. }
8.
9. BranchGroup createScene (){
10. BranchGroup scene = new BranchGroup();
11.
12. scene.addChild(new Sphere(0.5f, Sphere.GENERATE_NORMALS,
13. createAppearance()));
14.
15. AmbientLight lightA = new AmbientLight();
16. lightA.setInfluencingBounds(new BoundingSphere());
17. scene.addChild(lightA);
18.
19. return scene;
20. }
Code Fragment 6-1 Creating a Scene with a Lit Sphere.
Lines 4 and 5 of Code Fragment 6-1 could be replaced with the following line creating and using an
anonymous Material object.
Appear.setMaterial(new Material());
Material objects are fully customizable using the parameterized constructor, simplifying the use of
anonymous Material objects (see Section 6.4). By contrast, creating an anonymous Light object makes
adding the influencing bounds for the light much harder (see Section 6.3). Keep in mind that naming the
Material object may make it easier to share the object among various appearance bundles, resulting in
better performance.
The SimpleUniverse provides the VirtualUniverse and Locale objects along with the View Branch Graph
for the Scene Graph Diagram shown in Figure 6-6. Without a transformation, the Sphere object and the
BoundingSphere object are centered at the origin, and thus they intersect. The Sphere object is shaded by
the AmbientLight source. Figure 6-7 shows the resulting image with a white background. The background
specification is not shown in the code.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-7
BG
L
Appearance
S
Geometry BoundingSphere
SimpleUniverse
View Branch Graph
Figure 6-6 Scene Graph Diagram of Simple Example (Code Fragment 6-1)
The sphere of Figure 6-7 is uniform gray in color, which is the ambient material property default value.
Figure 6-7 A Sphere with Ambient Light.
Figure 6-7 demonstrates that scenes lit with ambient light alone are dull. Because Ambient lighting is
uniform, it produces uniform shade. Ambient light is intended as fill light in the scene where other sources
do not light. Adding a DirectionalLight source will make this scene more interesting.
Inserting Code Fragment 6-2 into Code Fragment 6-1 adds a DirectionalLight to the content branch graph
of the scene graph. Again, the defaults are used for the light source, and a default BoundingSphere is used
for the region of influence. Figure 6-8 shows the resulting scene graph diagram without the objects
provided by the SimpleUniverse.
1. DirectionalLight lightD1 = new DirectionalLight();
2. lightD1.setInfluencingBounds(new BoundingSphere());
3. // customize DirectionalLight object
4. scene.addChild(lightD1);
Code Fragment 6-2 Adding a Directional Light to the Scene.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-8
BG
L
Appearance
S
Geometry
L
BoundingSphere BoundingSphere
Figure 6-8 Abbreviated Scene Graph Diagram of Simple Example (Code Fragment 6-1 and 6-2).
Figure 6-9 shows the image produced by the combination of two code fragments. The influence of the
AmbientLight object can hardly be seen with the DirectionalLight source. Obviously, customization of the
light objects and/or the material properties of the visual object is necessary to create interesting scenes.
These topics are covered in Sections 6.3 and 6.4, respectively. The next section presents a discussion of
the location of light objects in the scene graph.
Figure 6-9 A Sphere with Ambient and Directional Light Sources.
6.2.2 Where to Add a Light Object in the Scene Graph
The influence of a light object on the world is not affected by the light object's position in the scene graph;
however, the bounds object referenced by the light is. The bounds object is subject to the local coordinates
of the scene graph where the light object is inserted. Consider Figure 6-10 as an example. The same
BoundingSphere object referenced by two light sources provided two different regions of influence due the
translation provided by the TransformGroup object. The origin of the local coordinate system of the scene
graph below the TransformGroup is 2 meters below the origin of the world (Locale) and the other region of
influence sphere.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-9
BG
TG
L
Appearance
S
Geometry
L
translate (0,-2,0)
BoundingSphere
y-axis
x-axis
1
-1
-3
light1 light2
light2
region of
influence
light1
region of
influence
Figure 6-10 BoundingSphere Affected by Transformation
Whether or not either, or both, light source objects of the scene graph in Figure 6-10 influence the shading
(light) of the visual object depends on whether the bounds of the visual object intersects the region of
influence of the light objects. Specifying a light's region of influence as a single bounds object may not
work for all applications. Section 6.6 presents alternative methods for controlling the influence of lights.
6.3 Light Classes
The Java 3D API provides four classes for lights. Each are derived from the Light class. Figure 6-11
shows the Java 3D class hierarchy related to lights. Light, an abstract class, provides the methods and
associated capability constants for manipulating the state, color, and bounds of a Light object. The state of
light is a Boolean turning the light on or off. Sections 6.3.1 through 6.3.4 give details for each of the light
classes. Section 6.6 presents alternative methods for controlling the influence of lights.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-10
java.lang.Object
javax.media.j3d.SceneGraphObject
javax.media.j3d.Node
javax.media.j3d.Leaf
javax.media.j3d.Light
javax.media.j3d.AmbientLight
javax.media.j3d.DirectionalLight
javax.media.j3d.PointLight
javax.media.j3d.SpotLight
Figure 6-11 Java 3D API Class Hierarchy for Light Classes
The following reference block lists the methods and constants of the Light class. Recall that bounds set
with setInfluencingBounds() enables a light when the referenced bounds object intersects the
view frustum.
Light Method and Capability Summary (partial list)
Light is an abstract class containing instance variables common to all lights. Additional methods appear in a
reference block in Section 6.6 (page 6-29).
void setColor(Color3f color)
Sets the Light's current color.
void setEnable(boolean state)
Turns the light on or off.
void setInfluencingBounds(Bounds bounds)
Sets the light's influencing bounds.
Light Capabilities Summary
Refer to Section 1.8.2 for more information on Capabilities.
ALLOW_INFLUENCING_BOUNDS_READ | WRITE
ALLOW_STATE_READ | WRITE
ALLOW_COLOR_READ | WRITE
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-11
6.3.1 Ambient Light
Ambient light objects provide light of the same intensity in all locations
4
and in all directions. Ambient
light objects model the light reflected from other visual objects. If you look up at the underside of your
desk, you will see the bottom surface of the desk although no light source is directly shining on that surface
(unless you have a lamp under your desk). The light shining up on the bottom surface of the desk reflected
off the floor and other objects. In natural environments with many objects, light reflects off many objects
to provide ambient light. The AmbientLight class in Java 3D simulates this effect.
The following reference block lists the constructors for the AmbientLight class. The Light abstract class
provides the methods and capabilities for this class (listed in the previous reference block).
AmbientLight Constructor Summary
A light source object providing the same intensity of light at all locations in all directions. Models the complex
inter-object reflection of light present in natural scenes. See the Light Method Summary on page 6-10 for
methods.
AmbientLight()
Constructs and initializes an ambient light source using the following default values:
lightOn true
color (1, 1, 1)
AmbientLight(Color3f color)
Constructs and initializes an ambient light using the specified parameters.
AmbientLight(boolean lightOn, Color3f color)
Constructs and initializes an ambient light using the specified parameters.
While it may be natural to think of an ambient light source as globally applicable, it is not necessarily true
in a Java 3D program. AmbientLight source influence is controlled by its bounds just like other Java 3D
light sources. Multiple AmbientLight source objects can be used in a Java 3D program. There is no limit
on the number of AmbientLight source objects in Java 3D programs
5
.
As mentioned in Section 6.1 (Shading in Java 3D ), the shade of a vertex is the result of the light sources,
the material properties of the visual object, and their relative geometry (distance and orientation). For
ambient reflections, the geometry is not a factor. The ambient material property is only used in calculating
the ambient reflection. The lighting model calculates the ambient reflection of light as the product of
AmbientLight intensity and the ambient material properties of visual object. Section 6.4 presents material
properties of visual objects in more detail.
6.3.2 Directional Light
A DirectionalLight source approximates very distant light sources such as the sun. Unlike AmbientLight
sources, DirectionalLight sources provide light shining in one direction only. For objects lit with a
DirectionalLight source, the Light vector is constant.
4
Of course, the influence of the light source is limited by its bounds. "In all locations" means under the visual
object as well as over it when the light source's bounds intersects the ambient light source's region of influence.
5
While the Java 3D API imposes no limit on the number of light sources, the implementation may. See page 6-20
for more information on the Limit on the Number of Lights.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-12
Figure 6-12 shows two vertices of the same sphere being lit by a DirectionalLight source. The Light
Vector is the same for these two and all vertices. Compare Figure 6-12 with Figure 6-1 to see the
difference. Since all light vectors from a DirectionalLight source are parallel, the light does not attenuate.
In other words, the intensity of a DirectionalLight source does not vary by the distance between the visual
object and the DirectionalLight source.
N L
E
N
L
E
Figure 6-12 Light Vector is Constant for DirectionalLight Source.
The next two reference block list the constructors and methods for DirectionalLight object, respectively.
DirectionalLight Constructor Summary
DirectionalLight objects model very distant light sources having a constant light direction vector.
DirectionalLight()
Constructs and initializes a directional source using the following default values:
lightOn true
color (1, 1, 1)
direction (0, 0, -1)
DirectionalLight(Color3f color, Vector3f direction)
Constructs and initializes a directional light with specified color and direction. By default the state is true (on).
DirectionalLight(boolean lightOn, Color3f color, Vector3f direction)
Constructs and initializes a directional light with specified state, color, and direction.
The following reference block lists the methods and capability bits the DirectionalLight class adds to the
methods of Light class.
DirectionalLight Method Summary
See the Light Method Summary on page 6-10 for more methods.
void setDirection(Vector3f direction)
Set light direction.
void setDirection(float x, float y, float z)
Set light direction.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-13
DirectionalLight Capabilities Summary
In addition to the Capabilities inherited from Light (listed on page 6-11), DirectionalLight objects have the
following Capability.
ALLOW_DIRECTION_READ | WRITE
DirectionalLights only participate in diffuse and specular reflection portions of the lighting model. For
diffuse and specular reflections, the geometry is a factor (unlike ambient reflections). Varying the direction
of the light source will change the shading of visual objects. Only diffuse and specular material properties
are used in calculating the diffuse and specular reflections. Section 6.4 presents material properties of
visual objects in more detail.
6.3.3 Point Light
The PointLight is the conceptual opposite of a DirectionalLight. It is an omni-directional light source
whose intensity attenuates with distance and has location. (A DirectionalLight source has no location, just
a direction.) PointLight objects approximate bare light bulbs, candles, or other light sources without
reflectors or lenses.
A quadratic equation models the attenuation of PointLight sources. The equation is found in Section E.2 of
The Java 3D API Specification. Figure 6-13 illustrates the relationship of a PointLight object with a
sphere. Note that the light vectors are not parallel.
N
L
E
N
L
E
Figure 6-13 Light Vector Varies for a PointLight Source.
The following two reference blocks list the constructors and methods of PointLight, respectively.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-14
PointLight Constructor Summary
The PointLight object specifies an attenuated light source at a fixed point in space that radiates light equally in all
directions away from the light source.
PointLight()
Constructs and initializes a point light source using the following default values:
lightOn true
color (1, 1, 1)
position (0, 0, 0)
attenuation (1, 0, 0)
PointLight(Color3f color, Point3f position, Point3f attenuation)
Constructs and initializes a point light. By default, the light is on.
PointLight(boolean lightOn, Color3f color, Point3f position, Point3f
attenuation)
Constructs and initializes a point light.
PointLight Method Summary
See the Light Method Summary on page 6-10 for more methods.
void setAttenuation(Point3f attenuation)
Sets this Light's current attenuation values and places it in the parameter specified. The three values specified in
the Point3f object specify the constant, linear, and quadratic coefficients, respectively.
2
1
distance quadratic distance linear constant
n attenuatio
+ +
=
where distance is measured from the light source to the vertex being shaded.
void setAttenuation(float constant, float linear, float quadratic)
Sets this Light's current attenuation values and places it in the parameter specified. See the above equation.
void setPosition(Point3f position)
Set light position.
void setPosition(float x, float y, float z)
Set light position.
PointLight Capabilities Summary
In addition to the Capabilities inherited from Light (listed on page 6-11), PointLight objects have the following
Capabilities.
ALLOW_POSITION_READ | WRITE
ALLOW_ATTENUATION_READ | WRITE
Like DirectionalLights, PointLights only participate in diffuse and specular reflection portions of the
lighting model. For diffuse and specular reflections, the geometry is a factor. Varying the location of a
PointLight object will change the shading of visual objects in a scene.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-15
6.3.4 Spot Light
SpotLight is a subclass of PointLight. SpotLight class adds direction and concentration to the position and
attenuation parameters of PointLight. SpotLight objects model man-made light sources such as flash
lights, lamps, and other sources with reflectors and/or lenses.
The intensity of light produced from a SpotLight source produces light within a specified spread angle from
the direction of the light. If the vertex lies outside the spread angle of the light, then no light is produced.
Inside the spread angle, the intensity varies by the angle and distance to the vertex. Again, a quadratic
equation models the attenuation due to distance. The concentration parameter and a different equation
governs the variation of intensity due to angle. The equations governing these relationships are found in
Section E.2 of The Java 3D API Specification. Figure 6-14 illustrates in 2D how light intensity varies
from a PointLight source in 3D.
spreadAngle
Out side t he
spread angle,
no light is
produced
I nside t he
spread angle,
light int ensit y
depends on
t he angle and
dist ance t o
t he vert ex
direction of SpotLight
a vertex
angle to
vertex
Figure 6-14 Light Intensity Varies with Distance and Orientation for a PointLight Source.
The spread angle of a SpotLight object may cause the light to illuminate part of a visual object. This is the
only light capable of lighting part of a visual object.
The following two reference blocks list the constructors and methods of PointLight, respectively.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-16
SpotLight Constructor Summary
SpotLight is a subclass of a point light object with the addition of direction, spread angle, and concentration
attributes.
SpotLight()
Constructs and initializes a spot light source using the following default values:
lightOn true
color (1, 1, 1)
position (0, 0, 0)
attenuation (1, 0, 0)
direction (0, 0, -1)
spreadAngle PI (180 degrees)
concentration 0.0
SpotLight(Color3f color, Point3f position, Point3f attenuation, Vector3f
direction, float spreadAngle, float concentration)
Constructs and initializes a spot light. See the PointLight Method Summary on page 6-14 for information on
attenuation. By default the light is on.
SpotLight(boolean lightOn, Color3f color, Point3f position, Point3f
attenuation, Vector3f direction, float spreadAngle, float concentration)
Constructs and initializes a spot light. See the PointLight Method Summary on page 6-14 for information on
attenuation.
SpotLight Method Summary
See the PointLight Method Summary on page 6-14, and the Light Method Summary on page 6-10 for more
methods.
void setConcentration(float concentration)
Set spot light concentration.
void setDirection(float x, float y, float z)
Set light direction.
void setDirection(Vector3f direction)
Sets the light's direction.
void setSpreadAngle(float spreadAngle)
Set spot light spread angle.
SpotLight Capabilities Summary
In addition to the Capabilities inherited from Light (listed on page 6-11), SpotLight objects have the following
Capabilities.
ALLOW_SPREAD_ANGLE_READ | WRITE
ALLOW_CONCENTRATION_READ | WRITE
ALLOW_DIRECTION_READ | WRITE
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-17
Like DirectionalLight and PointLight objects, SpotLights only participate in diffuse and specular reflection
portions of the lighting model. For diffuse and specular reflections, the geometry is a factor. Changing the
location or orientation of a SpotLight source changes the shading of the vertices within the light's region of
influence.
6.3.5 Applications of Light Sources
With all of the types of light sources, and variety of ways to use them, I will give a little guidance on their
typical use in this section. In general, you want to use as few light sources as you can for a given
application. How many is enough will vary depending on the lighting effect desired for the application.
The number of lights and the setting of attributes is much more an artistic consideration than a scientific
one.
From an artistic point of view, it is often sufficient to have only two lights for a given scene. One light
provides the main lighting, the other is used to fill in the darker side of the objects. The main light is
typically positioned to the viewer's right, the fill to the viewer's left. Again, these are simply general
guidelines for what can be a complex artistic design.
Including Directional light sources is preferred for most applications since the computation required in
rendering is significantly less than for point and spot lights. Point light sources are rarely used due to the
high computational complexity.
Including a single Ambient light source with a large region of influence is normal. This will light the
backsides of objects (like the "dark side of the moon"). The default color will work reasonably well. The
time required to include the Ambient light is small compared to other light sources. Leaving out an
Ambient light may be very noticeable in some scenes, and not noticed at all in other scenes.
6.3.6 Examples of Lighting
The interaction of light with objects is very complex in nature. Even in the virtual world where the lighting
model is less complex, the light sources are simplistic, and the surfaces are less detailed, the effect of a light
source on a visual object is rather complex. This section presents a few lighting examples to help clarify
the characteristics, capabilities, and limitations of the lighting model in Java 3D.
Two Colored Lights
Figure 6-15 shows a single white sphere illuminated by two directional light sources, one red and one blue.
Although it may surprise you, the resulting shade is magenta. Mixing red and blue watercolor results in
purple, which is the result in the subtractive color system. Mixing red and blue light results in magenta, the
results of an additive color system.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-18
Figure 6-15 Spheres Lit by Two Directional Light Sources
In the absence of light, the sphere is black. If the only light source is red, then the sphere appears red, or
some shade of red. In adding a blue light source, only red, blue, and mixtures of red and blue are possible.
Different Lighting Patterns
The next application illustrates the differences among light sources. In LightsNPlanesApp.java
three planes are lit by one light source each. From left to right, DirectionalLight, PointLight, and
SpotLight objects light the planes. Figure 6-16 shows the image rendered by this application.
Figure 6-16 Planes Lit by Directional, Point, and Spot Light Sources (best viewed in color).
The DirectionalLight illuminates the plane evenly. The PointLight, located directly above the upper edge of
the center plane, illuminates the center plane unevenly due to the variable direction of light with respect to
the normals, and, to a lesser extent, attenuation of the light. The SpotLight, also located directly above the
center of its plane, only illuminates a small part of the third plane.
Figure 6-17 illustrates the geometry involved in the lighting of the first two planes. In the left illustration,
the constant light vectors of the DirectionalLight source in combination with the constant normal vectors of
a plane results in constant reflection vectors, and even illumination of the plane. In the right illustration the
variable light vectors of the PointLight source combine with the constant normal vectors of the plane
resulting in various directions for reflection vectors, and uneven illumination of the plane. The SpotLight is
a special case of the PointLight source where the influence of the light source is limited by the spread angle.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-19
DirectionalLight source
constant direction light vectors
Plane
constant
surface normal
constant
direction
reflection
vectors
PointLight source
variable direction light vectors
plane
constant
surface normal
variable
direction
reflection
vectors
Figure 6-17 Geometry of Lighting Planes with Directional and Point Light Sources
Concentration and Spread Angle of SpotLights
Figure 6-18 shows images rendered from two different versions of the ConcentrationApp.java
program. One plane is lit by nine spot lights in the program. The spread angle and concentration values
for the spot lights vary by position. The spread angle varies by row with values of .1, .3. and .5 (radians)
for the upper to lower row, respectively. The concentration varies by column with values of 1.0, 50.0, and
100.0 for the left to right columns, respectively.
The concentration values have no effect for the upper row, the spread angle is the only factor. On the
lower row, the concentration has an effect for each of the spread angles. The blue in the images is the
diffuse color of the material.
Figure 6-18 A Plane Lit by SpotLights with Different Concentrations and Spread Angles.
ConcentrationApp demonstrates two limitations of the lighting model. The first being the rendering
artifacts shown in Figure 6-18. Similar artifacts are visible in Figure 6-16. The uneven lighting patterns
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-20
for both the green and red planes is due to the small number of vertices used to represent the planes. Recall
the lighting model is only applied per vertex. So the more vertices, the smoother the lighting effect and the
longer it will take to render.
The difference in the left and right images of Figure 6-18 is due to the difference in the number of vertices
used to represent the plane. The version of the program that generated the left image used 16 times more
vertices than the one on the right (2,500 vertices versus 40,000). The artifacts in the right image is a result
of the reduction of vertex density on the surface and the triangulation imposed by the Java 3D rendering
system.
Limit on the Number of Lights
The second limitation demonstrated in ConcentrationApp is not seen in the rendering. The plane in
ConcentrationApp is really four plane objects next to each other. This was done to overcome a potential
limitation of underlying rendering system. The OpenGL specification only requires support for eight
simultaneous light sources
6
. If the plane in ConcentrationApp were one visual object, then OpenGL would
limit the number of lights to eight for some machines.
Using the influencing bounds to pick only the relevant light sources for a visual object, Java 3D
dynamically creates light specifications for lights as visual objects are rendered. As long as no single
object is lit by more than eight lights, Java 3D programs are not limited in the number of lights in a virtual
world.
So in providing four smaller planes and the appropriate bounds to ensure that no plane is influenced by
more than eight lights in the example, it appears there are nine lights (actually ten, with the ambient light)
illuminate one plane. It takes a little more programming, but the resulting program is more portable.
While many implementations of OpenGL support more than eight simultaneous lights, if you plan
distribute your programs, you should be aware of this potential limitation.
In this section, a few examples show some of the characteristics and limitation of lighting in Java 3D. The
intention of this section is to give readers basic usage examples and some example figures to compare to
their own programs. It is not possible to provide examples of every possible lighting situation, as the
factors in rendering are too varied.
One last thing, the point and spot light support the specification of attenuation. The attenuation is specified
by the constant terms in the inverse quadratic equation based on the distance between the light and the
vertex (see the reference block on page ). Finding the appropriate attenuation for a specific application is
an artistic issue. No attenuation example programs are included in this tutorial.
6.4 Material Object
The material properties of a visual object are specified in the Material object of an appearance bundle.
Material is a subclass of NodeComponent. Figure 6-19 shows the Java 3D API hierarchy for Material.
6
As you should be aware, the Java 3D API uses low level graphics systems for rendering (currently OpenGL or
DirectX). The limitations of a particular low level graphics system may affect the results of a Java 3D program.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-21
java.lang.Object
javax.media.j3d.SceneGraphObject
javax.media.j3d.NodeComponent
javax.media.j3d.Material
Figure 6-19 API Hierarchy for Material
The Material object specifies ambient, diffuse, specular, and emissive colors and a shininess value. Each
of the first three colors are used in the lighting model to calculate the corresponding reflection. The
emissive color allows visual objects to "glow in the dark". The shininess value is only used in calculating
specular reflections.
The following two reference blocks list the constructors and methods for Material.
Material Constructor Summary
The Material object defines the appearance of an object under illumination.
Material()
Constructs and initializes a Material object using the following default values:
ambientColor (0.2, 0.2, 0.2)
emissiveColor (0, 0, 0)
diffuseColor (1, 1, 1)
specularColor (1, 1, 1)
shininess 0.0
Material(Color3f ambientColor, Color3f emissiveColor, Color3f diffuseColor,
Color3f specularColor, float shininess)
Constructs and initializes a new Material object using the specified parameters.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-22
Material Method Summary (partial list)
void setAmbientColor(Color3f color)
Sets this material's ambient color.
void setAmbientColor(float r, float g, float b)
Sets this material's ambient color.
void setDiffuseColor(Color3f color)
Sets this material's diffuse color.
void setDiffuseColor(float r, float g, float b)
Sets this material's diffuse color.
void setDiffuseColor(float r, float g, float b, float a)
Sets this material's diffuse color plus alpha.
void setEmissiveColor(Color3f color)
Sets this material's emissive color.
void setEmissiveColor(float r, float g, float b)
Sets this material's emissive color.
void setLightingEnable(boolean state)
Enables or disables lighting for visual objects referencing this appearance node component object.
void setShininess(float shininess)
Sets this material's shininess.
void setSpecularColor(Color3f color)
Sets this material's specular color.
void setSpecularColor(float r, float g, float b)
Sets this material's specular color.
java.lang.String toString()
Returns a String representation of this Materials values.
Material Capabilities Summary
In addition to the Capabilities inherited from NodeComponent, Material objects have the following Capability.
ALLOW_COMPONENT_READ | WRITE allows reading/writing of individual component field information.
6.4.1 Simple Material Examples
Specular reflections occur naturally with smooth objects. In general, the smoother a surface is, the more
defined and intense the specular reflection. When a surface is sufficiently smooth, it acts like a mirror
reflecting the light without changing the color of the light. Consequently, the specular color of an object is
normally white. Change the specular color of a material to alter the intensity of a specular reflection (e.g.,
Color3f(0.8f, 0.8f, 0.8f)).
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-23
The shininess value controls the spread range of viewing angle for which a specular reflection can be seen.
Higher shininess values result in smaller specular reflections. Figure 6-20 shows nine different spheres
illuminated by one light source. Each sphere has a different shininess value.
Figure 6-20 Different Material Properties
A Material object is associated with a visual object through an Appearance object much the same way
appearance attributes objects are. The setMaterial() method of Appearance class references a
Material object for that Appearance object. Refer to Code Fragment 6-1 (lines 1-4) for an example.
6.4.2 Geometry color, ColoringAttributes, and Material Properties
There are three ways to specify color for a visual object: per-vertex color specified in the geometry with
getColor() methods (Section 2.5.1), ColoringAttributes of an Appearance node (Section 2.6.3), and
Material Object (Section 6.3). Java 3D allows you to create visual objects using none, some, or all three of
the ways to specify color.
When more than one color specification has been made, two simple rules determine which color
specification takes precedence.
Material color is only used when rendering lit objects and ColoringAttributes color is only used
when rendering unlit objects.
Per-vertex geometry color always takes precedence over ColoringAttributes or Material color.
The rules may be clearer when the problem is divided into lit and unlit objects. Lighting in enabled for an
object when a Material object is referenced. Conversely, when no Material object is associated with the
visual object, lighting is disabled for that object. Note that a scene may have both lit and unlit objects.
When lighting is enabled for an object (i.e., a Material object is referenced), Material color or per-vertex
Geometry color is used in shading. If present, per-vertex color overrides the diffuse and ambient Material
colors. Note that the ColoringAttributes color is never used for lit objects. Table 6-1 summarizes the
relationships.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-24
Table 6-1 Coloring for Objects when Lighting is Enabled (Material object is referenced)
per-vertex Geometry color ColoringAttributes color Result
NO NO Material color
YES NO Geometry color
NO YES Material color
YES YES Geometry color
When lighting is disabled for an object (i.e., a Material object is not referenced), ColoringAttributes color
or per-vertex color is used for coloring. If present, per-vertex Geometry color overrides the
ColoringAttributes color. Table 6-2 summarizes the relationships.
Table 6-2 Coloring for Objects when Lighting is Disabled (no Material object is referenced)
per-vertex Geometry color ColoringAttributes color Result
NO NO flat white
YES NO Geometry color
NO YES ColoringAttributes
YES YES Geometry color
6.5 Surface Normals
As mentioned in Section 6.2, normals are required for shaded visual objects. When creating visual objects
using Geometry classes, use one of the setNormal() methods from Section 2.5.1 of Module 1 to
specify per vertex normal vectors.
The NormalGenerator included with the Java 3D utilities generates normals when specifying visual objects
using GeometryInfo objects. To generate normals, put your visual object geometry into a GeometryInfo
object and call NormalGenerator.generateNormals().
Geometric primitives generate their own normals when specified. Refer to Section 2.3.8 of Module 1 for
more information.
No matter how the normals are specified (or generated), only one normal is specified per vertex. This leads
to some interesting problems. For example, when both surfaces of polygons are viewable, the normal is
only correct for one of the surfaces. The result is for the back faces to be rendered (if they are rendered)
only using the ambient material properties. Both the diffuse and specular reflections require proper normal
specification.
This common problem is solved by specifying back face normals as the inverse of the front face normals.
(See Section 2.6.4 of Module 1 for a discussion of front and back faces.) Use the
setBackFaceNormalFlip() method of a PolygonAttributes object for this purpose.
Figure 6-21 shows two images of the shaded twist strip. The left image was rendered with front facing
normals only, the right with back face flipped normals.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-25
Figure 6-21 Twist Strip with (left) and without (right) Back Face Flip Normals (best viewed in color)
When a vertex is shared by surfaces of widely varying orientations, having only one normal per vertex can
result in problems. Consider the examples illustrated in Figure 6-22. The geometry illustrated on the left
hand side of Figure 6-22 shows the cross section of a surface where each polygon is oriented at a 90 angle
to its neighbors. If the normal is selected as the actual normal for one surface, it is very wrong for its
neighbor. If the normals are specified as shown, then the surface will be shaded consistently between
vertices with parallel normals. A similar problem occurs with the cube geometry shown on the right hand
side in Figure 6-22. The solution to both problems is to increase the number of vertices in order to increase
the number of normals. This, of course, increases memory usage and rendering time.
three possible normals for a vertex normals along a polygonal surface (cross-section)
Figure 6-22 Geometry with Normal Specification Problems
6.6 Specifying the Influence of Lights
In previous examples the specification of a light object's influencing bounds is accomplished through
referencing a Bounds object. This links the location of the influencing bounds with the location of the light.
(Section 6.2.2 explained how the transformations in the scene graph affect the bounding volumes used to
specify influencing bounds of lights.) While this makes it trivial to move lights together with the visual
objects they light, other applications need more flexible specification of the influence of lights. Fortunately,
the Java 3D API provides an alternative method for specifying the influencing bounds and a way to limit
the scope in addition to the bounds.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-26
6.6.1 Influencing Bounds Alternative: BoundingLeaf
A BoundingLeaf object is one alternative to an influencing bounds object. A BoundingLeaf object is
referenced by other leaf nodes to define a region of influence. As a descendant of SceneGraphObject,
instances of BoundingLeaf object are added to the scene graph. The BoundingLeaf object is subject to the
local coordinate system of its position in the scene graph, which could be independent of the coordinate
system of the light object. In other words, using a BoundingLeaf allows a light and its influencing bounds
to move independently.
A call to setInfluencingBoundingLeaf() for a light object specifies the BoundingLeaf argument
as the influencing bounds for the light. This specification overrides any regional influencing bounds
specification. A BoundingLeaf object can be shared by multiple light objects.
Figure 6-23 shows the scene graph diagram for an example application of a BoundingLeaf object with light
objects. In this scene, two lights are moved together using a TransformGroup object (on the right). These
lights could be instances of PointLight or SpotLight. However, the influence of these lights does not
change when the lights move. The influence of the lights moves when the left TransformGroup changes the
location of the BoundingLeaf object. Compare this scene graph diagram to the one in Figure 6-10.
BG
TG
L
Appearance
S
Geometry
L
BL
TG
Figure 6-23 Moving Light Objects Independently of Their Influence using a BoundingLeaf.
In Figure 6-10, if the light is moved it's region of influence moves. Also, as demonstrated in Figure 6-10,
the region of influence of two lights sharing the same Bounds object may or may not have the same region
of influence. When two or more lights share the same BoundingLeaf object, they always have the same
region of influence.
6.6.2 Scoping Limits Lights' Influence
A bounding region, whether a Bounds or a BoundingLeaf object, specifies the region of influence of a light
object. A specified scope can further limit the influence of a light to a portion of the scene graph. By
default, all lights have the scope of the virtual world in which it resides. Adding a scope specification
further reduces the influence of a light to the visual objects in the scene graph below the group(s) specified.
For example, consider the following application.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-27
Light Scoping Example
The scene consists of a lamp and some visual objects on a table. The lamp has a shade, so not all of the
objects, nor all of the table, should be lit by the lamp. The interior (but not the exterior) of the lamp shade
should be lit by the lamp as well (in this example, the lamp shade is fully opaque). We know that Java 3D
will not provide the occlusion for us. Using just a bounding volume, the influence of the light can be
controlled, but it could be very difficult, especially if the lit and unlit objects are near to each other, or
move.
Specifying scope limitations for the light allows you to control complex influence limitations more easily.
The only consideration is to keep the lit and unlit visual objects in separate parts of the scene graph. Your
initial thought might be to start building the scene graph with BranchGroups for the lit and unlit items, but
that is not often necessary nor recommended for most applications.
BG
TG
L
S
BG
TG
S
TG
S
TG
S
TG
S
TG
L
S
BG
TG
S
TG
S
TG
S
TG
S
lamp
lamp
lit box
lit box
shadow polygon
shadow polygon
unlit box unlit box
table table
lit group unlit group scene
Figure 6-24 Two Possible Scene Graphs for the Light Scoping Example.
The scene graph diagram on the left of Figure 6-24 shows a nave approach to scene graph construction.
The organization is not natural and will be difficult to manipulate in an animated application. For example,
if the table moves, the lamp and other objects should move with it. In the left scene graph, moving the table
(via TransformGroup manipulation) will not move the lamp or the lit box; only the unlit box moves with
the table.
The scene graph diagram on the right represents a more natural organization for the scene. The objects on
the table are children of the TransformGroup that positions the table. If the table moves (via
TransformGroup manipulation) the objects on the table move with it.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-28
The example scene is created in examples/light/LightScopeApp.java. Figure 6-25 shows
two images rendered from the example program. The left image uses light scoping to limit the influence of
the lamp light to the lamp and the lit box. The right image does not use scoping; therefore, the lamp light
illuminates the 'unlit box'.
The bright area under the lamp (not represented in either scene graph diagram) is a polygon placed just
above the table top. This bright polygon represents the part of the table that is lit by the lamp. The bright
area appears lighter than the rest of the table (even in the right image of Figure 6-9) because its normals are
more closely aligned with the point light of the lamp.
The shadow does not appear lit in either image of Figure 6-25 because its diffuse material property is
black. The shadow can be created through the use of scoping only if an additional group node is used in
the scene graph.
The shadow in this scene was created by hand. Techniques for automatically (even dynamically) creating
shadows are discussed in Section 6.7.1. Note that the techniques discussed in Section 6.7.1 may apply to
automatically creating the bright area of the table.
Figure 6-25 Light Scoping Example Scene With (left) and Without (right) Scoping of the Lamp Light.
Also not represented in either scene graph diagram are three additional light sources: two directional light
sources and an ambient light source. These are necessary to simulate the light of a natural scene (see
"Inter-object Effects Not Considered" subsection of section 6.1 on page 6-3, and Section 6.3.5).
The following reference block shows the methods of Light used to specify scoping limitations and the use
of BoundingLeaf objects to specify an influence bounds.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-29
Light Method Summary (partial list)
More Light class methods appear in Section 6.3 (page 6-9).
void addScope(Group scope)
Appends the specified scope to this node's list of scopes.
java.util.Enumeration getAllScopes()
Returns an Enumeration object of all scopes.
void insertScope(Group scope, int index)
Inserts the scope specified by the group node at the specified index location.
int numScopes()
Returns a count of this lights' scopes.
void removeScope(int index)
Removes the node's scope at the specified index location.
void setInfluencingBoundingLeaf(BoundingLeaf region)
Sets the Light's influencing region to the specified bounding leaf. Setting a BoundingLeaf overrides an influencing
bounds object.
void setScope(Group scope, int index)
Sets the Light's hierarchical scope at the index specified. By default, lights are scoped only by their region of
influence bounds.
One other benefit of using scopes to limit a light's influence: it may reduce rendering time. Calculating the
bounds intersection for a visual object with the influencing bounds of a light is more complex than
determining the scope of a light. Be aware that neither using influencing bounds nor scopes will limit a
light's influence to part of a visual object.
6.7 Creating Glow-in-the-Dark Objects, Shadows, and Other Lighting Issues
The previous sections cover the typical applications of lights in Java 3D applications. This section covers
some of the less used features and techniques.
6.7.1 Glow-in-the-Dark Objects
The Material object allows the specification of an emissive color. This can be used to create the effect of a
glow-in-the-dark object. Having an emissive color does not make the visual object a light source; it will not
illuminate other visual objects. Emissive material is also useful in special applications, such as indicating a
special object or an object that has been picked (Chapter 5).
Figure 6-26 shows the scene from the light scoping example program where the unlit box has been given
emissive color (most noticeable in color). Compare this image to the left image of Figure 6-25. As you can
see, the use of emissive color only changes the visual object that has it. This example also demonstrates
that the effective use of emissive color, as with most of the lighting parameters, is more of an artistic than
programming problem.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-30
Figure 6-26 A Glow-in-the-Dark Object Example.
6.7.2 Computing Shadows
The complexity of computing shadows is so great it is not part of any real-time graphics system. The
complexity comes from computing whether or not light from a light source reaches a vertex. Every other
polygon from every other visual object must be considered in computing the answer.
Figure 6-27 Projecting the Shadow of a Visual Object to a Plane for One Light
Shadowing is much more complex in reality. Light sources are not purely directional nor perfect point
sources. Consequently, shadows do not have sharp edges. Ignoring reality, as we often do in graphics,
let's take a look at ways for simulating shadows.
6.7.3 Creating Shadows
There are two basic parts to simulating (or faking) shadows: computing where the shadows are, and
creating geometry (or textures) to serve as the shadow. There are several ways of computing the location
of shadow, but the details of the various shadowing techniques are beyond the scope of this tutorial. The
next two sections cover two general techniques for creating shadow content. Section 6.7.4 presents a
simple example program that calculates the position of shadows.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-31
Shadow Polygons
A polygon specified without material properties can be used as a shadow polygon, called a colored shadow
polygon. The color of the shadow polygon, specified by either geometry or with a ColoringAttributes
object, is chosen to appear as the object in shade. Shadow polygons specified in this way may look fake in
complex scenes.
Shadow polygons specified with material properties but outside of the influence of one or more light objects
are called shaded shadow polygons. Shaded shadow polygons shaded by light objects which influence it
which appear more realistic. Obviously, specifying a shaded shadow polygon is more complex than
specifying a colored shadow polygon.
No matter how a shadow polygon is specified, the position of the shadow polygon is just above, or in front
of, the polygon that is shadowed. While adding shadow polygons normally does not result in more
polygons to render (because of the occlusion of other polygons) it does create more objects in the virtual
universe which can degrade rendering performance.
Instead of creating shadow polygons, shadows can be created by changing the influence of lights to exclude
polygons 'in the shade'. Scoping of lights is particularly useful for this purpose. However, since influence
is determined on a per object basis, it can be complex to calculate how to subdivide visual objects which
are partially shaded.
Shadow Textures
As mentioned earlier, natural shadows are complex. A natural shadow rarely has a straight edge and a
constant shade. Texturing can be used to make more realistic shadows. There are two basic ways of using
texturing in creating shadows: applying texture to shadow polygons, or applying textures to visual objects.
Since texturing has not been covered yet (Chapter 7), and calculating shadow textures (even off-line) is
difficult (and beyond the scope of this tutorial) this is a subject left for another book.
Moving Object, Moving Shadows
Keep in mind that adding shadows to an application makes the application much more complex. For
example, when a cube with a shadow rotates, the shadow rotates and changes shape. For that matter,
moving lights make shadows move too. In either case, movement adds another level of complexity to the
programming of shadows.
6.7.4 Shadow Example Program
The program example/light/ShadowApp.java gives an example of how simple shadow polygons
can be created. The program defines a class to create the shadow polygons. The shadow class creates one
shadow polygon for each geometry given as input. Code Fragment 6-3 shows the SimpleShadow class
used to create shadow polygons in ShadowApp.java. Figure 6-28 shows the rendered scene with a
shadow.
1. public class SimpleShadow extends Shape3D {
2. SimpleShadow(GeometryArray geom, Vector3f direction,
3. Color3f col, float height) {
4.
5. int vCount = geom.getVertexCount();
6. QuadArray poly = new QuadArray(vCount, GeometryArray.COORDINATES
7. | GeometryArray.COLOR_3
8. );
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-32
9.
10. int v;
11. Point3f vertex = new Point3f();
12. Point3f shadow = new Point3f();
13. for (v = 0; v < vCount; v++) {
14. geom.getCoordinate(v, vertex);
15. shadow.set( vertex.x + (vertex.y-height) * direction.x,
16. height + 0.0001f,
17. vertex.z + (vertex.y-height) * direction.y);
18. poly.setCoordinate(v, shadow);
19. poly.setColor(v, col);
20. }
21.
22. this.setGeometry(poly);
23. }
Code Fragment 6-3 Shadow Class for Making Shadow Polygons.
A number of assumptions made in SimpleShadow class (to make it easy) limit the applications of this class.
SimpleShadow is limited in that it: only projects to planes, only considers one light, only does some
orientations, doesn't consider the dimensions of the plane it is projecting on to. Writing a general purpose
shadow calculation class is a significant undertaking.
Figure 6-28 Scene Produced by ShadowApp.java Demonstrating Automatic Shadowing in Java 3D
6.7.5 Advanced Topic: The Role of the View Object in Shading
The view (or views) associated with a scene graph plays a variety of roles in how a scene is rendered. This
section does not explain all of the roles of the View object. The Java 3D API Specification provides a
complete reference to the View class. This section only mentions two methods of the View class useful in
understanding the shading of visual objects.
As mentioned in the "Local Eye versus Infinite Eye Vectors" section (subsection of 6.1 on page 6-3), the
eye vector is constant by default. This is known as an infinite eye vector. That is, the scene is rendered as
if it were viewed from infinity. Having an infinite eye significantly reduces the rendering computation.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-33
However, the resulting image may look incorrect. Figure 6-29 shows images rendered from one scene
using an infinite eye and local eye viewing using different light sources.
___________________________________________________________________________________
(a)directional light, (b) directional light, (c) point light (d) point light
infinite eye local eye infinite eye local eye
_____________________________________________________________________________________________________________________________________________________________________________________________________________________
Figure 6-29 Infinite Eye Versus Local Eye Rendering with Directional and Point Light Sources.
To fully appreciate the images of Figure 6-29 you need to know the geometry of the scene. The scene is of
nine spheres in a planar organization. Each of the images are viewed with the same field of view from the
same position. The only variables are whether the light is a DirectionalLight or a PointLight, and whether
the eye is infinite or local. The DirectionalLight has direction (0, 0, -1), the PointLight is positioned at (0,
0, 1).
In Figure 6-29 images (a) and (c) are rendered with an infinite eye. In these images, the eye vectors are
constant, so the specular reflections are basically in the same position for each sphere. Images (b) and (d)
in Figure 6-29 are rendered with a local eye. The eye vectors vary in these images, so the specular
reflections are in different position for each sphere. Note also, the diffuse reflection (blue) on the sphere
varies with the light source only. The eye vector only plays a role in the specular reflection calculation.
Again, the infinite eye viewing feature is used to reduce computation, and therefore time, in rendering.
Image (a) of Figure 6-29 takes the least time to render and image (d) takes the most time. Images (b) and
(c) take about the same amount of time, which is less that the time for (d), but more that the time for (a).
The actual time for rendering varies with the system used. The difference is most pronounced on systems
that render in software.
View Method Summary (partial list, methods related to shading)
The View object contains all parameters needed in rendering a three dimensional scene from one viewpoint.
void setLocalEyeLightingEnable(boolean flag)
Sets a flag that indicates whether the local eye point is used in lighting calculations for perspective projections.
void setWindowEyepointPolicy(int policy)
Sets the view model's window eye point policy to one of: RELATIVE_TO_FIELD_OF_VIEW,
RELATIVE_TO_SCREEN, RELATIVE_TO_WINDOW
The View object can be gotten from a SimpleUniverse using the appropriate methods. Then the view object
can be manipulated as necessary as in the following example.
SimpleUniverse su = new SimpleUniverse(canvas);
su.getViewer().getView().setLocalEyeLightingEnable(true);
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-34
6.8 Chapter Summary
This chapter presents the Java 3D features for rendering objects using lights. Section 6.1 explains the
lighting model, gives a recipe for constructing lit scenes, and presents a simple example using a light.
Section 6.2 shows an example program consisting of a single sphere and two light sources. Section 6.3
provides details of the light classes available in the Java 3D API. Section 6.3.5 illustrates the differences
among the light source classes through several example programs. Section 6.4 shows the Material object
API interface. Section 6.5 discussed various aspects of creating surface normals for geometric content.
Section 6.6 presents advanced topics on specifying the influence of lights including scene graph hierarchical
scoping. Section 6.7 discusses advanced topics such as creating shadows. You are reading Section 6.8,
the chapter summary.
This chapter explains the classes which are shaded in the following Java 3D API class hierarchy diagram.
java.lang.Object
javax.media.j3d.SceneGraphObject
Node
Leaf
Light
AmbientLight
DirectionalLight
PointLight
SpotLight
NodeComponent
Material
Figure 6-30 Java 3D API Hierarchy for Classes Covered in this Chapter.
6.9 Self Test
1. Add a green DirectionalLight pointing up to the LitSphereApp to illustrate additive color mixing
with all three primary colors. Dont forget to add the light to the scene graph and set the influencing
bounds for the new light source object. Which two primary colors make yellow?
2. To learn more about the interaction between material colors and light colors, create a scene with red,
green, and blue visual objects. Light the objects with a single color light. What did you see? You may
use LitSpereApp.java or MaterialApp.java as a starting point.
Module 3: Lights and Textures Chapter 6. Lights
Getting Started with the Java 3D API 6-35
3. Using LightScopeApp.java as a starting point (see Section 6.6.2), change the program to create the
shadow of the lit box through the use of scoping only.
4. Using ShadowApp.java as a starting point, find situations where the shadow polygon produced by
SimpleShadow is not correct, then fix SimpleShadow to make it work. (You could spend many
hours working on this.)
tutorial v1.5 (Java 3D API v1.1.2)
Getting Started with
the Java 3D
API
Chapter 7
Textures
Dennis J Bouvier
K Computing
Getting Started with the Java 3D API Chapter 7 Textures
The Java 3D Tutorial
1999 Sun Microsystems, Inc.
2550 Garcia Avenue, Mountain View, California 94043-1100 U.S.A
All Rights Reserved.
The information contained in this document is subject to change without notice.
SUN MICROSYSTEMS PROVIDES THIS MATERIAL "AS IS" AND MAKES NO WARRANTY OF ANY
KIND, EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS SHALL
NOT BE LIABLE FOR ERRORS CONTAINED HEREIN OR FOR INCIDENTAL OR CONSEQUENTIAL
DAMAGES (INCLUDING LOST PROFITS IN CONNECTION WITH THE FURNISHING, PERFORMANCE
OR USE OF THIS MATERIAL, WHETHER BASED ON WARRANTY, CONTRACT, OR OTHER LEGAL
THEORY).
THIS DOCUMENT COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS.
CHANGES ARE PERIODICALLY MADE TO THE INFORMATION HEREIN; THESE CHANGES WILL BE
INCORPORATED IN NEW EDITIONS OF THE PUBLICATION. SUN MICROSYSTEMS, INC. MAY MAKE
IMPROVEMENTS AND/OR CHANGES IN THE PRODUCT(S) AND/OR PROGRAM(S) DESCRIBED IN THIS
PUBLICATION AT ANY TIME.
Some states do not allow the exclusion of implied warranties or the limitations or exclusion of liability for incidental
or consequential damages, so the above limitations and exclusion may not apply to you. This warranty gives you
specific legal rights, and you also may have other rights which vary from state to state.
Permission to use, copy, modify, and distribute this documentation for NON-COMMERCIAL purposes and without
fee is hereby granted provided that this copyright notice appears in all copies.
This documentation was prepared for Sun Microsystems by K Computing (530 Showers Drive, Suite 7-225,
Mountain View, CA 94040, 770-982-7881, www.kcomputing.com). For further information about course
development or course delivery, please contact either Sun Microsystems or K Computing.
Java, JavaScript, Java 3D, HotJava, Sun, Sun Microsystems, and the Sun logo are trademarks or registered
trademarks of Sun Microsystems, Inc. All other product names mentioned herein are the trademarks of their
respective owners.
Module 3: Lights and Textures
The Java 3D Tutorial 7-i
Table of Contents
Chapter 7:
Textures..................................................................................................................................................... 7-1
7.1 What is Texturing.......................................................................................................................... 7-1
7.2 Basic Texturing............................................................................................................................. 7-2
7.2.1 Simple Texturing Recipe....................................................................................................... 7-3
7.2.2 Simple Texture Example Programs....................................................................................... 7-6
7.2.3 More about Texture Coordinates .......................................................................................... 7-8
7.2.4 A Preview of Some Texturing Choices............................................................................... 7-11
7.2.5 Texture Options................................................................................................................... 7-11
7.2.6 Texture3D ........................................................................................................................... 7-14
7.3 Some Texturing Applications ..................................................................................................... 7-14
7.3.1 Texturing Geometric Primitives.......................................................................................... 7-14
7.3.2 Texturing Lines ................................................................................................................... 7-15
7.3.3 Using Text2D Textures ....................................................................................................... 7-16
7.4 Texture Attributes ....................................................................................................................... 7-16
7.4.1 Texture Mode...................................................................................................................... 7-17
7.4.2 Texture Blend Color............................................................................................................ 7-18
7.4.3 Perspective Correction Mode.............................................................................................. 7-18
7.4.4 Texture Map Transform...................................................................................................... 7-19
7.4.5 TextureAttributes API......................................................................................................... 7-19
7.5 Automatic Texture Coordinate Generation................................................................................. 7-20
7.5.1 Texture Generation Format ................................................................................................. 7-21
7.5.2 Texture Generation Mode ................................................................................................... 7-21
7.5.3 How to use a TexCoordGeneration Object ......................................................................... 7-22
7.5.4 TexCoordGeneration API ................................................................................................... 7-23
7.6 Multiple Levels of Texture (Mipmaps)....................................................................................... 7-24
7.6.1 What is Multi Level Texturing (MIPmap) .......................................................................... 7-25
7.6.2 Multiple Levels of Texture Examples................................................................................. 7-27
7.6.3 Multiple Levels of Texture Minification Filters ................................................................. 7-28
7.6.4 Mipmap Mode..................................................................................................................... 7-29
7.7 Texture, Texture2D, and Texture3D API ................................................................................... 7-29
7.7.1 Minification and Magnification Filters.............................................................................. 7-29
7.7.2 Texture API ......................................................................................................................... 7-30
7.7.3 Texture2D API .................................................................................................................... 7-31
7.7.4 Texture3D API .................................................................................................................... 7-32
7.8 TextureLoader and NewTextureLoader API .............................................................................. 7-33
7.8.1 TextureLoader API.............................................................................................................. 7-33
7.8.2 NewTextureLoaderAPI ....................................................................................................... 7-34
7.9 Chapter Summary........................................................................................................................ 7-35
7.10 Self Test ...................................................................................................................................... 7-35
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-ii
List of Figures
Figure 7-1 Some of the Images (outlined) used as Textures in Example Programs. ................................ 7-2
Figure 7-2 Simple Texturing Recipe......................................................................................................... 7-3
Figure 7-3 Texture Mapping Coordinates................................................................................................. 7-5
Figure 7-4 The Orientation of Texture Coordinates in Texture Image Space. ......................................... 7-6
Figure 7-5 Scenes Rendered by the SimpleTextureApp (left) and SimpleTextureSpinApp
(right) programs. ............................................................................................................................... 7-7
Figure 7-6 Three Textured Planes as Rendered By TexturedPlaneApp.java ........................................... 7-8
Figure 7-7 Picture of Texture Mapping .................................................................................................... 7-9
Figure 7-8 Some of the Possible Orientations for a Texture on a Plane. .................................................. 7-9
Figure 7-9 In Texturing, You Get What You Ask For. ........................................................................... 7-10
Figure 7-10 An Appearance Bundle with Texture and TextureAttributes Components. ....................... 7-11
Figure 7-11 Comparing the Combinations of Boundary Mode Settings for a Textured Plane............... 7-12
Figure 7-12 Image Produced by BoundaryColorApp. ............................................................................ 7-13
Figure 7-13 Texturing the Sphere Geometric Primitive. ........................................................................ 7-15
Figure 7-14 Textured Lines in Java 3D................................................................................................... 7-16
Figure 7-15 The Texture of a Text2D Object Applied to Another Visual Object.................................. 7-16
Figure 7-16 Two Visual Objects Sharing a Texture Customized by TextureAttributes Components. .. 7-17
Figure 7-17 Comparing Generation Modes of the TexCoordGeneration Object. .................................. 7-22
Figure 7-18 Appearance Bundle with Texture, TextureAttributes, and TexCoodGeneration................ 7-23
Figure 7-19 Multiple Levels of a Texture (outlined). (Image Sizes: 128x128, 64x64, 32x32, , 1x1)7-26
Figure 7-20 The Image Generated for a Plane Textured with a Multi Color Mipmap Texture.............. 7-26
List of Reference Blocks
GeometryArray Method setTextureCoordinate ........................................................................................ 7-5
Appearance setTextureAttributes method............................................................................................... 7-17
TextureAttributes Constructor Summary................................................................................................ 7-19
TextureAttributes Constants ................................................................................................................... 7-19
TextureAttributes Method Summary ...................................................................................................... 7-20
TextureAttributes Capabilities Summary................................................................................................ 7-20
Appearance setTexCoordGeneration method ......................................................................................... 7-23
TexCoordGeneration Constructor Summary .......................................................................................... 7-23
TexCoordGeneration Field Summary..................................................................................................... 7-24
TexCoordGeneration Method Summary................................................................................................. 7-24
TexCoordGeneration Capabilities Summary.......................................................................................... 7-24
Texture Field Summary........................................................................................................................... 7-30
Texture Method Summary ...................................................................................................................... 7-31
Texture Capabilities Summary................................................................................................................ 7-31
Texture2D Constructor Summary........................................................................................................... 7-32
Texture3D Constructor Summary........................................................................................................... 7-32
Texture3D Method Summary.................................................................................................................. 7-33
TextureLoader Field Summary ............................................................................................................... 7-33
TextureLoader Constructor Summary (partial list)................................................................................. 7-33
TextureLoader Method Summary........................................................................................................... 7-34
NewTextureLoader Constructor Summary (partial list) ......................................................................... 7-34
NewTextureLoader Method Summary (partial list)................................................................................ 7-34
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-iii
List of Tables
Table 7-1 How Texture Format Affect Pixels ........................................................................................ 7-14
Table 7-2 Summary of Texture Modes ................................................................................................... 7-18
Table 7-3 Directory of Texture Features................................................................................................. 7-29
List of Code Fragments
Code Fragment 7-1 Using a TextureLoader Object to Load the STRIPE.GIF Image File. ...................... 7-4
Code Fragment 7-2 Creating an Appearance with a Texture.................................................................... 7-4
Code Fragment 7-3 Applying Texture Coordinates to a Quad. ................................................................ 7-6
Code Fragment 7-4 Adding Three New TexturedPlane Objects to the Scene Graph............................... 7-8
Code Fragment 7-5 Texture Coordinate Assignments for Planes in TextureRequestApp. .................... 7-10
Code Fragment 7-6 Creating a Sphere Primitive with Pre-Assigned Texture Coordinates.................... 7-14
Code Fragment 7-7 Creating an Appearance Bundle to Display the Lines of a Geometry Array. ......... 7-15
Code Fragment 7-8 Creating Multiple Level Texturing from a Base Level Image Only. ...................... 7-27
Code Fragment 7-9 Multiple Levels of Texture Loaded from Individual Image Files........................... 7-28
Preface to Chapter 7
This document is one part of a tutorial on using the Java 3D API. You should be familiar with Java 3D
API basics to fully appreciate the material presented in this Chapter. Additional chapters and the full
preface to this material is presented in the Module 0 document available at:
http://java.sun.com/products/java-media/3D/collateral
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-iv
Module 3: Lights and Textures
The Java 3D Tutorial 7-1
7
Textures
Chapter Objectives
After reading this chapter, youll be able to:
Add visual richness to simple geometry with textures
Load textures easily with the TextureLoader utility
Customize the use of textures with TextureAttributes objects
Automatically generate texture coordinates to simplify texturing
The appearance of many real world objects depends on its texture. The texture of an object is really the
relatively fine geometry at the surface of an object. To appreciate the role surface textures play in the
appearance of real world objects, consider carpet. Even when all of the fibers of a carpet are the same
color the carpet does not appear as a constant color due to the interaction of the light with geometry of
the fibers. Even though Java 3D is capable of modeling the geometry of the individual carpet fibers, the
memory requirements and rendering performance for a room size piece of carpet modeled to such detail
would make such a model useless. On the other hand, having a flat polygon of a single color does not
make a convincing replacement for the carpet in the rendered scene.
Up to this point in the tutorial, the detail of visual objects has been provided by the geometry. As a
result, visually rich objects, such as trees, can require a great deal of geometry which in turn requires the
appropriate memory and rendering computation. At some level of detail, the performance may become
unacceptable. This chapter shows how to add the appearance of surface detail to a visual object without
adding more geometry through the use of textures.
7.1 What is Texturing
Carpet may be the extreme example in terms of the complexity and density of the surface geometry, but it
is far from the only object for which we perceive texture. Bricks, concrete, wood, lawns, walls, and
paper are just some of the objects for which flat (non-textured) polygons do not visually represent well.
But, just like with carpet, the cost of representing surface texture in geometric primitives for these
objects would be quite high.
CHAPTER
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-2
A possible alternative to modeling the fiber of the carpet is to model the carpet as a flat polygon with
many vertices, assigning colors to the vertices to give variations in color. If the vertices are sufficiently
close, then the image of the carpet can be produced. This requires significantly less memory than the
model that includes the fibers of the carpet; however, the model would still require too much memory for
a reasonable size room. This idea, that of representing the image of the object on a flat surface, is the
basic idea of texturing. However, with texturing, the geometry can be very simple.
Texturing, also called texture mapping, is a way to add the visual richness of a surface without adding the
fine geometric details. The visual richness is provided by an image, also called a texture
1
, which gives
the appearance of surface detail for the visual object. The image is mapped on to the geometry of the
visual object at rendering time. Thus the term texture mapping.
Figure 7-1 shows some of the textures used in example programs for this chapter. As you can see from
this figure, a texture can provide the visual richness of objects of various sizes.
Figure 7-1 Some of the Images (outlined) used as Textures in Example Programs.
7.2 Basic Texturing
Texturing of polygons in a Java 3D program is achieved though creating the appropriate appearance
bundle and loading the texture image into it, specifying the location of the texture image on the geometry,
and setting texturing attributes. As you will see, specifying textures can be complex. Fortunately, there
are utility classes to help with the process and the default settings for texturing options are appropriate
for basic texturing applications.
To explain texturing, Section 7.2.1 presents a simple recipe; then Section 7.2.2 develops an example
program based on the recipe, further explaining texturing. The remaining subsections present additional
example programs to further explain details of texture specification. The texturing options not discussed
in the context of an example will be discussed with the API details in Section 7.7.
1
Even though texture images are referred to as 'textures' and they visually represent geometric structures, they are
neither representations of geometry nor do they alter the geometry of a visual object in any way.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-3
7.2.1 Simple Texturing Recipe
Due to the flexibility of texturing in the Java 3D API, the number of texturing related options can be a bit
bothersome. Even so, texturing need not be difficult. To make easy work of texture specifications,
follow the simple recipe of Figure 7-2.
The recipe only outlines the steps directly related to texturing. The reader should realize that the
geometry and appearance are set in a Shape3D object which is added to the scene graph. Previous
chapters of this tutorial, Chapters 1 and 2 in particular, cover the implied steps of the recipe
1. Prepare texture images
2a. Load the texture
2b. Set the texture in Appearance bundle
3. Specify TextureCoordinates of Geometry
Figure 7-2 Simple Texturing Recipe
As with several of the recipes in the tutorial, some steps of the recipe may be performed out of the order
they are presented. In fact, the steps of this recipe may be performed in any order (provided steps 2a and
2b are done together).
Texturing Step 1: Prepare the texture image
This recipe begins with a non-programming step: "prepare texture images. Creating and editing texture
images is something that is normally done external to Java 3D programs. In fact, most texture images are
prepared before the program is begun. There are two essential tasks in texture image preparation: 1.
ensuring the images are of acceptable dimensions, and 2. ensuring the images are saved in a file format
which can be read. Of course the image could be edited to achieve the desired color, transparency, and
tiling characteristics.
For rendering efficiency, Java 3D requires the size of the texture image to be a mathematical power of
two (1, 2, 4, 8, 16, ) in each dimension. Failing to meet this restriction will result in a runtime
exception.
If an image is not of acceptable dimensions, it must be modified (scaled or cropped) to meet the
dimension requirements before it is used. Image editing can be done in a wide variety of programs
including the Java Advanced Imaging API
2
. In Figure 7-1, the two smaller images are 128 by 128, the
tree is 256 by 128, and the earth is 256 by 256.
As far as the file formats are concerned, any file format can be used provided there is a method to load it.
The programs of this chapter load textures using the TextureLoader utility class (more information in the
next step, API details in Section 7.7). A TextureLoader object loads JPEG, GIF, and other file formats.
One more word about the example programs before moving to the next step. The code fragments and
example programs of this chapter use file names for some image files that are included in the example
programs jar. There is nothing special about these image files other than that they comply with the
power of two dimension restriction. Any image file can be used in the programs provided the images
have dimensions that are a power of two. Feel free to compile and run the example programs with your
own image files. Now, with texture images ready, the programming can begin.
2
The Java Advanced Imaging API (http://java.sun.com/products/java-media/jai) enables Java
programmers to easily create and edit 2D imagery.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-4
Texturing Step 2a: Load the Texture
The next step is to get the prepared image into an image object. This is known as loading the texture.
Textures can be loaded from files or URLs using the same basic process
3
. Loading a texture can be
accomplished with many lines of code, or with two lines of code that use a TextureLoader utility object.
Either way, the result is to get the image into a ImageComponent2D object. Code Fragment 7-1 shows an
example of two lines that use a TextureLoader. The result of these two lines is to load the image of the
file stripe.gif into a Image2DComponent object which can be used to create the necessary
appearance bundle of step 3.
1. TextureLoader loader = new TextureLoader("stripe.gif", this);
2. ImageComponent2D image = loader.getImage();
Code Fragment 7-1 Using a TextureLoader Object to Load the STRIPE.GIF Image File.
Before moving on to step 3 of the recipe, let's take a closer look at the use of the TextureLoader object.
The second argument of the constructor specifies an object which serves an the image observer. The
TextureLoader class uses the java.awt.image package for loading the images. This package loads
images asynchronously, which is particularly useful when an image is loaded from a URL. To facilitate
managing asynchronous loads of images, AWT components are capable of being image observers, which
is to observe the image load process. An image observer can be queried for the details of the image load.
For the purpose of writing Java 3D programs all that you need to know is that any AWT component can
serve as an image observer. Since Applet is an extension of the AWT component Panel, the Applet
object of a Java 3D program can be the image observer for the TextureLoader object. Further details on
image observers and other AWT topics is beyond the scope of this tutorial. Refer to an AWT reference
for more information.
Texturing Step 2b: Create the Appearance Bundle
To be used as a texture for a visual object, the texture image loaded in Step 2a must be set as the texture
in a Texture object, which is then used in an appearance bundle referenced by the visual object.
Specifically, a Texture2D
4
object holds the texture image. The ImageComponent2D image loaded in the
Step 2a is central to the appearance bundle creation of step 2b
5
.
Code Fragment 7-2 shows the two lines of code from Step 2a followed by the code to form a simple
texturing appearance bundle. Having loaded the texture (lines 1 and 2), the image is then set in the
Texture2D object (line 4). The Texture2D object is then added to the Appearance object (line 6).
1. TextureLoader loader = new TextureLoader("stripe.jpg", this);
2. ImageComponent2D image = loader.getImage();
3. Texture2D texture = new Texture2D();
4. texture.setImage(0, image);
5. Appearance appear = new Appearance();
6. appear.setTexture(texture);
Code Fragment 7-2 Creating an Appearance with a Texture.
3
Other sources for Textures include Text2D objects and procedurally created images.
4
There is a Texture3D object discussed in Section 7.7.4. The Texture3D object is used when a volume of color, or a
stack of images, is the texture.
5
The discussion of the image observer is a major reason why loading a texture (step 2a) is identified as a step
separate from the creation of the appearance bundle (step 2b).
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-5
The appearance bundle created in Code Fragment 7-2 could have other node components, most notably
of the possibilities is the TextureAttributes node component. For the simple example, no
TextureAttributes object is used. Section 0 discusses TextureAttributes.
Texturing Step 3: Specify TextureCoordinates
In addition to loading the texture into an appearance bundle, the programmer also specifies the placement
of the texture on the geometry through the specification of the texture coordinates. Texture coordinate
specifications are made per geometry vertex. Each texture coordinate specifies a point of the texture to
be applied to the vertex. With the specification of some points of the image to be applied to vertices of
the geometry, the image will then be rotated, stretched, squashed, and/or duplicated to make it fit the
specification
6
.
TextureCoordinates are specified in the s (horizontal) and t (vertical) dimensions of the texture image
space as shown in Figure 7-3. Figure 7-3 shows the texture coordinates in the texture image space.
0 1.0 s
t
1.0
0
Figure 7-3 Texture Mapping Coordinates
The reference block below shows just one of the GeometryArray methods available for setting texture
coordinates. Refer to Chapter 2 of this tutorial or the Java 3D API Specification for additional
setTextureCoordinate methods.
GeometryArray Method setTextureCoordinate
Texture coordinates are specified per vertex in the geometry via one of several setTextureCoordinate methods which
are methods of the GeometryArray class.
void setTextureCoordinate(int index, Point2f texCoord)
Sets the texture coordinate associated with the vertex at the specified index for this object.
Code Fragment 7-3 creates a single plane using a QuadArray geometry object. Texture coordinates are
assigned to each vertex. In Code Fragment 7-3, lines three through eleven establish the four corners of a
quad in 3-space. Lines 13 through 21 establish the texture's location on the geometry. This particular
code fragment creates a plane of 2 meters on a side and places the texture image in the normal (upright,
not reversed) orientation across the face of the plane.
6
Specifically, the texture coordinates are linearly interpolated from the vertices to map the texture to the geometry.
See Section 7.2.3 for more details.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-6
1. QuadArray plane = new QuadArray(4, GeometryArray.COORDINATES
2. | GeometryArray.TEXTURE_COORDINATE_2);
3. Point3f p = new Point3f();
4. p.set(-1.0f, 1.0f, 0.0f);
5. plane.setCoordinate(0, p);
6. p.set(-1.0f, -1.0f, 0.0f);
7. plane.setCoordinate(1, p);
8. p.set( 1.0f, -1.0f, 0.0f);
9. plane.setCoordinate(2, p);
10. p.set( 1.0f, 1.0f, 0.0f);
11. plane.setCoordinate(3, p);
12.
13. Point2f q = new Point2f();
14. q.set(0.0f, 1.0f);
15. plane.setTextureCoordinate(0, q);
16. q.set(0.0f, 0.0f);
17. plane.setTextureCoordinate(1, q);
18. q.set(1.0f, 0.0f);
19. plane.setTextureCoordinate(2, q);
20. q.set(1.0f, 1.0f);
21. plane.setTextureCoordinate(3, q);
Code Fragment 7-3 Applying Texture Coordinates to a Quad.
Figure 7-4 shows the relationship between the vertex coordinates and the texture coordinates for the
example quad created in Code Fragment 7-3. The left image of Figure 7-5 shows the application of the
stripe.gif texture to the example geometry.
v0 = (-1.0, 1.0, 0.0)
tc (0.0, 1.0)
v1 = (-1.0, -1.0, 0.0)
tc (0.0, 0.0)
v3 = (1.0, 1.0, 0.0)
tc (1.0, 1.0)
v2 = (1.0, -1.0, 0.0)
tc (1.0, 0.0)
Figure 7-4 The Orientation of Texture Coordinates in Texture Image Space.
Having now completed the three texturing steps, the textured object can be added to a scene graph. The
following section presents a series of example programs demonstrating some options in texturing.
7.2.2 Simple Texture Example Programs
Following the recipe of Figure 7-2, a simple texturing example program has been developed. A complete
example is found in SimpleTextureApp.java of the examples/texture directory in the
examples jar available with this tutorial. Figure 7-5 shows the scene rendered by SimpleTextureApp on
the left. This program appears as little more than an image display program.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-7
Figure 7-5 Scenes Rendered by the SimpleTextureApp (left) and SimpleTextureSpinApp
(right) programs.
Using a RotationInterpolator object
7
another example program, SimpleTextureSpinApp, was
created. In this program the same textured plane spins to demonstrate the 3D nature of the program.
Figure 7-5 shows a rendering from this program on the right. One thing to notice when viewing the
program, the back side of the plane is blank.
The NewTextureLoader Class
Java 3D programs using textures can have a large number of lines just for loading textures and creating
the appearance bundles. Some programming and, more importantly, runtime memory can be conserved
by sharing appearance bundles when appropriate. However, this does not reduce the amount of
programming a great deal. Further reductions in programming can be achieved by creating a class to
create the texture appearance bundles. The challenge in creating such a class lies in the image observer
requirement for the TextureLoader object.
The Canvas3D object or an Applet can server as the image observer, but having a reference to some
component everywhere in the program can be bothersome. To address this inconvenience, I have
extended the TextureLoader class eliminating the need for an image observer component. Instead a
single method is used to specify an image observer for all future uses of the texture loader.
The constructors for NewTextureLoader are the same as those for TextureLoader except none require a
image observer component. The methods for NewTextureLoader are those of TextureLoader with the
additional method for setting an image observer. See Section 7.8 for API information for both classes.
Another example program, TexturedPlaneApp, loads three textures and displays them on planes as
shown in Figure 7-6. The significance of this program is that the textures are loaded using the
TexturedPlane class defined external to the rest of the program which is more easily done with the
NewTextureLoader class. This TexturedPlane class is not flexible enough to be used in very many
applications, but serves as a demonstration for similar classes.
7
The interpolator code used is similar to that of the HelloJava3Dd example from Chapter 1. Interpolators are
explained in Chapter 5 of the tutorial.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-8
Figure 7-6 Three Textured Planes as Rendered By TexturedPlaneApp.java
Code Fragment 7-4 is an excerpt from TexturedPlaneApp and is nearly all the code required to
create the three textured planes of that application. The image observer object is provided to the
NewTextureLoader object of the TexturedPlane.
1. scene.addChild(tg0);
2. tg0.addChild(tg1);
3. tg1.addChild(new TexturedPlane("stripe.gif"));
4.
5. tg0.addChild(tg2);
6. tg2.addChild(new TexturedPlane("brick.gif"));
7.
8. tg0.addChild(tg3);
9. tg3.addChild(new TexturedPlane("earth.jpg"));
Code Fragment 7-4 Adding Three New TexturedPlane Objects to the Scene Graph.
7.2.3 More about Texture Coordinates
As mentioned in "Texturing Step 3: Specify TextureCoordinates" (page 7-5), the texture image is made
to fit the geometry based on the specification of the texture coordinates. The actual process is to map the
texels of the texture to the pixels of the geometry as it is rendered. Each pixel of a texture is called a
texel, or a 'texture element'. This is the process of texture mapping.
Texture mapping begins with the specification of texture coordinates for the vertices of the geometry. As
each pixel of textured triangle is rendered, the texture coordinates for the pixel is calculated from the
vertices of the triangle. Trilinear interpolation of the vertices' texture coordinates determine the texture
coordinates for the pixel and therefore, the texel of the texture image used in the final color of the pixel.
Figure 7-7 illustrates the process of trilinear interpolation for an example pixel. Rendering is done in
scanline order. The pixel, P, to texture map is roughly in the center of the current scanline in the triangle
on the left of the illustration. Texture coordinates have been assigned to each of the vertices of the
triangle. They are labeled TC1, TC2, and TC3. These texture coordinates are the starting point for the
trilinear interpolation (each of the linear interpolations are shown as two-headed arrows in the figure).
The first two linear interpolations determine the texture coordinates along the sides of the triangle at the
scanline (labeled points A and B in the figure). The third interpolation is done between these two points.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-9
The resulting texture coordinates for P are (0.75, 0.6). On the right of the figure is the texture. Using the
calculated texture coordinates for P the texel is selected.
0 1.0 s
t
1.0
0
TC1: (1.0, 1.0)
TC3: (1.0, 0.0)
(TC2: (0.0, 1.0)
A: (0.5, 1.0)
B: (1.0, 0.2)
P: (0.75, 0.6)
(1.0, 1.0)
(0.0, 1.0)
(1.0, 0.0)
scanline
Figure 7-7 Picture of Texture Mapping
Texel selection is not fully explained in the above example. The Specification of Filtering section (page
7-12) gives more details on texel selection. Another detail not yet explained is the interaction between
the texel color, other sources of color, and the final pixel color. The default mode is 'replace' in which
the texel color is used as the color of the pixel, but there are other modes as explained in Section 0.
Before moving on to other topics, further discussion of texture coordinates and mapping is in order.
To this point in the chapter all of the textures have been used in their ordinary orientation. Figure 7-8
shows planes with a few of the texture orientations possible just by setting the texture coordinates of the
vertices. The TextureCoordApp example program produces this image.
Figure 7-8 Some of the Possible Orientations for a Texture on a Plane.
You should note that in the TextureCoordinatesApp example program the stripe.gif texture is loaded only
once. Only one texture appearance bundle is created which is shared by all four textured planes. This is
possible because there is nothing in the texture bundle that is unique for any of the planes. Loading the
texture only once saves time and memory.
Of course, mistakes can be made in specifying the texture coordinates. When this happens, the Java 3D
rendering system does what is asked of it. When the texture coordinates are not specified for regularly
spaced mapping, then the triangulation of the geometry becomes obvious as the 'seams' of the texture will
occur along the edges of triangles.
Figure 7-9 shows the image rendered for textured planes where the texture coordinates are not specified
to make a uniform presentation of the texture. In the program that generates this image,
TextureRequestApp, there is only one texture bundle shared by the three visual objects. The
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-10
variations in the appearance of the planes is due only to the specification of the texture coordinates. This
is a rendering of the phrase "In texturing, you get what you ask for."
Figure 7-9 In Texturing, You Get What You Ask For.
This program shows some of the possible renderings for a plane using the same texture. The texture
assignments made in this program are examples of possible mistakes while all are legitimate applications.
The left-most image is an application of only a single row of texels the same texture coordinates are
assigned to pairs of vertices. The right-most image is the application of a single texel all four texture
coordinates are the same. The middle two images demonstrate the assignment of texture coordinates in
non-uniform ways. The change of the texture along the diagonal is due to the triangulation of the
polygon.
Code Fragment 7-5 shows the texture coordinate assignments made in TextureRequestApp. These
assignments used with the stripe.gif texture result in the images of Figure 7-9.
1. // texture coordinate assignments fof the first plane
2. texturedQuad.setTextureCoordinate(0, new Point2f( 1.0f, 0.0f));
3. texturedQuad.setTextureCoordinate(1, new Point2f( 1.0f, 0.0f));
4. texturedQuad.setTextureCoordinate(2, new Point2f( 0.0f, 0.0f));
5. texturedQuad.setTextureCoordinate(3, new Point2f( 0.0f, 0.0f));
6. // texture coordinate assignments for the second plane
7. texturedQuad.setTextureCoordinate(0, new Point2f( 0.0f, 1.0f));
8. texturedQuad.setTextureCoordinate(1, new Point2f( 1.0f, 0.5f));
9. texturedQuad.setTextureCoordinate(2, new Point2f( 0.5f, 0.5f));
10. texturedQuad.setTextureCoordinate(3, new Point2f( 0.0f, 1.0f));
11. // texture coordinate assignments for the third plane
12. texturedQuad.setTextureCoordinate(0, new Point2f( 1.0f, 0.0f));
13. texturedQuad.setTextureCoordinate(1, new Point2f( 1.0f, 1.0f));
14. texturedQuad.setTextureCoordinate(2, new Point2f( 0.0f, 0.0f));
15. texturedQuad.setTextureCoordinate(3, new Point2f( 1.0f, 1.0f));
16. // texture coordinate assignments for the forth plane
17. texturedQuad.setTextureCoordinate(0, new Point2f( 0.0f, 0.0f));
18. texturedQuad.setTextureCoordinate(1, new Point2f( 0.0f, 0.0f));
19. texturedQuad.setTextureCoordinate(2, new Point2f( 0.0f, 0.0f));
20. texturedQuad.setTextureCoordinate(3, new Point2f( 0.0f, 0.0f));
Code Fragment 7-5 Texture Coordinate Assignments for Planes in TextureRequestApp.
The complete source for the TextureRequestApp and TextureCoordApp example programs is
available in the examples jar available with the tutorial.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-11
7.2.4 A Preview of Some Texturing Choices
There is much more to texturing than just specifying the texture coordinates for the vertices of the
geometry. To this point, the discussion of texturing has not included any of the options available in
texture applications. For example, the Texture2D object can be configured for different boundary modes
and mapping filters. Section 7.2.5 presents these options. But there is even more than this.
Additional configuration of a texture is done through a TextureAttributes node component. Figure 7-10
shows a visual object with an appearance bundle with both Texture and TextureAttributes components.
Section 7.4 presents the details of the TextureAttributes components.
Appearance
S
Geometry
Texture TextureAttributes
Figure 7-10 An Appearance Bundle with Texture and TextureAttributes Components.
Other options in texturing are beyond the settings in Texture and TextureAttributes. For example, a
texture can be three dimensional. Section 7.7 presents the API for the Texture3D class, which, like
Texture2D, is an extension of the Texture class. Section 7.6 presents Multiple level textures, commonly
called MIPmaps, and their applications. Section 7.5 presents a utility for automatic texture coordinate
generation.
Since many of these options are intertwined in the API, the API details appear at the end of the chapter
after all of the various options have been discussed.
7.2.5 Texture Options
Texture2D, the class used in the previous examples, is an extension of Texture. Some of the basic
choices for texturing are implemented in the Texture class. Since Texture is an abstract class, your
settings will be made through either a Texture2D or Texture3D object. The settings are Boundary Mode,
Filters, and Texture Format.
Boundary Mode: Wrap or Clamp
In all of the previous programs, the textures have been mapped in such a way that one copy of the image
has been used to cover the plane. The issue of what to do when a texture coordinate is beyond the 0 to 1
range of the texture space was not addressed.
The boundary mode setting determines what mapping takes place when the texture coordinates go
beyond the 0 to 1 range of the image space. The choices are to wrap the image, or to clamp it.
Wrapping, which means to repeat the image as needed, is the default. Clamping the image uses the color
from the edge of the image anywhere outside of the 0 to 1 range. These settings are made independently
in the s and t dimensions.
In the BoundaryModeApp example program the texture is mapped onto approximately the middle
ninth of each of the planes. Figure 7-11 shows the scene as rendered by this program. The variations in
the images are due only to the setting of the boundary modes for the planes. From left to right the
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-12
settings are (s then t) WRAP and WRAP, CLAMP and WRAP, WRAP and CLAMP, and CLAMP and
CLAMP. Consult the source code of this example for specific details of this program. Section 7.7.2
presents the API for this topic in more detail.
Figure 7-11 Comparing the Combinations of Boundary Mode Settings for a Textured Plane.
Note that unlike the previous applications which share the same texture object among four visual objects,
the texture is loaded four times in this application. This is necessary since each of the texture objects has
different combinations of Boundary Mode settings.
Specification of Filtering
In the computation of texture coordinates for each pixel, rarely does a pixel map directly to just one texel.
Usually a pixel is either the size of multiple texels or smaller than one texel. In the former case a
magnification filter is used to map the multiple texels to one pixel. In the later case a minification filter
is used to map the texel or texels to the pixel. There are choices for how to handle each of these cases.
The magnification filter specifies what to do when a pixel is smaller than a texel. In this case the texture
will be magnified as it is applied to the geometry. Each texel will appear as several pixels and it is
possible for the resulting image to exhibit "texelization where the individual texels would be seen in the
rendering. The choices for magnification filter are to do point sampling, which is to select the nearest
texel and use its color, or to interpolate among neighboring texels. The point sampling, or nearest
neighbor sampling, filter usually has the least computational cost; while the linear interpolation sampling
typically costs more (in computation and therefore rendering time) but reduces the appearance of any
texelization
8
.
The minification filter specifies what to do when a pixel is larger than a texel. In this case the texels
must be "minified" (opposite of magnified) to fit the pixel. The problem lies in that a pixel can only have
one color value and yet several texels could supply the color. The choices for the minification filter are to
do point sampling, which is to select the nearest texel and use its color, or to interpolate among
neighboring texels.
It is not always clear which filter will be used. Consider a texture stretched in one direction but squashed
in another. Depending on which dimension is considered, a different filter would be picked. There is
nothing the programmer can do to determine which will be used. However, the runtime system usually
picks the filter that results in the better image.
The selection of a filter has other implications with respect to the use of the boundary color (next
section). Also, the minification filter choices are more complex when a multiple level texture is used.
Multi level texturing is discussed in Section 7.6. Section 7.7.1 gives the API details for filter settings.
8
Performance differences will vary significantly among different platforms.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-13
Boundary Color
The boundary mode behavior is further configurable by a boundary color. When the boundary mode is
CLAMP and boundary color is specified, the boundary color is used when texture coordinates are outside
of the 0 to 1 range. Only one boundary color can be specified so that one color is used in each dimension
for which the boundary mode is set to clamp. The example program BoundaryColorApp
demonstrates this feature.
In Figure 7-12 boundary colors are set for all four planes. The left most plane does not use its boundary
color as the boundary modes are both WRAP. For the next plane the black boundary color is used in the
vertical dimension only due to the boundary modes. You can see the blend between the blue and black
on the left; on the right side of the image the black boundary color blends with the white edge of the
texture. The boundary colors for the remaining two planes are green and red. Both boundary modes are
CLAMP for the rightmost plane in the image.
Figure 7-12 Image Produced by BoundaryColorApp.
Note that the Boundary Color is not used if the filter is BASE_LEVEL_POINT. For the Boundary Color
to be used, the filter needs to be at least BASE_LEVEL_LINEAR. The corollary is that anytime the
filter is not BASE_LEVEL_POINT the BoundaryColor will be used.
Also note that the same texture is loaded four times in this application. One texture object can not be
shared among the four planes in this application since each texture object is configured with a different
combination of Boundary Mode settings.
Texture Format
The last setting of the Texture class is that of the texture format. The texture format is both a statement
of how many values there are per texel and how those values effect pixels. For example, a texture format
setting of INTENSITY states that the single texel value will be used for red, green, blue, and alpha values
of the pixel. A texture format setting of RGB states that the three texel values will be used for red, green,
and blue values of the pixel while the alpha value of the pixel remains the same.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-14
Table 7-1 How Texture Format Affect Pixels
Texture Format values per texel modify pixel color modify pixel alpha
INTENSITY 1 yes, R=G=B yes, R=G=B=A
LUMINANCE 1 (color only) yes, R=G=B no
ALPHA 1 (alpha only) no yes
LUMINANCE_ALPHA 2 yes, R=G=B yes
RGB 3 yes no
RGBA 4 yes yes
The texture mode, or how the texel values are used to change the pixel value, is a setting of the texture
attribute object.
7.2.6 Texture3D
As the name implies, a Texture3D object holds a three dimensional texture image. You might think of it
as being a volume of color. The Texture3D class is an extension of Texture, so all of the features of the
Texture class as explained in the previous section (Section 7.2.5) applies to Texture3D. The only feature
that Texture3D has that Texture2D does not is a specification for the boundary mode in the third
dimension, or r dimension.
7.3 Some Texturing Applications
Believe it or not, there are many more texturing features to be discussed. However, you can use the
features already discussed in many applications. This section takes a break from discussing the details of
texturing to demonstrate two applications of texturing. One application is to apply a texture to a
geometric primitive (see Chapter 2). Another is to texture the lines of non-filled polygons. A third
application uses the texture created by a Text2D (see Chapter 3) object to another visual object.
7.3.1 Texturing Geometric Primitives
One way to simplify the process of presenting a texture is to use a geometric primitive. A flag can be
used to have texture coordinates automatically assigned when creating geometric primitives. Code
Fragment 7-6 shows the use of a constructor for a Sphere primitive with the coordinate generation.
1. objRoot.addChild(new Sphere(1.0f, Primitive.GENERATE_TEXTURE_COORDS, appear));
Code Fragment 7-6 Creating a Sphere Primitive with Pre-Assigned Texture Coordinates.
The line of Code Fragment 7-6 is used in the PrimitiveTextureApp example program. The
complete source for this application is available in the examples/texture subdirectory of the
example program jar distributed with this tutorial. This program textures the sphere with the
earth.jpg image, also in the examples jar, resulting in the image of Figure 7-13.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-15
Figure 7-13 Texturing the Sphere Geometric Primitive.
7.3.2 Texturing Lines
Polygons are not the only graphic elements that can be textured; lines can be textured too. The
TexturedLinesApp demonstrates using a 1-D texture to texture lines of a visual object. In this
application, the twisted strip visual object created in Chapter 2 is used. The only 'trick' to texturing the
lines is to create the appropriate appearance bundle to display the lines of the geometry and not filled
polygons. Code Fragment 7-7 shows the lines of code to add the PolygonAttributes component to an
appearance bundle to display lines.
1. PolygonAttributes polyAttrib = new PolygonAttributes();
2. polyAttrib.setCullFace(PolygonAttributes.CULL_NONE);
3. polyAttrib.setPolygonMode(PolygonAttributes.POLYGON_LINE);
4. twistAppear.setPolygonAttributes(polyAttrib);
Code Fragment 7-7 Creating an Appearance Bundle to Display the Lines of a Geometry Array.
A one dimensional texture is really a Texture2D object with one dimension (usually t) having size 1. For
the example program, the texture is 16 texels by 1 texel. Two dimensional texture coordinates are
assigned to the visual object. The t-value of every texture coordinate is set to 0.0f. However, any t-value
could be used and the result would be the same. Figure 7-14 shows the twisted strip
9
geometry displayed
as textured lines. The complete source code and texture for TexturedLinesApp appears in the
examples/texture subdirectory of the examples jar distributed with the tutorial.
9
The twisted strip geometry used in this example first appears in Chapter 2 of the tutorial.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-16
Figure 7-14 Textured Lines in Java 3D.
7.3.3 Using Text2D Textures
Text2D objects create textures of specified text and apply the texture to a polygon. This texture can be
easily accessed from the Text2D and applied to another visual object. Figure 7-15 shows the image
produced by Text2DTextureApp, a program in the examples jar, which applies the texture created by
the Text2D object shown in the background to geometry of another visual object as seen in the
foreground.
Figure 7-15 The Texture of a Text2D Object Applied to Another Visual Object.
7.4 Texture Attributes
Section 7.2 presented some of the options available in texturing. The TextureAttributes node component
allows further customization of the texturing. Texture attribute settings include the texture mode, blend
color, perspective correction mode, and a texture map transform. The default values for these settings are
REPLACE, black, FASTEST, and NONE, respectively. In addition, the setEnable method allows
enabling and disabling of texture mapping. Each of the settings are explained in this section.
One benefit of having texturing features controlled by a different node component is the ability to share a
texture among visual objects but still be able to customize it for each visual object. Figure 7-10 shows
two visual objects sharing a single texture object. Each of the visual objects customize the texture with
the TextureAttributes component in its appearance bundle.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-17
Appearance
S
Geometry
Texture TextureAttributes
Appearance
S
Geometry
TextureAttributes
Figure 7-16 Two Visual Objects Sharing a Texture Customized by TextureAttributes Components.
TextureAttributes objects are added to the scene graph as members of an appearance bundle. The
Appearance method is setTextureAttributes, as shown in the following reference block.
Appearance setTextureAttributes method
void setTextureAttributes(TextureAttributes textureAttributes)
Sets the textureAttributes object in an appearance object.
7.4.1 Texture Mode
To appreciate the role of the texture mode you must understand the sequence of operations involved in
determining the color of a pixel. Very simply stated, a pixel's non-texture color is calculated first, then
the texture is applied. The non-texture color is determined from geometry per-vertex color,
ColoringAttributes, or by the combination of material properties and lighting conditions. Just as there
are several ways to determine the non-texture color, there are several possible ways to combine the non-
texture color and the texture color.
The texture mode setting is a major factor in determining how the texel value (color and/or alpha) affects
the non-texture pixel color and alpha values. The actual texturing operation depends on the combination
of the texture format (see Section 7.2.5) and the texture mode. Refer to the Java 3D API Specification
(Appendix E) for more information.
The default texture mode is REPLACE, the other options are BLEND, DECAL, and MODULATE. Each
of the modes is described in the following subsections. Also note Table 7-2 (page 7-18) which
summarizes the texture modes.
Blend
In BLEND mode, the texture color blends with the non-texture color. The texture color determines the
amount of the non-texture color to use. The resulting transparency is the combination of the texture and
material transparency. This particular texture mode has the added flexibility of optionally including a
blend color. Section 7.4.2 for more information on blend color.
Decal
In DECAL mode, the texture color is applied as a decal on top of the non-texture color. The
transparency of the texture determines the amount of material color to use. The transparency of the pixel
is left unchanged. This is completely analogous to applying a decal to a real world object. The texture
format must be RGB or RGBA for DECAL texture mode.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-18
Modulate
In MODULATE mode the Texture color is combined with the non-texture color. The resulting
transparency is the combination of the texture and material transparency. Since the resulting color
depends on both the non-texture and the texture colors, this mode is useful in applying the same texture
to a variety of visual objects without having them all look the same. This mode is often used in lit
scenes.
Replace
In REPLACE mode the texture provides the color and transparency for the pixel, ignoring all other colors
except the specular color (if lighting is enabled). This is the default texture mode even when there is no
TextureAttributes component in the appearance bundle.
Texture Modes Summary
Table 7-2 gives summary information for each of the texture modes. This table is meant as a general
guide to understanding the variety of texture modes available. The actual color calculations are based on
a combination of texture mode and texture format
10
.
When lighting is enabled, the ambient, diffuse, and emissive color components are all affected by the
texture operation; specular color is not. The specular color is calculated normally based on material and
lighting conditions, then after the texture operation is applied to the other color components the
(untextured) specular color is added to the other colors yielding the final pixel color.
Table 7-2 Summary of Texture Modes
Texture Mode Pixel Color Derived From Determined By Application Hint
BLEND Texture color, non-texture, and optional
blend color
texture color lit scenes with blending
color
DECAL Texture color and non-texture color alpha of texture detailing a surface
MODULATE Texture color and non-texture color n/a lit scenes
REPLACE texture color only (default texture
mode)
n/a non-lit scenes
7.4.2 Texture Blend Color
The blend color is used in texturing only when the texture mode is BLEND. The resulting pixel color is
a combination of the texel color and the blend color. With the blend color the same texture can be
applied in a variety of shades to different visual objects. The blend color is expressed as an RGBA
value. The default blend color is (0,0,0,0) black with and alpha of 0.
7.4.3 Perspective Correction Mode
Texture mapping takes place in the image space. For this reason the textured planes may appear
incorrect when viewed from an edge. That is, they appear incorrect unless a perspective correction is
10
The actual texture operation may vary by implementation of Java 3D.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-19
made. In Java 3D the perspective correction is always made. The choice is how this perspective
correction is made.
The two options are FASTEST and NICEST. Obviously, the choice is the classic speed versus image
quality tradeoff. For this option, the default setting is NICEST.
7.4.4 Texture Map Transform
Within the Texture Attributes component a Transform3D object can be specified to alter the texture
mapping function. This texture map transform can be used to move a texture on a visual object at run
time. The transform translates, rotates, and scales texture coordinates (s,t,r) before the texels are selected
from the texture image.
A translation in the texture transform would slide the texture across the visual object. A rotation
transformation could be used to reorient the texture on a visual object. A scale transformation can be
used to repeat the texture across a visual object. Of course, since a transform object can contain a
combination of these, the texture can be animated on a visual object by manipulating the texture
transform.
7.4.5 TextureAttributes API
The following reference blocks list the constructors, methods, and capabilities of the Texture Attributes
node component.
TextureAttributes Constructor Summary
extends: NodeComponent
The TextureAttributes object defines attributes that apply to texture mapping. See the following reference block for
a list of texture mode and perspective correction mode constants. Consult the text for more information.
TextureAttributes()
Constructs a TextureAttributes object with default settings:
texture mode : REPLACE, transform : null, blend color : black (0,0,0,0), perspective correction: NICEST
TextureAttributes(int textureMode, Transform3D transform,
Color4f textureBlendColor, int perspCorrectionMode)
Construct a TextureAttributes with specified values.
TextureAttributes Constants
These constants are used in constructors and methods for setting the texture and perspective correction modes.
Texture Mode Constants
BLEND Blend the texture blend color with the object color.
DECAL Apply the texture color to the object as a decal.
MODULATE Modulate the object color with the texture color.
REPLACE Replace the object color with the texture color.
Perspective Correction Mode Constants
FASTEST Use the fastest available method for texture mapping perspective correction.
NICEST Use the nicest (highest quality) available method for texture mapping perspective correction.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-20
TextureAttributes Method Summary
See the following reference block for a list of texture mode and perspective correction mode constants. Consult the
text of this chapter for more information.
void getTextureBlendColor(Color4f textureBlendColor)
Gets the texture blend color for this appearance component object.
void getTextureTransform(Transform3D transform)
Retrieves a copy of the texture transformation object.
void setPerspectiveCorrectionMode(int mode)
Sets perspective correction mode to be used for color and/or texture coordinate interpolation to one of:
FASTEST Use the fastest available method for texture mapping perspective correction.
NICEST Use the nicest (highest quality) available method for texture mapping perspective correction.
void setTextureBlendColor(Color4f textureBlendColor)
void setTextureBlendColor(float r, float g, float b, float a)
Sets the texture blend color for this TextureAttributes object.
void setTextureMode(int textureMode)
Sets the texture mode parameter to one of:
BLEND Blend the texture blend color with the object color.
DECAL Apply the texture color to the object as a decal.
MODULATE Modulate the object color with the texture color.
REPLACE Replace the object color with the texture color.
void setTextureTransform(Transform3D transform)
Sets the texture transform object used to transform texture coordinates.
TextureAttributes Capabilities Summary
ALLOW_BLEND_COLOR_READ | WRITE Allow reading (writing) texture blend color
ALLOW_MODE_READ | WRITE Allow reading (writing) texture and perspective correction modes.
ALLOW_TRANSFORM_READ | WRITE Allow reading (writing) texture transform.
7.5 Automatic Texture Coordinate Generation
As previously discussed, assigning texture coordinates to each vertex of the geometry is a necessary step
in texturing visual objects. This process can be time consuming as well as difficult for large and/or
complex visual objects. Keep in mind that this is a problem for the programmer and once solved, it is not
a recurring problem.
Texture coordinates are often assigned with code specific to a visual object. However, another solution
is to automate the assignment of texture coordinates via some method. This method could be used for
any visual object whether large or small, complex or simple. This approach is exactly what a
TexCoordGeneration (texture coordinate generation) object does. Whether an object is loaded from a
file or created in the program code, a texture coordinate generation object can be used to assign texture
coordinates.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-21
TexCoordGeneration is a Java 3D API core class used to generate texture coordinates. To automatically
generate texture coordinates, the programmer specifies the texture coordinate parameters in a
TexCoordGeneration object and adds that object to the appearance bundle of the visual object. The
texture coordinates are calculated based on the coordinate specification parameters at runtime. The
parameters are explained in the following sections.
7.5.1 Texture Generation Format
This setting simply specifies if the texture coordinates will be generated for a two or three dimensional
texture. The possible settings are TEXTURE_COORDINATE_2 and TEXTURE_COORDINATE_3 which
generates 2D texture coordinates (S and T) and 3D texture coordinates (S, T, and R), respectively.
7.5.2 Texture Generation Mode
There are two basic texture generation approaches: linear projection or sphere mapping. The following
two subsections explain these options.
Linear Projection
With linear projection, the texture coordinates are specified with planes. For texture coordinates of two
dimensions (s,t), two planes are used. The distance from a vertex to one plane is the texture coordinate in
one dimension; distance to the other plane to a vertex is the texture coordinate in the other dimension.
For three dimensional textures, three planes are used.
The three possible plane parameters are named planeS, planeT, and planeR, where the name corresponds
to the dimension for which it is used. Each plane is specified as a 4-tuple (plane equation). The first
three values are the surface normal vector for the plane. The fourth value specifies the distance from the
origin to the plane along a vector parallel to the plane's surface normal vector.
There are two variations on this automatic texture coordinate generation method. The first, called object
linear, produces static texture coordinates. With object linear generated texture coordinates, if the visual
object moves, the texture coordinates do not change. The second option, called eye linear, produces
texture coordinates relative to the eye coordinates resulting in variable texture coordinates for the object.
With eye linear texture coordinates moving objects appear to move through the texture.
Figure 7-17 shows images produced by an example program that uses a TexCoordGeneration object
to assign texture coordinates to a twisted strip. A one dimensional texture is used for this application.
The texture has a single red texel at one end. When the application runs, the twisted strip rotates.
The image on the left of Figure 7-17 shows the texturing with the OBJECT_LINEAR generation mode.
In this case the texture rotates with the object and you can see the red texel rotate with the strip. The
image on the right of Figure 7-17 shows the resulting texture when the EYE_LINEAR generation mode
is used for the twisted strip. In this case, the red texel stays in the center of the view as the object rotates.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-22
Figure 7-17 Comparing Generation Modes of the TexCoordGeneration Object.
TexCoordGenApp is the program that produces these images and is available in the texture
subdirectory of the examples jar distributed with this tutorial. This is one application you should run to
see the difference. The example program is written with the Generation Mode set to EYE_LINEAR.
Line 100 is the place to change to OBJECT_LINEAR generation mode.
Sphere Map
If a shiny object is in the middle of a real room, the shiny object would likely reflect the image of many
of the other objects in the room. The reflections would depend on the shape of the object and orientation
of things in the room. The sphere map coordinate generation mode is designed to assign texture
coordinates to approximate the reflections of other objects onto the visual object as would happen for the
shiny object in the example real world.
When a TexCoordGeneration object is used in sphere map generation mode the texture coordinates are
calculated based on the surface normals and the viewing direction.
The texture used for this effect must be specially prepared. If the virtual environment of the shiny object
exists in the real world, a photograph of the scene taken with a fisheye lens will create a suitable texture
image. If the scene does not exist, then the texture must be created to look like the image is a photograph
taken with a fisheye lens.
7.5.3 How to use a TexCoordGeneration Object
To use a TexCoordGeneration Object, set it as a component of an appearance bundle for the visual object
to be textured. Figure 7-18 shows the diagram of an appearance bundle with an TexCoordGeneration
object along with a Texture and TextureAttributes object.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-23
TexCoord
Generation
Texture
Appearance
S
Geometry
TextureAttributes
Figure 7-18 Appearance Bundle with Texture, TextureAttributes, and TexCoodGeneration.
The following reference block shows the Appearance method for setting a TexCoordGeneration object as
a component of an appearance bundle.
Appearance setTexCoordGeneration method
void setTexCoordGeneration(TexCoordGeneration texCoordGeneration)
Sets the texCoordGeneration object to the specified object.
7.5.4 TexCoordGeneration API
The following reference blocks list the constructors, constants, methods, and the capabilities for
TexCoordGeneration class objects.
TexCoordGeneration Constructor Summary
The TexCoordGeneration object contains all parameters needed for texture coordinate generation. It is included as
part of an Appearance component object.
TexCoordGeneration()
Constructs a TexCoordGeneration object using defaults for all state variables.
TexCoordGeneration(int genMode, int format)
Constructs a TexCoordGeneration object with the specified genMode and format.
TexCoordGeneration(int genMode, int format, Vector4f planeS)
TexCoordGeneration(int genMode, int format, Vector4f planeS, Vector4f planeT)
TexCoordGeneration(int genMode, int format, Vector4f planeS, Vector4f planeT,
Vector4f planeR)
Constructs a TexCoordGeneration object with the specified genMode, format, and the coordinate plane equation(s).
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-24
TexCoordGeneration Field Summary
The TexCoordGeneration object contains all parameters needed for texture coordinate generation. It is included as
part of an Appearance component object.
Generation Mode Constants
EYE_LINEAR Generates texture coordinates as a linear function in eye coordinates. (default)
OBJECT_LINEAR Generates texture coordinates as a linear function in object coordinates.
SPHERE_MAP Generates texture coordinates using a spherical reflection mapping in eye coordinates.
Format Constants
TEXTURE_COORDINATE_2 Generates 2D texture coordinates (S and T) (default)
TEXTURE_COORDINATE_3 Generates 3D texture coordinates (S, T, and R)
TexCoordGeneration Method Summary
void setEnable(boolean state)
Enables or disables texture coordinate generation for this appearance component object.
void setFormat(int format)
Sets the TexCoordGeneration format to the specified value.
void setGenMode(int genMode)
Sets the TexCoordGeneration generation mode to the specified value.
void setPlaneR(Vector4f planeR)
Sets the R coordinate plane equation.
void setPlaneS(Vector4f planeS)
Sets the S coordinate plane equation.
void setPlaneT(Vector4f planeT)
Sets the T coordinate plane equation.
TexCoordGeneration Capabilities Summary
ALLOW_ENABLE_READ | WRITE allows reading/writing its enable flag.
ALLOW_FORMAT_READ allows reading its format information.
ALLOW_MODE_READ allows reading its mode information.
ALLOW_PLANE_READ allows reading its planeS, planeR, and planeT component information.
7.6 Multiple Levels of Texture (Mipmaps)
To understand the reason for multiple levels of texture, consider an application which contains a textured
visual object which moves about in the scene (or the viewer moves). When this visual object is near the
viewer it appears as many pixels in the image. For this case, a texture of good size should be used to
avoid viewing individual texels; this is especially true when point sampling is used for the magnification
filter.
However, when this visual object is viewed as a distance, the texture will be much too large for the
visual object and the texture will be mininified during the rendering. (Recall that texture mapping takes
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-25
place at render time in the image, or screen, space.) Point sampling for the minification filter will
probably not yield satisfactory results when the visual object appears 1/32 or smaller (in pixel size) than
the texture resolution. The tradeoff is image quality for rendering performance.
If instead of using a large texture map (because the visual object will appear large) a small one is used to
make the visual object look better when it is small, the reverse problem exists. For good quality images
the magnification filter will involve linear interpolation resulting in more computation. Once again, the
tradeoff is for image quality versus rendering performance. The only advantage that using a smaller
texture map has is a reduced memory requirement for storing the texture.
What is needed is a small texture map when the visual object is appears small and a large texture map
when the visual object appears large. The current texturing technique using one texture image, called
base level texturing, can not do this. That is exactly what multiple levels of texture provides.
7.6.1 What is Multi Level Texturing (MIPmap)
Multiple Levels of Texture refers to a texturing technique where a series of texture images together are
used as the texture for visual objects. The series of images is (usually) the same texture at a variety of
resolutions. When a visual object is being rendered with multiple levels of texture, the texture image that
is closest to the screen size of the visual object is used.
The performance of the renderer depends on the minification and magnification filters used (see Sections
7.2.5 and 0). However, with MIPmaps you have more control over the appearance of the visual objects
and can get better looking visual objects with better performance
11
.
Using multiple levels of texture is like using a DistanceLOD object (see Section 5.4) to apply different
textures to a visual object when it is viewed from different distances. The exceptions are that with the
Mipmap the visual object will always be textured whereas with the DistanceLOD object, the object could
be untextured at some distances. And, for visual objects textured at all distances, the MIPmap is more
efficient and has added filtering possibilities as compared with a DistanceLOD object used for a similar
application.
Multiple levels of texture is commonly referred to as a mipmap. The term "MIPmap" comes from an
acronym of the Latin phrase multum in parvo, which means many things in a small place. The term
MIPMap truly refers to a specific storage technique for storing a series of images for use in multilevel
texturing. The term MIPmap is commonly used to mean multilevel texturing.
With the MIPmap storage technique, the size of a texture image is the size of the previous ( the size
in each dimension). This continues until the size of the smallest image is 1 texel by 1 texel. For
example, if the full size texture is 16x4, the remaining textures are 8x2, 4x1, 2x1, and 1x1. Figure 7-19
shows the multiple levels of texture for the stripe.gif texture, each outlined. Each of these texture
images was prepared using image editing software.
11
The quality of appearance versus rendering performance tradeoff depends on the execution environment, choices
of texture filters, the texture image, and the range of distances the visual object is viewed from.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-26
Figure 7-19 Multiple Levels of a Texture (outlined). (Image Sizes: 128x128, 64x64, 32x32, , 1x1)
Figure 7-20 shows an image of a single plane textured with a multiple level texture where each level of
the texture is a different color. The plane is oriented at an angle to the viewer such that the left side is
much nearer to the viewer than the right side. Due to the perspective projection the left side of the plane
appears larger in image coordinates than the right side.
Due to the orientation and projection of the plane, the pixels represent less of the surface area (in the
virtual object coordinate system) on the left and progressively more visual object surface area proceeding
to the right, resulting in the texture level changes. At the left of the plane in the image, the base level of
the texture is used. The color changes in the image indicate where texture level changes occurred while
rendering.
Having a texture where each level is a different color is not the typical application of multiple level
texturing. This application simply illustrates the operation of a multiple level texture.
Figure 7-20 The Image Generated for a Plane Textured with a Multi Color Mipmap Texture.
Figure 7-20 is generated by MIPmapDemo, an example program available in the examples jar
12
. The
texture in this program is created from the files named color<number>.gif (e.g., color128.gif,
color64.gif, color32.gif, ) also in the examples jar.
12
The example MIPmapDemo.java example application was inspired by a similar OpenGL example application
in the OpenGL Programming Guide, third edition, by Mason Woo, et al.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-27
7.6.2 Multiple Levels of Texture Examples
As far as programming with the Java 3D API is concerned, creating a multilevel texture is nearly the
same as creating the single level, or base level, texture. Looking back at the simple texturing recipe
(Figure 7-2) the only thing that differs is that multiple texture images are required for the multilevel
texture. There are two ways to create the multiple levels of texture images. One way is to create each
image by hand using the appropriate image editing/creation applications, the other uses a texture loader
feature to create those images from the base image.
The two multiple level texturing techniques take about the same amount of code. The least amount of
overall work is to generate the levels' images from the base image. Code Fragment 7-8 presents the
texture loading code from MIPmapApp.java. This application is an example of generating multiple
levels of texture from a base image. The complete code for this application is available in the tutorial's
examples jar example/texture subdirectory.
1. Appearance appear = new Appearance();
2.
3. NewTextureLoader loader = new NewTextureLoader("stripe.gif",
4. TextureLoader.GENERATE_MIPMAP);
5. ImageComponent2D image = loader.getImage();
6.
7. imageWidth = image.getWidth();
8. imageHeight = image.getHeight();
9.
10. Texture2D texture = new Texture2D(Texture.MULTI_LEVEL_MIPMAP,
11. Texture.RGB, imageWidth, imageHeight);
12. imageLevel = 0;
13. texture.setImage(imageLevel, image);
14.
15. while (imageWidth > 1 || imageHeight > 1){ // loop until size: 1x1
16. imageLevel++; // compute this level
17.
18. if (imageWidth > 1) imageWidth /= 2; // adjust width as necessary
19. if (imageHeight > 1) imageHeight /= 2; // adjust height as necessary
20.
21. image = loader.getScaledImage(imageWidth, imageHeight);
22. texture.setImage(imageLevel, image);
23. }
24.
25. texture.setMagFilter(Texture.BASE_LEVEL_POINT);
26. texture.setMinFilter(Texture.MULTI_LEVEL_POINT);
27.
28. appear.setTexture(texture);
Code Fragment 7-8 Creating Multiple Level Texturing from a Base Level Image Only.
Code Fragment 7-8 begins by following the same steps as are used for any texture application by loading
the base image. One difference is that the TextureLoader is created with the GENERATE_MIPMAP flag
set (lines 3-4). Then the base image is retrieved from the loader in the usual way.
The dimensions of this image are needed not only to create the Texture2D object, but also to calculate
the sizes of the images that follow. For this reason they recorded in two variables (lines 7 and 8). These
variables will be used while generating and loading the remaining images for the texture.
The Texture2D object is created using the MIPmap Mode MULTI_LEVEL_MIPMAP and the dimension
of the base image. (lines 10 and 11). The base level is level 0. Then the level number is recorded and the
base image set as the image for level 0 (lines 12 and 13).
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-28
The loop interates until the size of the image is 1 pixel by 1 pixel (line 15). The level number is
incremented for each iteration (line 16) and the dimension of the image is calculated (lines 18 and 19).
The appropriately scaled image is gotten from the TextureLoader (line 21) and set for the current level in
the Texture2D object (line 22).
When creating a multiple level texture map be sure to set a multiple level filters as is done on lines 25
and 26 of Code Fragment 7-8. (Section 7.7.1 presents more information on filter choices.) The default
filter settings disable multiple level texturing.
Creating the images by hand allows for superior image quality and/or special effects. The generated
images are produced by filtering the base image.
1. Appearance appear = new Appearance();
2.
3. String filename = "stripe.gif"; // filename for level 0
4. NewTextureLoader loader = new NewTextureLoader(filename);
5. ImageComponent2D image = loader.getImage();
6.
7. imageWidth = image.getWidth();
8. imageHeight = image.getHeight();
9.
10. Texture2D texture = new Texture2D(Texture.MULTI_LEVEL_MIPMAP,
11. Texture.RGBA,imageWidth, imageHeight);
12. imageLevel = 0;
13. texture.setImage(imageLevel, image);
14.
15. while (imageWidth > 1 || imageHeight > 1){ // loop until size: 1x1
16. imageLevel++; // compute this level
17.
18. if (imageWidth > 1) imageWidth /= 2; // adjust width as necess.
19. if (imageHeight > 1) imageHeight /= 2;// adjust height as necess.
20. filename = "stripe"+imageWidth+".gif";// file to load
21.
22. loader = new NewTextureLoader(filename);
23. image = loader.getImage();
24.
25. texture.setImage(imageLevel, image);
26. }
27.
28. texture.setMagFilter(Texture.BASE_LEVEL_POINT);
29. texture.setMinFilter(Texture.MULTI_LEVEL_POINT);
30.
31. appear.setTexture(texture);
Code Fragment 7-9 Multiple Levels of Texture Loaded from Individual Image Files.
Section 7.8 presents the API for the TextureLoader and NewTextureLoader classes.
7.6.3 Multiple Levels of Texture Minification Filters
In addition to the two base level filter options, there are two multiple level filter options for the
minification filter setting. These additional settings are MIPMAP_POINT, and MIPMAP_LINEAR. As
with the other filter settings, the point filter is likely to be faster but yield images of lower quality as
compared to the linear filter.
Remember, when using a multiple level texture, you must select one of the multiple level filters for the
minification filter to utilize the levels other than the base level. These additional filter settings do not
apply to the magnification filter settings since magnification of the texture would only be done at the
base level. Consult section 7.7.1 for further filter information.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-29
7.6.4 Mipmap Mode
The MIPmap Mode of the Texture class is really a choice between multiple levels of texture and a single
level texture, called base level texturing. The two settings are BASE_LEVEL and
MULTI_LEVEL_MIPMAP. Of course, for multiple levels of texture the latter setting is used.
7.7 Texture, Texture2D, and Texture3D API
Many of the preceding sections present some portion of the Texture, Texture2D, or Texture3D classes.
Since these classes are described over many sections, the API for these classes is presented in this
section.
Texture is the base class for Texture2D and Texture3D. The Texture class provides the majority of the
interface for the Texture2D and Texture3D classes including multi level texturing. Table 7-3 presents a
summary of the features of these three classes. For each texturing option the table lists the class which
provides the interface, the set-Method for changing the setting, the default value, and sections of the
tutorial which discuss the feature.
Table 7-3 Directory of Texture Features
Feature/Setting Class set-Methods Default Sections
Texture Image Texture
setImage()
null 7.2
Image Format Texture (see constructors) none 7.2
Mipmap Mode Texture
setMipMapMode()
BASE_LEVEL 7.6
Minification Filter Texture
setMinFilter()
BASE_LEVEL_POINT 7.2.5, 7.6.3,
7.7.1
Magnification
Filter
Texture
setMagFilter()
BASE_LEVEL_POINT 7.2.5, 7.6.3,
7.7.1
Boundary Modes Texture
Texture
Texture3D
setBoundaryModeS()
setBoundaryModeT()
setBoundaryModeR()
WRAP
WRAP
WRAP
7.2.5
BoundaryColor Texture
setBoundaryColor()
black 7.2.5
7.7.1 Minification and Magnification Filters
Sections 7.2.5 and 7.6.3 both discuss texture filters. Since neither of these sections discuss texture filters
in detail, this section presents texture filters in a little more generality.
As previously discussed there are separate filter settings for minification and magnification. The
magnification choices are: BASE_LEVEL_POINT, BASE_LEVEL_LINEAR, FASTEST, or NICEST.
The filter will be BASE_LEVEL_POINT when FASTEST is specified and BASE_LEVEL_LINEAR
when NICEST is specified.
The minification choices are: BASE_LEVEL_POINT, BASE_LEVEL_LINEAR,
MULTI_LEVEL_POINT, MULTI_LEVEL_LINEAR, FASTEST, or NICEST. The base level filter
choices can be used for single or multiple level textures. The actual filters used when FASTEST or
NICEST is specified is implementation dependant and may not choose a multi level filter for a multiple
level texture.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-30
7.7.2 Texture API
Now that all texture features have been presented, the Texture API is presented. The Texture class is
abstract so there is no Texture class constructor reference block. The next reference block lists the fields
of the Texture class which are used as settings. The method and capabilities reference blocks follow.
Texture Field Summary
The Texture object is a component object of an Appearance object that defines the texture properties used when
texture mapping is enabled. Texture object is an abstract class and all texture objects must be created as either a
Texture2D object or a Texture3D object.
Format Constants
ALPHA Specifies Texture contains only Alpha values.
INTENSITY Specifies Texture contains only Intensity values.
LUMINANCE Specifies Texture contains only luminance values.
LUMINANCE_ALPHA Specifies Texture contains Luminance and Alpha values.
RGB Specifies Texture contains Red, Green and Blue color values.
RGBA Specifies Texture contains Red, Green, Blue color values and Alpha value.
MIP Map Mode Constants
BASE_LEVEL Indicates that Texture object only has one level.
MULTI_LEVEL_MIPMAP Texture object has multiple images- one for each mipmap level
Filter Constants
BASE_LEVEL_LINEAR Performs bilinear interpolation on the four nearest texels in level 0 texture map.
BASE_LEVEL_POINT Selects the nearest texel in level 0 texture map.
MULTI_LEVEL_LINEAR Performs tri-linear interpolation between four texels each from two nearest mipmap
levels.
MULTI_LEVEL_POINT Selects the nearest texel in the nearest mipmap.
Boundary Mode Constants
CLAMP Clamps texture coordinates to be in the range [0, 1].
WRAP Repeats the texture by wrapping texture coordinates that are outside the range [0,1].
Perspective Correction Mode Constants
FASTEST Uses the fastest available method for processing geometry.
NICEST Uses the nicest available method for processing geometry.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-31
Texture Method Summary
The Texture object is a component object of an Appearance object that defines the texture properties used when
texture mapping is enabled. Texture object is an abstract class and all texture objects must be created as either a
Texture2D object or a Texture3D object.
ImageComponent getImage(int level)
Gets a specified mipmap level.
void setBoundaryColor(Color4f boundaryColor)
void setBoundaryColor(float r, float g, float b, float a)
Sets the texture boundary color for this texture object.
void setBoundaryModeS(int boundaryModeS)
Sets the boundary mode for the S coordinate in this texture object.
void setBoundaryModeT(int boundaryModeT)
Sets the boundary mode for the T coordinate in this texture object.
void setEnable(boolean state)
Enables or disables texture mapping for this appearance component object.
void setImage(int level, ImageComponent image)
Sets a specified mipmap level.
void setMagFilter(int magFilter)
Sets the magnification filter function.
void setMinFilter(int minFilter)
Sets the minification filter function.
void setMipMapMode(int mipmapMode)
Sets mipmap mode for texture mapping for this texture object.
Texture Capabilities Summary
ALLOW_BOUNDARY_COLOR_READ allows reading its boundary color information.
ALLOW_BOUNDARY_MODE_READ allows reading its boundary mode information.
ALLOW_ENABLE_READ | WRITE allows reading its enable flag.
ALLOW_FILTER_READ allows reading its filter information.
ALLOW_IMAGE_READ allows reading its image component information.
ALLOW_MIPMAP_MODE_READ allows reading its mipmap mode information.
7.7.3 Texture2D API
Texture2D is a concrete extension of the abstract Texture class. Texture2D provides only one
constructor of interest. All of the methods used with Texture2D objects are methods of Texture. The
following reference block presents the Texture2D constructor.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-32
Texture2D Constructor Summary
Texture2D is a subclass of Texture class. It extends Texture class by adding a constructor.
Texture2D(int mipmapMode, int format, int width, int height)
Constructs an empty Texture2D object with specified mipmapMode, format, width, and height. Image at level 0 must
be set by the application using 'setImage' method. If mipmapMode is set to MULTI_LEVEL_MIPMAP, images for
ALL levels must be set.
Parameters:
mipmapMode - type of mipmap for this Texture: One of BASE_LEVEL, MULTI_LEVEL_MIPMAP.
format - data format of Textures saved in this object. One of INTENSITY, LUMINANCE, ALPHA,
LUMINANCE_ALPHA, RGB, RGBA.
width - width of image at level 0. Must be power of 2.
height - height of image at level 0. Must be power of 2.
7.7.4 Texture3D API
Texture3D is a concrete extension of the abstract Texture class. Texture3D provides only one
constructor and a method to set the boundary mode in the r dimension. All other methods used with
Texture3D objects are methods of Texture. The following two reference blocks present the Texture3D
constructor and the Texture 3D method.
Texture3D Constructor Summary
Texture3D is a subclass of Texture class. It extends Texture class by adding a third coordinate, a constructor, and a
mutator method for setting a 3D texture image.
Texture3D(int mipmapMode, int format, int width, int height, int depth)
Constructs an empty Texture3D object with specified mipmapMode, format, width, height, and depth. Image at level
0 must be set by the application using 'setImage' method. If mipmapMode is set to MULTI_LEVEL_MIPMAP,
images for ALL levels must be set.
Parameters:
mipmapMode - type of mipmap for this Texture: One of BASE_LEVEL, MULTI_LEVEL_MIPMAP.
format - data format of Textures saved in this object. One of INTENSITY, LUMINANCE, ALPHA,
LUMINANCE_ALPHA, RGB, RGBA.
width - width of image at level 0. Must be power of 2.
height - height of image at level 0. Must be power of 2.
depth - depth of image at level 0. Must be power of 2.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-33
Texture3D Method Summary
void setBoundaryModeR(int boundaryModeR)
Sets the boundary mode for the R coordinate in this texture object.
Parameters:
boundaryModeR - the boundary mode for the R coordinate, one of: CLAMP or WRAP.
7.8 TextureLoader and NewTextureLoader API
This section lists the reference blocks for the TextureLoader and NewTextureLoader classes. The
texture loader is explained in some detail in Step 2a of the simple texture recipe as defined in Section
7.2.1 on page 7-4. The texture loader is used in the all the example programs of this chapter. Of
particular interest are the examples on using the texture loader for the MIPmap applications (see Section
7.6).
The NewTextureLoader class extends the TextureLoader class providing an easier to use texture loader
utility one that does not require a awt.component image observer for each constructor.
7.8.1 TextureLoader API
The following reference block lists the single field constant used in creating TextureLoader objects.
TextureLoader Field Summary
GENERATE_MIPMAP
Optional flag - specifies that mipmaps are generated for all levels
The following reference block lists some constructors for the TextureLoader class. There are a number
of constructors not listed in the constructors reference block which allow loading texture images from
other sources. Consult the Java 3D API Specification for a complete list of constructors.
TextureLoader Constructor Summary (partial list)
extends: java.lang.Object
package: com.sun.j3d.utils.image
This class is used for loading a texture from an Image or BufferedImage. Methods are provided to retrieve the
Texture object and the associated ImageComponent object or a scaled version of the ImageComponent object.
Default format is RGBA.
Other legal formats are: RGBA, RGBA4, RGB5_A1, RGB, RGB4, RGB5, R3_G3_B2, LUM8_ALPHA8,
LUM4_ALPHA4, LUMINANCE and ALPHA
TextureLoader(java.lang.String fname, java.awt.Component observer)
TextureLoader(java.lang.String fname, int flags, java.awt.Component observer)
Contructs a TextureLoader object using the specified file, option flags and default format RGBA
TextureLoader(java.net.URL url, java.awt.Component observer)
TextureLoader(java.net.URL url, int flags, java.awt.Component observer)
Contructs a TextureLoader object using the specified URL, option flags and default format RGBA
The following reference block lists the methods of the TextureLoader class.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-34
TextureLoader Method Summary
ImageComponent2D getImage()
Returns the associated ImageComponent2D object
ImageComponent2D getScaledImage(float xScale, float yScale)
Returns the scaled ImageComponent2D object
ImageComponent2D getScaledImage(int width, int height)
Returns the scaled ImageComponent2D object
Texture getTexture()
Returns the associated Texture object
7.8.2 NewTextureLoaderAPI
The reason to use the NewTexureLoader is to avoid needing an image observer to construct a texture
loader. The following reference block lists some constructors for the NewTextureLoader class.
NewTextureLoader has the same constructors as TextureLoader except none require an awt component
to server as the image observer. NewTextureLoader.html, a javadoc file included in the examples
jar, gives complete documentation for the NewTextureLoader class.
NewTextureLoader Constructor Summary (partial list)
extends: com.sun.j3d.utils.image.TextureLoader
This class is used for loading a texture from an file or URL. This class differs from
com.sun.j3d.util.image.TextureLoader only in the absence of an image observer in the constructor and the method to
set a single image observer for all subsequent uses. All TextureLoader class constructors requiring an image
observer have a corresponding NewTextureLoader constructor without an image observer awt.component.
NewTextureLoader(java.lang.String fname)
NewTextureLoader(java.lang.String fname, int flags)
Contructs a TextureLoader object using the specified file, option flags and default format RGBA
TextureLoader(java.net.URL url)
TextureLoader(java.net.URL url, int flags)
Contructs a TextureLoader object using the specified URL, option flags and default format RGBA
The following reference block lists the two methods of the defined in the NewTextureLoader class. All
other methods are defined by the TextureLoader class. To use a NewTextureLoader object an image
observer must be set first. This is normally done when the Canvas3D object is created.
NewTextureLoader Method Summary (partial list)
java.awt.component getImageObserver()
Returns the awt.component object used as the image observer for NewTextureLoader objects.
void setImageObserver(java.awt.component imageObserver)
Sets a awt.component object as the object to use as an image observer in subsequent constructions of
NewTextureLoader objects.
Module 3: Lights and Textures Chapter 7. Textures
The Java 3D Tutorial 7-35
7.9 Chapter Summary
This chapter presents the Java 3D features for rendering objects with textures. Texturing is primarily a
function of the Texture class and its two subclasses, Texture2D and Texture3D. Section 7.1 provides
motivation for texturing and introduces some texturing terminology. Section 7.2 presents the basics of
the Texture, Texture2D, and Texture3D classes. Section 7.2 also includes a simple texturing recipe and a
simple texturing application. Section 7.3 demonstrates the use of Texture2D in some other applications.
Section 7.4 presents the TextureAttributes class. TextureAttributes objects are used to customize certain
aspects of texturing applications. Section 7.5 presents the TexCoordGeneration class. Objects of this
class are used to automatically generate texture coordinates for visual objects. Section 7.6 explains multi
level texturing. Section 7.7 presents the API for the Texture, Texture2D and Texture3D classes. Along
with the reference blocks for these classes is a 'directory' of texturing features (see Table 7-3 on page 7-
29). Section 7.8 presents the API for the TextureLoader class. TextureLoader objects are used in the
example programs throughout the chapter and briefly discussed in Sections 7.2 and 7.6. The chapter
concludes with the traditional set of "self test" questions.
7.10 Self Test
1. What happens if a texture coordinate assignment is not made for a vertex in some geometry? Is there
an exception? A warning? Does it render? If it renders, what is the result?
2. How can a single image of a texture (not repeated) be mapped onto a visual object and have the
image surrounded by a single solid color? Assume the texture image is the typical non-solid-color
image. How could the surrounding color be assigned or modified at runtime?
3. How can multiple textures be applied to a single visual object? How can you apply different textures
to the opposite sides of the same visual object? How can you apply different textures to the lines and
the surfaces of a polygon?
4. How would you animate a shadow that moves across a stationary visual object as the shadow moves?
5. How would you animate a shadow that moves across a visual object as the object passes through a
stationary shadow?