j3d tutorial

346
tutorial v1.5 (Java 3D API v1.1.2) Getting Started with the Java 3D API A Tutorial for Beginners Chapter 0 Overview and Appendices Dennis J Bouvier K Computing

Upload: robocprogrammer4515

Post on 09-Mar-2015

178 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: j3d Tutorial

tutorial v1.5 (Java 3D API v1.1.2)

Getting Started withthe Java 3D™ API

A Tutorial for BeginnersChapter 0

Overview and Appendices

Dennis J Bouvier

K Computing

Page 2: j3d Tutorial

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.

Page 3: j3d Tutorial

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-2Module 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-6What’s 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-8examples/HelloJava3D/HelloJava3Da......................................................................................................................0-8

examples/HelloJava3D/HelloJava3Db .....................................................................................................................0-8

examples/HelloJava3D/HelloJava3Dc......................................................................................................................0-8

examples/HelloJava3D/HelloJava3Dd .....................................................................................................................0-8

0.2.2 Geometry ....................................................................................................................................... 0-8examples/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-10examples/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-10examples/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

Page 4: j3d Tutorial

Getting Started with Java 3D Tutorial Preface

The Java 3D Tutorial 0-ii

0.2.5 Animation .................................................................................................................................... 0-11examples/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-12examples/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-13examples/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

Page 5: j3d Tutorial

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

versiondate 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

Page 6: j3d Tutorial

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

Page 7: j3d Tutorial

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 Started1.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 Content2.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

Page 8: j3d Tutorial

Getting Started with Java 3D Tutorial Preface

The Java 3D Tutorial 0-4

Chapter 3: Easier Content Creation3.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: Interaction4.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: Animation5.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: Lights6.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

Page 9: j3d Tutorial

Getting Started with Java 3D Tutorial Preface

The Java 3D Tutorial 0-5

Chapter 7: Textures7.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 3DAPI

Module 2:

Interaction

andAnimation

Module 3:

Lights

andTextures

START

Figure 0-1 Paths Through The Java 3D Tutorial

Page 10: j3d 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

What’s 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 don’t 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.

Page 11: j3d 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.

Page 12: j3d Tutorial

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 ProgramsThis 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.

Page 13: j3d Tutorial

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.

Page 14: j3d Tutorial

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 -lineswill 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.

Page 15: j3d Tutorial

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.

Page 16: j3d Tutorial

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.

Page 17: j3d Tutorial

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.

Page 18: j3d Tutorial

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.

Page 19: j3d Tutorial

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 programmer’s

guide.

It is also available online at http://java.sun.com/products/java-media/3DIt 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.

Page 20: j3d Tutorial

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/docsJava 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.

Page 21: j3d Tutorial

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

reader’s 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.

Page 22: j3d Tutorial

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.

Page 23: j3d Tutorial

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.

Page 24: j3d Tutorial

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.

Page 25: j3d Tutorial

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.

Page 26: j3d Tutorial

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

Page 27: j3d Tutorial

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. Don’t 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

Page 28: j3d Tutorial

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.

Page 29: j3d Tutorial

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

Page 30: j3d Tutorial

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.

Page 31: j3d Tutorial

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.

Page 32: j3d Tutorial

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.

Page 33: j3d Tutorial

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.

Page 34: j3d Tutorial

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.

Page 35: j3d Tutorial

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.

Page 36: j3d Tutorial

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.

Page 37: j3d Tutorial

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.

Page 38: j3d Tutorial

Getting Started with the Java 3D API Glossary

The Java 3D Tutorial 0-34

C

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).

Page 39: j3d Tutorial

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.

Page 40: j3d Tutorial

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.

Page 41: j3d Tutorial

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.

Page 42: j3d Tutorial

tutorial v1.5 (Java 3D API v1.1.2)

Getting Started withthe Java 3D™ API

Chapter 1

Dennis J Bouvier

K Computing

Page 43: j3d Tutorial

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.

Page 44: j3d Tutorial

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

Page 45: j3d Tutorial

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

Page 46: j3d Tutorial

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

Page 47: j3d Tutorial

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

Page 48: j3d Tutorial

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.

C H A P T E R

T

Page 49: j3d Tutorial

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 both1.

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 APIEvery 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.awtpackage 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 GraphA 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.

Page 50: j3d Tutorial

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 node’s 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 objects2.

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.

Page 51: j3d Tutorial

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.

Page 52: j3d Tutorial

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.

Page 53: j3d Tutorial

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

SAppearance Geometry

S

Figure 1-4 One Possible Fix for Illegal Scene Graph of Figure 1-3

Page 54: j3d Tutorial

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.

Page 55: j3d Tutorial

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 ProgramsThe 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.

