|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SYS-CON.TV |
TOP THREE LINKS YOU MUST CLICK ON Advanced Java Bringing Mars Down to Earth with Java3D
Exploring Java3D
By: Mike Jacobs
Jun. 3, 2004 12:00 AM
You've probably seen the breathtaking photographs of the surface of Mars from the rovers Spirit and Opportunity. You've also seen the amazing high-altitude photographs taken from satellites orbiting Mars. But let's face it, the rovers must land on flat, boring areas and the satellites are too high above the interesting places like canyons and craters. What is an Earth-bound Java programmer to do? Using the Java3D API and publicly available data, you can create pictures like Figure 1. The Java3D API is robust enough to handle just about any 3D programming job. The complexity can also make a grown man cry. This article covers the Java3D basics with an emphasis on producing something from another world without the tears. We'll first go over the anatomy of a scene - how to add shapes to the scene, light it, and explore it by moving the view. In the end you'll have a way to explore any location on Mars from any angle moving through the landscape in real time. What Is Java3D? Your Java3D universe consists of a tree structure called a scene graph that contains the shapes, lights, and virtual cameras called views. Java3D automatically renders the scene, properly lighting the shapes based on the view, and changing the view based on user input. Java3D takes care of details like removing hidden surfaces and applying textures to surfaces. The scene graph is the center of your Java3D universe. Creating a Scene Figure 2 shows additional objects that make up the view branch, which are beyond the scope of this article. Luckily, Java3D has a SimpleUniverse utility class so it's easy to create the universe and view branch. The SimpleUniverse object allows you to add your content branch and access the view transform group to change the view. The content branch contains the shapes and lights in your scene. User interaction with the scene is accomplished by adding behaviors to the content branch. A behavior links keyboard, mouse, or temporal events with changes to the content or view. For example, the keyboard or mouse can be used to update the view transform, allowing the user to move the virtual camera through the scene. Time can be used to animate the movement or morphing of shapes in your scene. For our purposes we'll use a modified version of the Java3D KeyNavigator behavior to move over the surface of Mars. There are many other predefined behaviors in Java3D and you can create your own as well. The following code shows how to build the universe and scene. ... 1 canvas = new Canvas3D(config); 2 universe = new SimpleUniverse(canvas); 3 BranchGroup content=createSceneGraph(); 4 addBehaviors(content); 5 addLights(content); 6 content.compile(); 7 universe.addBranchGraph(content); // The scene is ready to render This code includes the steps taken in the Java3DApplication class included in the source code. (The source code for this article can be downloaded from www.sys-con.com/java/sourcec.cfm.) This class implements a common recipe for Java3D applications. Shaping Up The geometry object determines the topology of the shape. There are several utility geometries available to create cubes, spheres, cylinders, and cones. These utility geometries are useful for learning, prototyping, or even assembling larger composite visual objects. More complex geometries can be created with subclasses of GeometryArray that organize arrays of triangles, lines, points, or quadrilaterals. Creating geometries with the GeometryArray subclasses is complex, but thankfully the GeometryInfo utility class drastically simplifies the process. We'll use the GeometryInfo class with a QuadArray to create the landscape geometry for Mars. The appearance object is used to describe the color, material, polygon, texture, and transparency attributes of a shape (see Figure 3). A ColoringAttributes object defines the color of the shape in an unlit scene as well as the type of shading to use (i.e., flat or smooth). The Material object specifies the color of the entire shape in a lit scene as well as the shininess of the shape. The PolygonAttributes object is used to render the shape as points, a wire frame, or a solid, and determine which polygons are to be culled. The TextureAttributes object controls how textures are combined with the shape color if the shape is textured. Texturing is valuable when there is a need to present a higher level of detail than what is available with the geometry. As you might have guessed by now, the TransparencyAttributes object helps you render objects such as glass or water. Now that you have your shape defined with a geometry and appearance, all you have left to do is add the shape to the content branch group. This is done by using the addChild() method on the branch group. Shedding Light on Your Scene A typical scene uses ambient light combined with two directional lights. Our Mars landscape uses ambient light and two spotlights. Creating the Landscape of Mars One of the instruments aboard the MGS was the Mars Orbiter Laser Altimeter (MOLA). If you've been to a home improvement store lately you'll conceptually understand how this instrument works. The latest home improvement gadget is a laser measuring tape. You point the gadget at a wall and it precisely measures the distance between you and the wall. The MOLA took over one billion measurements while the MGS circled the planet for 2.5 years. At the highest precision, those results were used to create a huge matrix of altitude measurements every 0.00781 degrees of longitude and latitude. This high precision data can detect objects as small as 460 meters, making it ideal for major terrain features, but you won't see the rock-level details seen in rover photographs. Today this data is used by NASA for mission planning and is available for the public to download as MOLA Mission Experiment Gridded Data Records (MEGDR). The MEGDR data is available at other resolutions as well, providing us with a wealth of geometry data. The MOLA data can be used with a Java3D QuadArray object to create an accurate Mars geometry. The MOLA data is organized as a large two-dimensional matrix with the longitude and latitude serving as the dimensions. The value at a given longitude and latitude is the average altitude for that area. A QuadArray object can be used to draw an array of vertices as individual quadrilaterals using a group of four vertices to define a quadrilateral. We'll use four neighboring MOLA data elements as vertices to create a series of quadrilaterals across an area of interest. The geometry of the planet surface is created by mapping the longitude, latitude, and altitude of the MOLA data to three-dimensional points needed for the vertices of the QuadArray. The following code uses GeometryInfo to easily create a geometry object. ... 1 GeometryInfo gi = new GeometryInfo(GeometryInfo.QUAD_ARRAY); 2 ... // Map MOLA data to 3D points in // Point3d[] coordinates variable 3 gi.setCoordinates(coordinates); 4 // Other texture or coloring tasks 5 NormalGenerator ng = new ormalGenerator(); 6 ng.generateNormals(gi); 7 Geometry g = gi.getGeometryArray(); Once the MOLA data is converted into three-dimensional points, a NormalGenerator can be used to finish the geometry object. A normal is a unit vector that defines the orientation of a surface such as a quadrilateral or triangle. Java3D uses the normal of a surface for hidden surface removal and to render the lighting effects of visible surfaces. The NormalGenerator computes the normal vectors for the quadrilaterals in the QuadArray and stores the results in the GeometryInfo object. You may have noticed that we skipped over line 4. This is where some impressive effects can be implemented with Java3D: vertex coloring and texture mapping. Vertex Coloring Texture Mapping The number of files in the MDIM poses a challenge to allow the rendering of any location. The MDIM is divided into regions based on the USGS Mars Chart (MC) series of printed maps. The MC regions form a staggered grid and the most useful, high-resolution images are far too large to create one large composite image. The solution is to use the imaging support provided by ImageIO, BufferedImage, and AffineTransform objects to create our own personal mosaic of the area to be rendered. Once this image is created it can be used with Java3D as a photographic overlay. As Figure 1 shows, Java3D supports the draping of a photograph over the geometry through texture mapping. Java3D automatically renders the photograph as a texture, provided we tell Java3D how to map the pixels in the texture to the vertices in the geometry. Java3D uses a simple texture coordinate system that specifies the horizontal and vertical texture coordinates as values ranging between zero and one. Similar to how we demonstrated vertex colors, texture coordinates must be determined for each geometry vertex. An array of texture coordinates is then set on the GeometryInfo object by using the setTextureCoordinates() method. To finish the appearance of the landscape, the texture and how to combine it with the geometry color is set in the TextureAttributes object. There are many ways to combine the texture color with the geometry color, but we'll use the MODULATE option. This option takes the product of the texture and geometry colors to create the final color. Colors in Java3D use the RGB model with each color component ranging between zero and one. Because the Mars photographs are black and white, the resulting product is a very realistic coloring of the landscape. Finishing Touches The atmosphere in Figure 1 is accomplished by surrounding the scene with a huge textured sphere. The sphere is one of the geometries supplied by Java3D that can automatically create normal vectors and texture coordinates. Simply provide the color and texture in an appearance object and Java3D combines them to create a sky sprinkled with wispy clouds. The atmosphere comes alive when we light it up with a sun. Our Mars landscape uses ambient light and two spotlights to create the sun in the dusty atmosphere. Here is where we can take advantage of a missing feature of Java3D. Because of the computational requirements, Java3D does not automatically render true shadows. Consequently, light passes through objects and fully lights the area where shadows would naturally occur. The sun can be implemented with a spotlight just outside of the atmosphere sphere. Java3D renders the concentrated light on the sphere as a circle and light passes through the sphere to light the planet surface below. A second spotlight with a wider spread is used to create an aura of the sun. The lighting effects of the spotlights on the atmosphere sphere give the impression of a sun shining down on the landscape. Explore Away References Acknowledgments
Copyright 2004 © Mayo Foundation for Medical Education and Research LATEST JAVA STORIES & POSTS
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK SPONSORED BY INFRAGISTICS
BREAKING JAVA NEWS
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||