6.5 Using multiple views Multiple views can be a useful technique for rendering different views of the created scene. Multiple views are often used in CAD or 3D-editor applications to display the three orthogonal views of an object (side, top, front) as well as an interactive camera view. For complex 3D manipulation, multiple views are sometimes the only way to give the user the required degree of control for interactive object manipulation. There are a few issues that you should be aware of if you opt to use multiple views. 6.5.1 Billboards and LOD behaviors Java 3D implements Billboard(rotate the object to face the viewer) and LOD(vary the geometry of objects depending on distance from viewer) as operations that directly manipulate the scenegraph. This obviously has implications when there is more than one viewer: if the Billboard Behaviorrotates an object to face Viewer1, it cannot simultaneously rotate the object to face Viewer2. If there is more than one active View, the Billboardand LOD Behaviorswill use the orientation and distance information from the first Viewattached to the live ViewPlatform. This is defined as the primary Viewfor the Behaviorand can be returned using the Behavior.getView()method. The OrientedShape3Dclass defines a variant of the Shape3Dclass that is always aligned to face the viewer, irrespective of View. Sun will be offering more complete support for multiple Viewsin forthcoming releases, so check the latest details at the Sun Java 3D site. 6.6 Summary By now you should have some good ideas as to how you will assemble your application from the components supplied by the Java 3D API, as well as many of the capabilities of the API. The VirtualUniverseclass provides flexibility in defining your application s view of your virtual world while the SimpleUniverse class abstracts some of the underlying details and provides a good starting point for simple applications or prototypes. Java 3D s view model includes built-in support for some powerful features: multiple Locales for very large worlds, rendering to stereoscopic displays, geometry to represent both the view and the viewer, and a physical environment for the view. We have only been able to touch on many of the capabilities many more are introduced in later chapters. If you are interested in using the VirtualUniverseclass directly please refer to chapter 17 and the SwingTest example, which builds up the scenegraph from scratch using VirtualUniverse. In the next chapter, we will start to discuss the important question of the data model you should adopt for your application. Your data model design will ideally be efficient for rendering, while flexible and maintainable enough to satisfy your application and development goals. 96
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
CHAPTER 7 Data model design 7.1 Choosing a data model 7.2 Performance objectives 7.3 Summary By thinking about the requirements of your data model in a conscious way early on in your development cycle, you can make Java 3D rendering an implementation of a view into your data model rather than the data model itself. Fundamentally you will have to decide upon an internal data model suitable for your application. This will be one of the following types: Surface (skin) model Voxel (volume) model Mathematical parametric model The decisions you make in this chapter will probably have the greatest impact upon your application performance. From the outset you should be intimately aware of the performance objectives for your application and the features your data model will have to support. 7.1 Choosing a data model When designing your 3D application the obvious place to start is to consider your user s view of the application. Everything that is rendered (drawn) by the underlying Java 3D scenegraph renderer can be described as geometry. Discussions of geometry are generally independent of such issues as user interaction, view parameters and rotation, rendering attributes, and object lighting. The geometry defined in your scene is rendered by the Java 3D renderer using the current view parameters and the geometry s attributes, such as color, material, and lighting. The choice of geometry description will probably be the most influential factor in deciding eventual application performance. Deciding the geometry description will always entail making several compromises between contradictory factors such as rendering speed and quality, size of data models, asset managements and load time. A simple 3D model viewer might simply load a 3D model file (perhaps in VRML format), use a Java 3D file loader to convert the model into Java 3D objects, then render it. For interactive applications however (such as games requiring complex character animation) or scientific visualization applications dealing with large data sets, such a simple approach will rarely suffice. 3D character animation may require that a data model support animation using inverse kinematics, that it implement skin-and-bones animation systems that can be scripted, or that it have data from motion capture devices played back through the characters. The Cosm team (http://www.cosm-game.com) is busy creating an online world built using Java and Java 3D that includes skin-and-bones character animation. You can also download some sample code for skin-and-bones animation from http://www.j3d.org. 97
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
viewer.setAvatar( viewerAvatar ); 6.4 Background geometry Background geometry is assumed to be positioned at infinite distance, that is, no perspective calculations need to be performed. It is also assumed that it has been tessellated onto a unit sphere. In addition, a background color, an image, and the bounds within which the background is active can be specified. Background geometry is rendered after the background image has been drawn. See figures 6.8 6.10. Figure 6.8 Sphere background geometry. A texture image was applied to the sphere and normal vectors generated such that the texture is visible when viewed from within the sphere Figure 6.9 Sphere used as background geometry, rendered as a wireframe with an applied texture image 94
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
Figure 6.10 The texture image used to generate the sunset effect used in AvatarTest.java. Note that the texture coordinates set by the sphere primitive require that the sunset portion of the image be split in half and inverted From AvatarTest.java //To set a Background image: ImageComponent2D image = new TextureLoader( “sky.jpg”, this).getScaledImage( 1300,1300 ); Background back = new Background( image ); back.setApplicationBounds( getBoundingSphere() ); //To set Background Geometry: Background back = new Background(); BranchGroup bgGeometry = new BranchGroup(); Appearance ap = new Appearance(); Texture tex = new TextureLoader( “back.jpg”, this).getTexture(); ap.setTexture( tex ); Sphere sphere = new Sphere( 1.0f, Primitive.GENERATE_TEXTURE_COORDS | Primitive.GENERATE_NORMALS_INWARD, ap ); bgGeometry.addChild( sphere ); back.setGeometry( bgGeometry ); The foregoing examples have the effect of setting a background image. However, the second approach, using a texture-mapped sphere with the image applied, has an advantage: the texture image is automatically scaled when it is applied to the sphere. In the first example, the background image must be manually scaled to correspond to the size of the rendering window. If the rendering window is resizable, the image must be rescaled or it will merely be painted into the top left corner of the rendering window. Applying the image as a texture may also render considerably faster depending upon your rendering hardware. In the second example, note that the normal vectors generated for the Spheremust point inward because the viewer is inside the generated Sphereand views the texture applied to the inside of the Sphere. Alternately, the sphere s PolygonAttributescan be set to CULL_NONEto render triangles with Normal vectors pointing away from the viewer. 95
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
Figure 6.7 A frame rendered by AvatarTest. The viewer s avatar is the large cube in the center of the frame From AvatarTest.java (see also PlatformTest.java) //Create a simple scene and attach it to the virtual universe SimpleUniverse u = new SimpleUniverse(); //Add everything to the scene graph it will now be displayed. BranchGroup scene = sg.createSceneGraph(); u.addBranchGraph(scene); PlatformGeometry pg = sg.createPlatformGeometry(); //set the just created PlatformGeometry. ViewingPlatform vp = u.getViewingPlatform(); vp.setPlatformGeometry(pg); //or Viewer viewer = u.getViewer(); ViewerAvatar viewerAvatar = new ViewerAvatar(); viewerAvatar.addChild( sg.createViewerAvatar() ); 93
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
There is nothing magical about the geometry that represents the viewer; it may be easier, and more consistent in your application, to represent the viewer using a separate BranchGroupattached to the root of your scenegraph. SimpleUniverseis defined in the Java 3D utilities package (com.sun.java.j3d.utils) along with the Viewer, ViewerAvatar, and ViewingPlatform classes. These classes are merely defined for convenience; it may be safer to use the core Java 3D scenegraph management classes. That said, here is a short example of using setPlatformGeometryto assign geometry for the Viewer; the output is shown in figures 6.6 6.7. Figure 6.6 A frame rendered by AvatarTest. The viewer s avatar is the large cube to the right of the frame 92
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
Transform3D t3d = new Transform3D(); t3d.setEuler( new Vector3d( Math.PI / 2.0, Math.PI, 0 ) ); tg.setTransform( t3d ); //create appearance and material for the Cone Appearance app = new Appearance(); Color3f black = new Color3f(0.4f, 0.2f, 0.1f); app.setMaterial(new Material(objColor, black, objColor, black, 90.0f)); //create the Primitive and add to the parent BranchGroup tg.addChild( new Cone( 1, 3, Primitive.GENERATE_NORMALS, app ) ); viewerAvatar.addChild( tg ); return viewerAvatar; } //create a simple Raster text label used to help identify //the viewer. PlatformGeometry createPlatformGeometry( String szText ) { PlatformGeometry pg = new PlatformGeometry(); pg.addChild( createLabel( szText, 0f, 2f, 0f ) ); return pg; } //creates a simple Raster text label (similar to Text2D) private Shape3D createLabel( String szText, float x, float y, float z ) { BufferedImage bufferedImage = new BufferedImage( 25, 14, BufferedImage.TYPE_INT_RGB ); Graphics g = bufferedImage.getGraphics(); g.setColor( Color.white ); g.drawString( szText, 2, 12 ); ImageComponent2D imageComponent2D = new ImageComponent2D( ImageComponent2D.FORMAT_RGB, bufferedImage ); //create the Raster for the image javax.media.j3d.Raster renderRaster = new javax.media.j3d.Raster( new Point3f( x, y, z ), javax.media.j3d.Raster.RASTER_COLOR, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), imageComponent2D, null ); return new Shape3D( renderRaster ); } 6.3.1 Avatars and platform geometry The SimpleUniverseclass allows you to attach geometry to the viewer of your 3D scene. There are two methods of attaching viewer geometry using the SimpleUniverseclass: ViewingPlatform.setPlatformGeometryor Viewer.setAvatar. The ViewingPlatform can be accessed from the SimpleUniverseby calling getViewingPlatformor calling getViewer to access the Viewerobject. There does not seem to be any difference between these two methods. 91
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
From PlatformTest.java //This method creates the SimpleUniverse View and ViewPlatform //scenegraph elements to create an avatar that has an associated //Canvas3D for rendering, a PlatformGeometry, ViewerAvatar, and a //KeyNavigator to allow movement of the ViewerAvatar with the //keyboard. ViewingPlatform createViewer( Canvas3D c, String szName, Color3f objColor, double x, double z ) { //create a Viewer and attach to its canvas. A Canvas3D can //only be attached to a single Viewer. Viewer viewer2 = new Viewer( c ); //create a ViewingPlatform with 1 TransformGroup above the //ViewPlatform ViewingPlatform vp2 = new ViewingPlatform( 1 ); //create and assign the PlatformGeometry to the Viewer vp2.setPlatformGeometry( createPlatformGeometry( szName ) ); //create and assign the ViewerAvatar to the Viewer viewer2.setAvatar( createViewerAvatar( szName, objColor ) ); //set the initial position for the Viewer Transform3D t3d = new Transform3D(); t3d.setTranslation( new Vector3d( x, 0, z ) ); vp2.getViewPlatformTransform().setTransform( t3d ); //set capabilities on the TransformGroup so that the //KeyNavigatorBehavior can modify the Viewer’s position vp2.getViewPlatformTransform().setCapability( TransformGroup.ALLOW_TRANSFORM_WRITE ); vp2.getViewPlatformTransform().setCapability( TransformGroup.ALLOW_TRANSFORM_READ ); //attach a navigation behavior to the position of the viewer KeyNavigatorBehavior key = new KeyNavigatorBehavior( vp2.getViewPlatformTransform() ); key.setSchedulingBounds( m_Bounds ); key.setEnable( false ); //add the KeyNavigatorBehavior to the ViewingPlatform vp2.addChild( key ); //set the ViewingPlatform for the Viewer viewer2.setViewingPlatform( vp2 ); return vp2; } //creates and positions a simple Cone to represent the Viewer. //The Cone is aligned and scaled such that it is similar to a 3D //”turtle”. ViewerAvatar createViewerAvatar( String szText, Color3f objColor ) { ViewerAvatar viewerAvatar = new ViewerAvatar(); //rotate the Cone so that it is lying down and the sharp end //is pointed toward the Viewer’s field of view. TransformGroup tg = new TransformGroup(); 90
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
Figure 6.3 Overhead view of the virtual arena with two avatars: Dan and Jim Figure 6.4 The view for avatar Jim Jim can see Dan Figure 6.5 The view for avatar Dan Dan can see Jim The example is too lengthy to be included in its entirety but some illustrative excerpts have been extracted: 89
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
Figure 6.2 The SimpleUniverse class encapsulates the details of the view side of the scenegraph (lower branch). The ViewingPlatform has been highlighted and contains a MultiTransformGroup composed of two TransformGroups. Attached to the ViewPlatform are a PlatformGeometry Group and a ViewerAvatar Group. By attaching a Key behavior to one of the TransformGroups in the MultiTransformGroup, the View, PlatformGeometry, and ViewerAvatar can all be moved simultaneously and rendered into the Canvas3D attached to the view SimpleUniverseis a bit of a misnomer since the class is anything but simple, and this can cause initial confusion because of the plethora of support classes that it relies upon. SimpleUniverseintroduces five new (non-core-API) classes: Viewer, a container class that keeps references to the following: ViewerAvatar, a representation of the viewer of the scene. Canvas3D, used for rendering the scene. AWT Framecontains the Canvas3Dused for rendering. PhysicalBodyreferences the view s PhysicalBody. PhysicalEnvironmentreferences the view s PhysicalEnvironment. View is used for the viewer of the scene. ViewingPlatform(extends BranchGroup) helps set up the Viewside of the scenegraph by creating a hierarchy of TransformGroupsabove the ViewPlatformwhere the view is attached to the scenegraph. The hierarchy of TransformGroupsis encapsulated in a MultiTransformGroup. In this way a series of transformations can be applied to the view irrespective of transformations that are applied on the geometry side of the scenegraph. ViewerAvatar(extends BranchGroup) contains the geometry used to render the viewer s virtual self in the virtual environment. MultiTransformGroupis a simple encapsulation of a Vectorof TransformGroups. PlatformGeometry(extends BranchGroup) contains the geometry associated with the viewer s ViewingPlatform. For example, in a multiplayer gaming scenario, each player might be able to drive one of several vehicles. A ViewingPlatformwould represent each vehicle in the scenegraph, and the geometry for the vehicle would be attached to the ViewingPlatform. The player would be represented by geometry attached to the ViewerAvatar, which in turn would govern another player s view of the player, while the ViewingPlatformwould contain the geometry to describe the internal characteristics of the vehicle the player was riding in. By attaching the view to different ViewingPlatforms, the player can move between vehicles. In the PlatformTest example, two avatars (Dan and Jim) and three views are created: overhead, Dan s, and Jim s (figures 6.3 6.5). Each Avataris assigned ViewerAvatargeometry (a simple Cone pointing in the direction of view) and PlatformGeometry(a text label to identify the avatar). 88
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services