Page 56: j3d Tutorial

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.

Page 57: j3d Tutorial

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.

Page 58: j3d Tutorial

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.

Page 59: j3d Tutorial

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 TerminologyBefore 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.

Page 60: j3d Tutorial

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: HelloJava3DaThe 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.

Page 61: j3d Tutorial

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 class11. SimpleUniverse simpleU = new SimpleUniverse(canvas3D);12. 13. // This moves the ViewPlatform back a bit so the14. // 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 graph3. BranchGroup objRoot = new BranchGroup();4. 5. // Create a simple shape leaf node, add it to the scene graph.6. // ColorCube is a Convenience Utility class7. objRoot.addChild(new ColorCube(0.4));8. 9. return objRoot;10. } // end of createSceneGraph method of HelloJava3Da11. } // 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

Page 62: j3d Tutorial

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 application2. // as well as an applet3. 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.

Page 63: j3d Tutorial

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.javaexample 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.

Page 64: j3d Tutorial

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 graph3. 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.

Page 65: j3d Tutorial

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.

Page 66: j3d Tutorial

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 CubeA 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.

Page 67: j3d Tutorial

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 graph3. BranchGroup objRoot = new BranchGroup();4. 5. // rotate object has composite transformation matrix6. 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

Page 68: j3d Tutorial

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 graph3. BranchGroup objRoot = new BranchGroup();4. 5. // rotate object has composite transformation matrix6. 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.

Page 69: j3d Tutorial

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 PerformanceThe 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.

Page 70: j3d Tutorial

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

graphcompile

BG

ColorCube

TG

View branch

graph

Figure 1-16 Conceptual Example of the Result of Compiling a Scene Graph

Page 71: j3d Tutorial

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.

Page 72: j3d Tutorial

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 BehaviorIn 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 performance4.

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

ViewPlatform’s activation volume intersects a Behavior object’s 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.

Page 73: j3d Tutorial

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 Alpha5 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.

Page 74: j3d Tutorial

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.

Page 75: j3d Tutorial

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 RotationInterpolator’s 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.

Page 76: j3d Tutorial

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 graph3. BranchGroup objRoot = new BranchGroup();4. 5. // Create the transform group node and initialize it to the6. // 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 class13. objSpin.addChild(new ColorCube(0.4));14. 15. // create time varying function to drive the animation16. Alpha rotationAlpha = new Alpha(-1, 4000);17. 18. // Create a new Behavior object that performs the desired19. // operation on the specified transform object and add it into20. // the scene graph.21. RotationInterpolator rotator =22. new RotationInterpolator(rotationAlpha, objSpin);23. 24. // a bounding sphere specifies a region a behavior is active25. 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.

Page 77: j3d Tutorial

Getting Started with Java 3D Chapter 1. Getting Started

The Java 3D Tutorial 1-30

BG

ColorCube

TGB

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.

Page 78: j3d Tutorial

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 graph3. BranchGroup objRoot = new BranchGroup();4. 5. // rotate object has composite transformation matrix6. 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 the16. // identity. Enable the TRANSFORM_WRITE capability so that17. // our behavior code can modify it at runtime. Add it to the18. // 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 class27. objSpin.addChild(new ColorCube(0.4));28. 29. // Create a new Behavior object that performs the desired30. // operation on the specified transform object and add it into31. // 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 active40. // create a sphere centered at the origin with radius of 141. 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

Page 79: j3d Tutorial

Getting Started with Java 3D Chapter 1. Getting Started

The Java 3D Tutorial 1-32

BG

ColorCube

TG

TGB

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

Page 80: j3d Tutorial

Getting Started with Java 3D Chapter 1. Getting Started

The Java 3D Tutorial 1-33

1.10 Chapter SummaryThis 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 TestOn 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 smaller6.

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.

Page 81: j3d Tutorial

tutorial v1.4 (Java 3D API v1.1.2)

Getting Started withthe Java 3D™ API

Chapter 2Creating Geometry

Dennis J Bouvier

K Computing

Page 82: j3d Tutorial

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.

Page 83: j3d Tutorial

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-22.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-62.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-152.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-202.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-342.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

Page 84: j3d Tutorial

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

Page 85: j3d Tutorial

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

Page 86: j3d Tutorial

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

Page 87: j3d Tutorial

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, you’ll 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 SystemAs 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.

C H A P T E R

C

Page 88: j3d Tutorial

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 plateviewer position

y

z

x

Figure 2-1 Orientation of Axis in Virtual World

2.2 Visual Object Definition BasicsSection 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 object1. 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 rectangle2.

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.

Page 89: j3d Tutorial

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)

Page 90: j3d Tutorial

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.

