Examining a Model s Scene Graph


Displaying a Model

Once a model is loaded, it's displayed inside the scene. This simple task is complicated by the need to make sure that the model is positioned, oriented, and scaled so the user can see all of it.

I've simplified the problem by making some assumptions about how the model should be reoriented and scaled: a loaded model is always rotated clockwise around the x-axis by 90 degrees and scaled to be no bigger than 10 world units across. I don't bother repositioning the model since all the examples I tested were located close to the origin after they'd been scaled.

Why the rotation? Most of the models I'm using were created with 3D Studio Max, which uses a different axis system from Java 3D. The axes in 3D Studio Max use the XY plane as the floor, with the z-axis as the vertical; Java 3D treats the XZ plane as the floor and the y-axis as the vertical. The difference can be seen by considering a vector displayed in the two systems. The vertical vector (0, 0, 1) in 3D Studio Max will point forward in Java 3D (see Figure 16-5).

Figure 16-5. The vector (0,0,1) in 3D Studio Max and Java 3D


A model that's upright in 3D Studio Max will be displayed face down when loaded into a Java 3D scene. The solution? Rotate the model clockwise around the x-axis by 90 degrees to bring it back upright.

The rotation and the scaling operations are applied to the model via a transformGroup node placed between the model's BranchGroup node (loadedBG in Figure 16-6) and the sceneBG BranchGroup node (the top-level node of the scene). Figure 16-6 shows the scene graph fragment for the model. In practice, the model subgraph below loadedBG will be more complex than the one shown here.

Figure 16-6. Scene graph fragment for the loaded model


The code that creates this graph is located inloadModel( ) and executed just after the model has been loaded:

     loadedBG = loadedScene.getSceneGroup( );    // model's BG     Transform3D t3d = new Transform3D( );     t3d.rotX( -Math.PI/2.0 );       // rotate     Vector3d scaleVec = calcScaleFactor(loadedBG);  // scale     t3d.setScale( scaleVec );     TransformGroup tg = new TransformGroup(t3d);     tg.addChild(loadedBG);     sceneBG.addChild(tg);   // add (tg->loadedBG) to scene

The code is simple since it applies a rotation to every loaded model, even those that are correctly oriented.

The rotation operation is

     t3d.rotX(-Math.PI/2.0);

This specifies a negative rotation of 90 degrees about the x-axis according to Java 3D's righthand rule for rotations: place your closed right hand with its thumb pointing in the direction of the positive axis of interest, (the x-axis in this case) and your fingers will be bent in the direction of a positive rotation (see Figure 16-7).

Figure 16-7. Righthand, positive rotation for the x-axis


In this case, I want the model to rotate clockwise around the x-axis, which is a negative angle according to the righthand rule.

Scaling the Model

A model may become large when loaded into Java 3D's coordinate space. This can be corrected by using the object's bounding box to calculate a suitable scaling factor. This approach is employed in calcScaleFactor( ):

     private Vector3d calcScaleFactor(BranchGroup loadedBG)     {        BoundingBox boundbox = new BoundingBox( loadedBG.getBounds( ) );        // obtain the upper and lower coordinates of the box        Point3d lower = new Point3d( );        boundbox.getLower( lower );        Point3d upper = new Point3d( );        boundbox.getUpper( upper );        // calculate the maximum dimension        double max = 0.0;        if( (upper.x - lower.x ) > max )          max = (upper.x - lower.x );        if( (upper.y - lower.y ) > max )          max = (upper.y - lower.y );        if( (upper.z - lower.z ) > max )          max = (upper.z - lower.z );        double scaleFactor = 10.0/max;        // limit the scaling so that a big model isn't scaled too much        if( scaleFactor < 0.0005 )           scaleFactor = 0.0005;        return new Vector3d(scaleFactor, scaleFactor, scaleFactor);     }  // end of calcScaleFactor( )

The scaling factor will leave the model at most 10 units wide, high, or deep, which is comparable to the size of the floor (20 units square).

The scale factor reduction is constrained so a large model isn't shrunk too much. This problem occurs when one dimension of the model is large (for example, its height), but the other dimensions are small. An unconstrained reduction applied to the height will leave the width and depth so small that the model will be almost invisible.



Killer Game Programming in Java
Killer Game Programming in Java
ISBN: 0596007302
EAN: 2147483647
Year: 2006
Pages: 340

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net