Page 91: j3d Tutorial

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 appearance7. // the geometry is created in method createGeometry8. // the appearance is created in method createAppearance9. public VisualObject() {10. 11. voGeometry = createGeometry();12. voAppearance = createAppearance();13. this.setGeometry(voGeometry);14. this.setAppearance(voAppearance);15. }16.

Page 92: j3d Tutorial

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 object19. }20. 21. private Appearance createAppearance () {22. // code to create default appearance of visual object23. }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.geometrypackage, 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 ClassesThis 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,

Page 93: j3d Tutorial

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 size3. 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 appearance4. 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 objects5. 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.

Page 94: j3d Tutorial

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.

Page 95: j3d Tutorial

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.

Page 96: j3d Tutorial

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.

Page 97: j3d Tutorial

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.

Page 98: j3d Tutorial

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 ConeYoyoApp6

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.

Page 99: j3d Tutorial

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 appearance6. //7. public ConeYoyo() {8.

Page 100: j3d Tutorial

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 constructor43. 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);

Page 101: j3d Tutorial

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 ClassesTo 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 discussed7.

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.

Page 102: j3d Tutorial

Getting Started with the Java 3D API Chapter 2. Creating Geometry

The Java 3D Tutorial 2-16

javax.vecmathTuple2f

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, it’s important to be familiar with the

Tuple constructors and methods, which are listed below.

Page 103: j3d Tutorial

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).

Page 104: j3d Tutorial

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 L1 (Manhattan) distance between this point and point p1. The L1 distance is equal to:

abs(x1 - x2) + abs(y1 - y2) + abs(z1 - z2)

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.

Page 105: j3d Tutorial

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.

Page 106: j3d Tutorial

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 ClassesIn 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.

Page 107: j3d Tutorial

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.”

Page 108: j3d Tutorial

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.

Let’s see how this constructor works, but first recall that GeometryArray is an abstract class. Therefore,

you actually call the constructor for one of GeometryArray’s 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.javawhich 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.

Page 109: j3d Tutorial

Getting Started with the Java 3D API Chapter 2. Creating Geometry

The Java 3D Tutorial 2-23

1. // construct object to represent the X axis2. LineArray axisXLines= new LineArray (2, LineArray.COORDINATES);3. 4. // construct object to represent the Y axis5. LineArray axisYLines = new LineArray(2, LineArray.COORDINATES6. | LineArray.COLOR_3);7. 8. // construct object to represent the Z axis9. LineArray axisZLines = new LineArray(10, LineArray.COORDINATES10. | 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.

Page 110: j3d Tutorial

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

Page 111: j3d Tutorial

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

GeometryGeometry

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.

Page 112: j3d Tutorial

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.

Page 113: j3d Tutorial

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 triangles8.

8 The Triangulator class and related classes are explained in more detail in Chapter 3.

Page 114: j3d Tutorial

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, it’s 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

Page 115: j3d Tutorial

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 strips15. 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.

Page 116: j3d Tutorial

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 strips18. 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.

Page 117: j3d Tutorial

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.

Page 118: j3d Tutorial

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

GeometryArrayIndexedLineArray

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).

Page 119: j3d Tutorial

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.”

Page 120: j3d Tutorial

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 AttributesShape3D 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.

Page 121: j3d Tutorial

Getting Started with the Java 3D API Chapter 2. Creating Geometry

The Java 3D Tutorial 2-35

Appearance Geometry

S

LineAttributesColoring

AttributesMaterial

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.

Page 122: j3d Tutorial

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.

Page 123: j3d Tutorial

Getting Started with the Java 3D API Chapter 2. Creating Geometry

The Java 3D Tutorial 2-37

AppearanceGeometry

S

LineAttributesColoring

AttributesMaterial

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 aren’t Node objects, so they really don’t 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.

Page 124: j3d Tutorial

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.

Page 125: j3d Tutorial

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, booleanbackFaceNormalFlip)

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 don’t 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.)

Page 126: j3d Tutorial

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 object’s 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 object’s

appearance.

TransparencyAttributes Methods

void setTransparency(float tVal)

where tVal specifies an object’s 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.

Page 127: j3d Tutorial

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.

Page 128: j3d Tutorial

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

Page 129: j3d Tutorial

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 hasn’t 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 has6. // been defined, create a Shape3D object with culling turned off7. // in the Appearance bundle, and add the Shape3D to the scene graph8. 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.

Page 130: j3d Tutorial

Getting Started with the Java 3D API Chapter 2. Creating Geometry

The Java 3D Tutorial 2-44

0

0

1

12

2

0

1

2

3

4

5

6

78

9

Figure 2-24 Determining the Front Face of Polygons and Strips

2.7 Self TestOn 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?

Page 131: j3d Tutorial

tutorial v1.5 (Java 3D API v1.1.2)

Getting Started withthe Java 3D™ API

Chapter 3Easier Content Creation

Dennis J Bouvier

K Computing

Page 132: j3d Tutorial

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.

Page 133: j3d Tutorial

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

Page 134: j3d Tutorial

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

Page 135: j3d Tutorial

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 3This 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 ImageThe 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.javaexample 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.

Page 136: j3d Tutorial

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, you’ll 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

C H A P T E R

Page 137: j3d Tutorial

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 don’t 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.

Page 138: j3d Tutorial

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.loadersImplements: 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 graph16. 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

Page 139: j3d Tutorial

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 loader1.

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.

Page 140: j3d Tutorial

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.

Page 141: j3d Tutorial

Getting Started with Java 3D Chapter 3. Easier Content Creation

The Java 3D Tutorial 3-6

LoaderBase Constructor Summary

Package: com.sun.j3d.loadersImplements: 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

Page 142: j3d Tutorial

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 holes2. 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 triangles3.

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

geometry4.

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.

Page 143: j3d Tutorial

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 don’t

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.

Page 144: j3d Tutorial

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.

Page 145: j3d Tutorial

Getting Started with Java 3D Chapter 3. Easier Content Creation

The Java 3D Tutorial 3-10

GeometryInfo Constructor Summary

Package: com.sun.j3d.utils.geometryExtends: 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.

Page 146: j3d Tutorial

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.

Page 147: j3d Tutorial

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.geometryExtends: 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 object5.

Stripifier Constructor Summary

Package: com.sun.j3d.utils.geometryExtends: 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.

Page 148: j3d Tutorial

Getting Started with Java 3D Chapter 3. Easier Content Creation

The Java 3D Tutorial 3-13

NormalGenerator Constructor Summary

Package: com.sun.j3d.utils.geometryExtends: 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.

Page 149: j3d Tutorial

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

parameters6. 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 graph18. 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.

Page 150: j3d Tutorial

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.

Page 151: j3d Tutorial

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, intfontSize, 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.

Page 152: j3d Tutorial

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 graph17. 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.

extrusionreference

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.

Page 153: j3d Tutorial

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.

Page 154: j3d Tutorial

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.

Page 155: j3d Tutorial

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 objects7. 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.

Page 156: j3d Tutorial

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.

Page 157: j3d Tutorial

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.

Page 158: j3d Tutorial

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 background2. backg.setGeometry(createBackGraph()); // add BranchGroup of background3. 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.

Page 159: j3d Tutorial

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.

Page 160: j3d Tutorial

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.

Page 161: j3d Tutorial

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 performance8.

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 places9.

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.

Page 162: j3d 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 Background10

. In this code, the standard

createSceneGraph() method is modified to takes a single parameter, that of the SimpleUniverse

object11

. 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.

Page 163: j3d 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 data12

. 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.

Page 164: j3d Tutorial

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?

Page 165: j3d Tutorial

Tutorial version 1.5 (Java 3D API v 1.1.2)

Getting Started withthe Java 3D™ API

Chapter 4Interaction

BG

TG

View Platform

View Canvas3D Screen3D

Physical Body Physical EnvironmentS

TG

S

TG

S

TG

S

TG

S

TG

S

TG

TG

BG

B

Dennis J Bouvier

K Computing

Page 166: j3d Tutorial

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 OFMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS SHALL NOT BELIABLE FOR ERRORS CONTAINED HEREIN OR FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES(INCLUDING LOST PROFITS IN CONNECTION WITH THE FURNISHING, PERFORMANCE OR USE OFTHIS 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.

Page 167: j3d Tutorial

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

Page 168: j3d Tutorial

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

Page 169: j3d Tutorial

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

Page 170: j3d Tutorial

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.

Page 171: j3d Tutorial

Module 2: Interaction and Animation

The Java 3D Tutorial 4-1

4 Interaction

Chapter Objectives

After reading this chapter, you’ll 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.

C H A P T E R

Page 172: j3d Tutorial

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

Page 173: j3d Tutorial

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.

Page 174: j3d Tutorial

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

PickTranslateBehaviorPickMouseBehavior

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.

Page 175: j3d Tutorial

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

Page 176: j3d Tutorial

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. � SimpleBehavior(TransformGroup targetTG){16. this.targetTG = targetTG;17. }18. 19. // initialize the Behavior20. // set initial wakeup condition21. // called when behavior becomes live

22. � public void initialize(){23. // set initial wakeup condition24. this.wakeupOn(new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED));25. }26. 27. // called by Java 3D when appropriate stimulus occurs

28. � public void processStimulus(Enumeration criteria){29. // do what is necessary in response to stimulus30. 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/Interactiondirectory.

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

Page 177: j3d Tutorial

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 behavior1.

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.

Page 178: j3d Tutorial

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 graph39. BranchGroup objRoot = new BranchGroup();40. 41. TransformGroup objRotate = new TransformGroup();

42. � objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);43. �44. objRoot.addChild(objRotate);45. objRotate.addChild(new ColorCube(0.4));46. 47. SimpleBehavior myRotationBehavior = new SimpleBehavior(objRotate);

48. � myRotationBehavior.setSchedulingBounds(new BoundingSphere());

49. � 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.

Page 179: j3d Tutorial

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 visible2.

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.

Page 180: j3d Tutorial

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

objRotatemyRotationBehavior

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 performance3. 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 stop45

.

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.

Page 181: j3d Tutorial

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.

Page 182: j3d Tutorial

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

Page 183: j3d Tutorial

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

WakeupOnActivationWakeupOnAWTEvent

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.

Page 184: j3d Tutorial

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

WakeupOnActivationon 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

WakeupOnCollisionEntryon the first detection of the specified object colliding with any

other object in the scene graph4-17

WakeupOnCollisionExitwhen the specified object no longer collides with any other

object in the scene graph4-19

WakeupOnCollisionMovementwhen the specified object moves while in collision with any

other object in the scene graph4-20

WakeupOnDeactivationwhen a ViewPlatform's activation volume no longer intersects

with this object's scheduling region4-21

WakeupOnElapsedFrames when a specific number of frames have elapsed 4-21

WakeupOnElapsedTime when a specific number of milliseconds have elapsed 4-21

WakeupOnSensorEntryon first detection of any sensor intersecting the specified

boundary4-22

WakeupOnSensorExitwhen a sensor previously intersecting the specified boundary no

longer intersects the specified boundary4-22

WakeupOnTransformChangewhen the transform within a specified TransformGroup

changes4-23

WakeupOnViewPlatformEntryon first detection of a ViewPlatform activation volume

intersecting with the specified boundary4-23

WakeupOnViewPlatformExitwhen a View activation volume no longer intersects the

specified boundary4-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.

Page 185: j3d Tutorial

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.

Page 186: j3d Tutorial

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).

Page 187: j3d Tutorial

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 excluded23. 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 objects4. TransformGroup doorTG = new TransformGroup();5. OpenBehavior openObject = new OpenBehavior(doorTG);6. CloseBehavior closeObject = new CloseBehavior(doorTG);7. 8. //prepare the behavior objects9. openObject.setBehaviorObjectPartner(closeObject);10. closeObject.setBehaviorObjectPartner(openObject);11. 12. // set scheduling bounds for behavior objects – code excluded13. 14. // assemble scene graph – code excluded15.

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.

Page 188: j3d Tutorial

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.

Page 189: j3d Tutorial

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, orUSE_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.

Page 190: j3d Tutorial

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.

Page 191: j3d Tutorial

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.

Page 192: j3d Tutorial

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

Page 193: j3d Tutorial

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

Page 194: j3d Tutorial

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.

Page 195: j3d Tutorial

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.

Page 196: j3d Tutorial

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/Interactionsubdirectory. 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

Page 197: j3d Tutorial

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 method6. 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 graph3. TransformGroup vpTrans = null;4. 5. BranchGroup objRoot = new BranchGroup();6. 7. objRoot.addChild(createLand());8. 9. // create other scene graph content10. 11. 12. vpTrans = su.getViewingPlatform().getViewPlatformTransform();13. translate.set( 0.0f, 0.3f, 0.0f); // 3 meter elevation14. T3D.setTranslation(translate); // set as translation15. vpTrans.setTransform(T3D); // used for initial position

16. � KeyNavigatorBehavior keyNavBeh = new KeyNavigatorBehavior(vpTrans);

17. � keyNavBeh.setSchedulingBounds(new BoundingSphere(18. new Point3d(),1000.0));

19. � 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.

Page 198: j3d Tutorial

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 class32. 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

Page 199: j3d Tutorial

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 placeleft-button held with

mouse movement

MouseTranslatetranslate the visual object in a plane parallel to the image

plate

right-button held with

mouse movement

MouseZoomtranslate 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.

Page 200: j3d Tutorial

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 graph5. BranchGroup objRoot = new BranchGroup();6. 7. TransformGroup objRotate = new TransformGroup();

8. � objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

9. � objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);10. 11. objRoot.addChild(objRotate);12. objRotate.addChild(new ColorCube(0.4));13.

14. � MouseRotate myMouseRotate = new MouseRotate();

15. � myMouseRotate.setTransformGroup(objRotate);

16. � myMouseRotate.setSchedulingBounds(new BoundingSphere());

17. � 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

Page 201: j3d Tutorial

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 .

Page 202: j3d Tutorial

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.mouseExtends: 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.

Page 203: j3d Tutorial

Module2: Interaction and Animation Chapter 4. Interaction

The Java 3D Tutorial 4-33

MouseTranslate Constructor Summary

Package: com.sun.j3d.utils.behaviors.mouseExtends: 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.

Page 204: j3d Tutorial

Module2: Interaction and Animation Chapter 4. Interaction

The Java 3D Tutorial 4-34

MouseZoom Constructor Summary

Package: com.sun.j3d.utils.behaviors.mouseExtends: 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 intflags 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.

Page 205: j3d Tutorial

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 graph3. 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 interaction7. 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.

Page 206: j3d Tutorial

Module2: Interaction and Animation Chapter 4. Interaction

The Java 3D Tutorial 4-36

image plate

visual

objectmouse 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

Page 207: j3d Tutorial

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: SceneGraphObjectsubclasses: 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_REPORTINGSpecifies 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 | WRITESpecifies that this Node allows read (write) access to its bounds information.

ALLOW_PICKABLE_READ | WRITESpecifies 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.

Page 208: j3d Tutorial

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.

Page 209: j3d Tutorial

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 graph3. 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 objects11. transform.setTranslation(new Vector3f(-0.6f, 0.0f, -0.6f));12. objRotate = new TransformGroup(transform);13. objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

14. � 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. � pickRotate = new PickRotateBehavior(objRoot,canvas, behaveBounds);

21. � objRoot.addChild(pickRotate);22. 23. // add a second ColorCube object to the scene graph24. transform.setTranslation(new Vector3f( 0.6f, 0.0f, -0.6f));25. objRotate = new TransformGroup(transform);26. objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

27. � 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.

Page 210: j3d Tutorial

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.

Page 211: j3d Tutorial

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.

Page 212: j3d Tutorial

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.

Page 213: j3d Tutorial

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.

Page 214: j3d Tutorial

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 PickMouseBehaviorclass.

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.

Page 215: j3d Tutorial

Module2: Interaction and Animation Chapter 4. Interaction

The Java 3D Tutorial 4-45

PickMouseBehavior Method Summary

Package: com.sun.j3d.utils.behaviors.pickingExtends: 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.pickingextends: 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 flagis 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.

Page 216: j3d Tutorial

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).

Page 217: j3d Tutorial

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.pickingextends: 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.

Page 218: j3d Tutorial

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.pickingextends: PickMouseBehaviorimplements: 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.

Page 219: j3d Tutorial

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.pickingextends: PickMouseBehaviorimplements: 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.

Page 220: j3d Tutorial

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.pickingextends: PickMouseBehaviorimplements: 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.

Page 221: j3d Tutorial

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

Page 222: j3d Tutorial

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.

Page 223: j3d Tutorial

Tutorial version 1.5 (Java 3D API v 1.1.2)

Getting Started withthe Java 3D™ API

Chapter 5Animation

Dennis J Bouvier

K Computing

Page 224: j3d Tutorial

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 OFMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS SHALL NOT BELIABLE FOR ERRORS CONTAINED HEREIN OR FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES(INCLUDING LOST PROFITS IN CONNECTION WITH THE FURNISHING, PERFORMANCE OR USE OFTHIS 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.

Page 225: j3d Tutorial

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

Page 226: j3d Tutorial

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

Page 227: j3d Tutorial

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.

Page 228: j3d Tutorial

Module 2: Interaction and Animation

The Java 3D Tutorial 5-1

5 Animation

Chapter Objectives

After reading this chapter, you’ll 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 action1.

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 objects2. 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.

C H A P T E R

Page 229: j3d Tutorial

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 Animations3

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.

Page 230: j3d Tutorial

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 begins4. 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

alp

ha

val

ue 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.

Page 231: j3d Tutorial

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, DecreasingAlphaRampDuration5, 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 recipe6.

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 jar7.

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.

Page 232: j3d Tutorial

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_WRITEcapability 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 graph3. 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.

Page 233: j3d Tutorial

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 clock8. 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/Animationsubdirectory. 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.

Page 234: j3d Tutorial

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 Alpha9

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

durationtime ~ 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.

Page 235: j3d Tutorial

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.

Page 236: j3d Tutorial

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.

Page 237: j3d Tutorial

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.

Page 238: j3d Tutorial

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

PathInterpolator10

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.

Page 239: j3d Tutorial

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 object11.

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: Behaviorknown 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.

Page 240: j3d Tutorial

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

IGeometry

S

Appearance

BoundingSphereMaterial

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.

Page 241: j3d Tutorial

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.

Page 242: j3d Tutorial

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.

Page 243: j3d Tutorial

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).

Page 244: j3d Tutorial

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 doesn’t 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.

Page 245: j3d Tutorial

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.

Page 246: j3d Tutorial

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.

Page 247: j3d Tutorial

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.60.7

0.9

0.3

0.0

Figure 5-11The Relationship Between Knots and Alpha Value for a 2D Position Example.

Page 248: j3d Tutorial

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/Animationsubdirectory. 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.

Page 249: j3d Tutorial

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.

Page 250: j3d Tutorial

Module 3: Interaction and Animation Chapter 5. Animation

The Java 3D Tutorial 5-23

PathInterpolator

extends: InterpolatorDirect 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.

Page 251: j3d Tutorial

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 geometry12. 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.

Page 252: j3d Tutorial

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 background13.

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 behavior16. TGR.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); �

17. billboard = new Billboard(TGR); �18. billboard.setSchedulingBounds(bSphere); �19. 20. // assemble scene graph21. 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.

Page 253: j3d Tutorial

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.

Page 254: j3d Tutorial

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.

Page 255: j3d Tutorial

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).

Page 256: j3d Tutorial

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.

Page 257: j3d Tutorial

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 Capabilities6. 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 object19. 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 object27. objMove.addChild(targetSwitch); // must add switch to scene graph28. 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.

Page 258: j3d Tutorial

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.

Page 259: j3d Tutorial

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.

Page 260: j3d Tutorial

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 objects14. 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.

Page 261: j3d Tutorial

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.

Page 262: j3d Tutorial

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 efficiency6. private double[] weights = {0, 0, 0, 0};7. private WakeupCondition trigger = new WakeupOnElapsedFrames(0);8. 9. // create MorphBehavior10. MorphBehavior(Morph targetMorph, Alpha alpha){11. this.targetMorph = targetMorph;12. this.alpha = alpha;13. }14. 15. public void initialize(){16. // set initial wakeup condition17. this.wakeupOn(trigger);18. }19. 20. public void processStimulus(Enumeration criteria){21. // don't need to decode event since there is only one trigger22. weights[0] = 0; weights[1] = 0; weights[2] = 0; weights[3] = 0;23. 24. float alphaValue = 4f * alpha.value(); // get alpha25. int alphaIndex = (int) alphaValue; // which Geom obj26. weights[alphaIndex] = (double) alphaValue - (double)alphaIndex;27. if(alphaIndex < 3) // which other obj28. weights[alphaIndex + 1] = 1.0 - weights[alphaIndex];29. else30. weights[0] = 1.0 - weights[alphaIndex];31. 32. targetMorph.setWeights(weights);33. 34. this.wakeupOn(trigger); // set next wakeup condition35. }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.

Page 263: j3d Tutorial

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 graph3. 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 object21. Alpha alpha = new Alpha(-1, 2000); // continuous 2 sec. period22. alpha.setIncreasingAlphaRampDuration(100);23. 24. // create morph driving behavior25. 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.

Page 264: j3d Tutorial

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.

Page 265: j3d Tutorial

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?

Page 266: j3d Tutorial

tutorial v1.5 (Java 3D API v1.1.2)

Getting Started withthe Java 3D™ API

Chapter 6Lights

Dennis J Bouvier

K Computing

Page 267: j3d Tutorial

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.

Page 268: j3d Tutorial

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

Page 269: j3d Tutorial

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

Page 270: j3d Tutorial

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

Page 271: j3d Tutorial

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, you’ll 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.

C H A P T E R

Page 272: j3d Tutorial

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

LE

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

Page 273: j3d Tutorial

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.

Page 274: j3d Tutorial

Module 3: Lights and Textures Chapter 6. Lights

Getting Started with the Java 3D API 6-4

Shading Model

The lighting model shades1 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 polygon2. Figure 6-3 shows one flat shaded sphere and one Gouraud

shaded sphere. The advantage to flat shading is speed in software rendering3. 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.

Page 275: j3d Tutorial

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 withoutspecifying 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.

Page 276: j3d Tutorial

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.

Page 277: j3d Tutorial

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 object4. scene.addChild(lightD1);

Code Fragment 6-2 Adding a Directional Light to the Scene.

Page 278: j3d Tutorial

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.

Page 279: j3d Tutorial

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

-3light1light2

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.

Page 280: j3d Tutorial

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

Page 281: j3d Tutorial

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 locations4 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 truecolor (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 programs5.

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.

Page 282: j3d Tutorial

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 truecolor (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.

Page 283: j3d Tutorial

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.

Page 284: j3d Tutorial

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 truecolor (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, Point3fattenuation)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

distancequadraticdistancelinearconstantnattenuatio

∗+∗+=

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.

Page 285: j3d Tutorial

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

Outside thespread angle,no light isproduced

Inside thespread angle,light intensitydepends onthe angle anddistance tothe vertex

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.

Page 286: j3d Tutorial

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 truecolor (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, Vector3fdirection, 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, Point3fattenuation, 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

Page 287: j3d Tutorial

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.

Page 288: j3d Tutorial

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.javathree 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.

Page 289: j3d Tutorial

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.javaprogram. 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

Page 290: j3d Tutorial

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 sources6. 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.

Page 291: j3d Tutorial

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.

Page 292: j3d Tutorial

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) ).

Page 293: j3d Tutorial

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.

Page 294: j3d Tutorial

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.

Page 295: j3d Tutorial

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 vertexnormals 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.

Page 296: j3d Tutorial

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.

Page 297: j3d Tutorial

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

tabletable

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 naïve 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.

Page 298: j3d Tutorial

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.

Page 299: j3d Tutorial

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.

Page 300: j3d Tutorial

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.

Page 301: j3d Tutorial

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.COORDINATES7. | GeometryArray.COLOR_38. );

Page 302: j3d Tutorial

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.

Page 303: j3d Tutorial

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);

Page 304: j3d Tutorial

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. Don’t 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.

Page 305: j3d Tutorial

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.)

Page 306: j3d Tutorial

tutorial v1.5 (Java 3D API v1.1.2)

Getting Started withthe Java 3D™ API

Chapter 7Textures

Dennis J Bouvier

K Computing

Page 307: j3d Tutorial

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.

Page 308: j3d Tutorial

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

Page 309: j3d Tutorial

Module 3: Lights and Textures Chapter 7. Textures

The Java 3D Tutorial 7-ii

List of FiguresFigure 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

Page 310: j3d Tutorial

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

Page 311: j3d Tutorial

Module 3: Lights and Textures Chapter 7. Textures

The Java 3D Tutorial 7-iv

Page 312: j3d Tutorial

Module 3: Lights and Textures

The Java 3D Tutorial 7-1

7

Textures

Chapter Objectives

After reading this chapter, you’ll 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.

C H A P T E R

Page 313: j3d Tutorial

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 texture1, 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.

Page 314: j3d Tutorial

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 API2. 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.

Page 315: j3d Tutorial

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 process3. 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 Texture2D4 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).

Page 316: j3d Tutorial

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

specification6.

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.

Page 317: j3d Tutorial

Module 3: Lights and Textures Chapter 7. Textures

The Java 3D Tutorial 7-6

1. QuadArray plane = new QuadArray(4, GeometryArray.COORDINATES2. | 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.

Page 318: j3d Tutorial

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 object7 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.

Page 319: j3d 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.

Page 320: j3d Tutorial

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

Page 321: j3d Tutorial

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 plane2. 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 plane7. 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 plane12. 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 plane17. 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.

Page 322: j3d 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

Page 323: j3d Tutorial

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

texelization8.

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.

Page 324: j3d Tutorial

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 BoundaryColorAppdemonstrates 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.

Page 325: j3d Tutorial

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.

Page 326: j3d Tutorial

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 strip9 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.

Page 327: j3d 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.

Page 328: j3d Tutorial

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.

Page 329: j3d Tutorial

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 format10

.

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.

Page 330: j3d Tutorial

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.

Page 331: j3d Tutorial

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.

Page 332: j3d Tutorial

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.

Page 333: j3d Tutorial

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.

Page 334: j3d Tutorial

Module 3: Lights and Textures Chapter 7. Textures

The Java 3D Tutorial 7-23

TexCoord

GenerationTexture

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).

Page 335: j3d Tutorial

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

Page 336: j3d Tutorial

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 performance11

.

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.

Page 337: j3d Tutorial

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 jar12

. 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.

Page 338: j3d Tutorial

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: 1x116. imageLevel++; // compute this level17.

18. if (imageWidth > 1) imageWidth /= 2; // adjust width as necessary19. if (imageHeight > 1) imageHeight /= 2; // adjust height as necessary20.

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).

Page 339: j3d Tutorial

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 04. 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: 1x116. imageLevel++; // compute this level17.

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 load21.

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.

Page 340: j3d Tutorial

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_LINEARwhen 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.

Page 341: j3d Tutorial

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.

Page 342: j3d Tutorial

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.

Page 343: j3d Tutorial

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.

Page 344: j3d Tutorial

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_MIPMAPOptional 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.Objectpackage: 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.

Page 345: j3d Tutorial

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.

Page 346: j3d Tutorial

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?