Hi, all:

I think that I sent wrong file in the previous mail. here are the test
files. Just run java Tree3ele2, you will see the white ground.
I also attached two screen shots in a word file, first one was using
j2sdk1.3.0_02 with j3d1.2.1_03 and the second shot was using j2sdk1.3.1_04
with j3d1.3 running the same code. And I noticed that this appearance
problem only occurs with the IndexedTriangleStripArray. I wondered that
anyone using this type of geometry having  the similar problem.

Any help is appreciated.

Thanks!



>Hi, everyone:
>
>I have been fiddling with this problem for a while but still fail to find
>out the reason. I have a class Elevation to generate the ground Shape3D
>using IndexedTriangleStripArray without vertex color. I have tried to
>assign it with ground color through Appearance object. It worked fine until
>I updated to the new j3d version. Could someone be kind enough to check my
>test code? Thank you in advance!
>
>By the way, the Elevation.java is borrowed from the web just for
>constructing test case. I's like to acknowledge the author whoever he/she is.
>
>
>
>
>
>Lan Wu-Cavener
>Dept. of Landscape Architecture

Attachment: Elevation.class
Description: Binary data

//
//  CLASS
//    ElevationGrid     -  a 3D terrain grid built from a list of heights
//
//  DESCRIPTION
//    This class creates a 3D terrain on a grid whose X and Z dimensions,
//    and row/column spacing are parameters, along with a list of heights
//    (elevations), one per grid row/column pair.
//

//package mip.ivt.demo;

import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.geometry.*;

class Elevation extends Object
{
    // Parameters
    protected int xDimension = 0, zDimension = 0;
    protected double xSpacing = 0.0, zSpacing = 0.0;
    protected double[] heights = null;

    // 3D nodes
//    private Appearance mainAppearance = null;
    private Appearance mainAppearance = new Appearance();
    private Shape3D shape = null;
    private IndexedTriangleStripArray tristrip = null;


     //
     //  Construct an elevation grid
    public Elevation( )
 {
        xDimension = 2;
        zDimension = 2;
        xSpacing = 1.0;
        zSpacing = 1.0;
        mainAppearance = null;
        zeroHeights( );
        rebuild( );
    }

    public Elevation( int xDim, int zDim )
{
        xDimension = xDim;
        zDimension = zDim;
        xSpacing = 1.0;
        zSpacing = 1.0;
        mainAppearance = null;
        zeroHeights( );
        rebuild( );
    }

    public Elevation( int xDim, int zDim,
    Appearance app )
 {
         xDimension = xDim;
        zDimension = zDim;
        xSpacing = 1.0;
        zSpacing = 1.0;
        mainAppearance = app;
        zeroHeights( );
        rebuild( );
    }

     public Elevation( int xDim, int zDim,
                                     double xSpace, double zSpace )
 {
         xDimension = xDim;
         zDimension = zDim;
         xSpacing = xSpace;
         zSpacing = zSpace;
         mainAppearance = null;
         zeroHeights( );
         rebuild( );
     }

     public Elevation( int xDim, int zDim,
     double xSpace, double zSpace,
     Appearance app )
 {
         xDimension = xDim;
         zDimension = zDim;
         xSpacing = xSpace;
         zSpacing = zSpace;
         mainAppearance = app;
         zeroHeights( );
         rebuild( );
     }

     public Elevation( int xDim, int zDim,
     double[] h )
 {
         this( xDim, zDim, 1.0, 1.0, h, null );
     }

     public Elevation( int xDim, int zDim,
     double[] h,
     Appearance app )
 {
         this( xDim, zDim, 1.0, 1.0, h, app );
     }

     public Elevation( int xDim, int zDim,
     double xSpace, double zSpace,
     double[] h )
 {
         this( xDim, zDim, xSpace, zSpace, h, new Appearance() );
     }

     public Elevation( int xDim, int zDim,
     double xSpace, double zSpace,
     double[] h,
     Appearance app )
 {
         xDimension = xDim;
         zDimension = zDim;
         xSpacing   = xSpace;
         zSpacing   = zSpace;
         mainAppearance = app;
         if ( h == null )
             zeroHeights( );
         else
         {
             heights = new double[h.length];
             for ( int i = 0; i < h.length; i++ )
                 heights[i] = h[i];
         }
         rebuild( );
     }


     private void zeroHeights( )
 {
         int n = xDimension * zDimension;
         heights = new double[n];
         for ( int i = 0; i < n; i++ )
             heights[i] = 0.0;
     }



     private void rebuild( )
 {
         // Build a shape
         if ( shape == null )
         {
             shape = new Shape3D( );
             shape.setCapability( Shape3D.ALLOW_APPEARANCE_WRITE );
             shape.setCapability( Shape3D.ALLOW_GEOMETRY_WRITE );
             shape.setAppearance( mainAppearance );
//             addChild( shape );
         }
         else
         {
             shape.setAppearance( mainAppearance );
         }

         if ( xDimension < 2 || zDimension < 2 ||
         heights == null || heights.length < 4 )
         {
             tristrip = null;
             shape.setGeometry( null );
             return;
         }


         // Create a list of coordinates, one per grid row/column
         double[] coordinates = new double[xDimension*zDimension*3];
         double x, z;
         int n = 0, k = 0;
         z = ((double)(zDimension-1)) * zSpacing / 2.0;  // start at front edge
         for ( int i = 0; i < zDimension; i++ )
         {
             x = -((double)(xDimension-1)) * xSpacing / 2.0;// start at left edge
             for ( int j = 0; j < xDimension; j++ )
             {
                 coordinates[n++] = x;
                 coordinates[n++] = heights[k++];
                 coordinates[n++] = z;
                 x += xSpacing;
             }
             z -= zSpacing;
         }

         // Create a list of normals, one per grid row/column
         float[] normals = new float[xDimension*zDimension*3];
         Vector3f one = new Vector3f( 0.0f, 0.0f, 0.0f );
         Vector3f two = new Vector3f( 0.0f, 0.0f, 0.0f );
         Vector3f norm = new Vector3f( 0.0f, 0.0f, 0.0f );
         n = 0;
         k = 0;
         for ( int i = 0; i < zDimension-1; i++ )
         {
             for ( int j = 0; j < xDimension-1; j++ )
             {
                 // Vector to right in X
                 one.set( (float)xSpacing, (float)(heights[k+1] - heights[k]), 0.0f );

                 // Vector back in Z
                 two.set( 0.0f, (float)(heights[k+xDimension] - heights[k]), 
(float)-zSpacing );

                 // Cross them to get the normal
                 norm.cross( one, two );
                 normals[n++] = norm.x;
                 normals[n++] = norm.y;
                 normals[n++] = norm.z;
                 k++;
             }

             // Last normal in row is a copy of the previous one
             normals[n]   = normals[n-3]; // X
             normals[n+1] = normals[n-2]; // Y
             normals[n+2] = normals[n-1]; // Z
             n += 3;
             k++;
         }

         // Last row of normals is a copy of the previous row
         for ( int j = 0; j < xDimension; j++ )
         {
             normals[n]   = normals[n-xDimension*3];   // X
             normals[n+1] = normals[n-xDimension*3+1]; // Y
             normals[n+2] = normals[n-xDimension*3+2]; // Z
             n += 3;
         }

         // Create a list of texture coordinates, one per grid row/column
         float[] texcoordinates = new float[xDimension*zDimension*2];
         float deltaS = 1.0f / (float)(xDimension-1);
         float deltaT = 1.0f / (float)(zDimension-1);
         float s = 0.0f;
         float t = 0.0f;
         n = 0;
         for ( int i = 0; i < zDimension; i++ )
         {
             s = 0.0f;
             for ( int j = 0; j < xDimension; j++ )
             {
                 texcoordinates[n++] = s;
                 texcoordinates[n++] = t;
                 s += deltaS;
             }
             t += deltaT;
         }

         // Create a list of triangle strip indexes.  Each strip goes
         // down one row (X direction) of the elevation grid.
         int[] indexes = new int[xDimension*(zDimension-1)*2];
         int[] stripCounts = new int[zDimension-1];
         n = 0;
         k = 0;
         for ( int i = 0; i < zDimension-1; i++ )
         {
             stripCounts[i] = xDimension*2;
             for ( int j = 0; j < xDimension; j++ )
             {
                 indexes[n++] = k+xDimension;
                 indexes[n++] = k;
                 k++;
             }
         }


         // Create geometry for collection of triangle strips, one
         // strip per row of the elevation grid
         tristrip = new IndexedTriangleStripArray(
         coordinates.length,
         GeometryArray.COORDINATES |
         GeometryArray.NORMALS |
         GeometryArray.TEXTURE_COORDINATE_2,
         indexes.length,
         stripCounts );
         tristrip.setCoordinates( 0, coordinates );
         tristrip.setNormals( 0, normals );
         tristrip.setTextureCoordinates( 0, texcoordinates );
         tristrip.setCoordinateIndices( 0, indexes );
         tristrip.setNormalIndices( 0, indexes );
         tristrip.setTextureCoordinateIndices( 0, indexes );

         // Set the geometry for the shape
         shape.setGeometry( tristrip );
     }


     //
     //  Control the appearance
     //
     public void setAppearance( Appearance app )
 {
         mainAppearance = app;
         if ( shape != null )
             shape.setAppearance( mainAppearance );
     }


     //
     //  Control grid parameters
     //
     public void setHeights( double[] h )
 {
         if ( h == null )
             zeroHeights( );
         else
         {
             heights = new double[h.length];
             for ( int i = 0; i < h.length; i++ )
                 heights[i] = h[i];
         }
         rebuild( );
     }
     public double[] getHeights( )
 {
         return heights;
     }

     public void setXDimension( int xDim )
 {
         xDimension = xDim;
         rebuild( );
     }
     public int getXDimension( )
 {
         return xDimension;
     }

     public void setZDimension( int zDim )
 {
         zDimension = zDim;
         rebuild( );
     }
     public int getZDimension( )
 {
         return zDimension;
     }

     public void setXSpacing( double xSpace )
 {
         xSpacing = xSpace;
         rebuild( );
     }
     public double getXSpacing( )
 {
         return xSpacing;
     }

     public void setZSpacing( double zSpace )
 {
         zSpacing = zSpace;
         rebuild( );
     }
     public double getZSpacing( )
 {
         return zSpacing;
     }


     //
     //  Provide info on the shape and geometry
     //
     public Shape3D getShape( int partid )
 {
         return shape;
     }

     public int getNumTriangles( )
 {
         return xDimension * zDimension * 2;
     }

     public int getNumVertices( )
 {
         return xDimension * zDimension;
     }
 }


Attachment: Tree3ele2.class
Description: Binary data

import java.applet.Applet;
import com.sun.j3d.utils.applet.MainFrame;
import java.awt.*;

import java.awt.event.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import com.sun.j3d.utils.behaviors.vp.*;
import com.sun.j3d.utils.behaviors.mouse.*;
import com.sun.j3d.utils.image.TextureLoader;
import java.io.*;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.geom.AffineTransform;

public class Tree3ele2 extends Applet implements ActionListener
{
        protected final static Color3f White    = new Color3f( 1.0f, 1.0f, 1.0f );
        protected final static Color3f Green    = new Color3f( 0.0f, 1.0f, 0.0f );
        protected static final Color3f brown  = new Color3f( 0.78f, 0.2f, 0.1f );
        protected static final Color3f bkground = new Color3f(.761f, .973f, .969f);
        private final static Color3f groundAmbient = new Color3f( 0.6f, 0.4f, 0.3f );
        private final static Color3f groundEmissive = new Color3f( 0.2f, 0.1f, 0.05f );
        private final static Color3f groundDiffuse = new Color3f( 0.7f, 0.5f, 0.4f );
        private final static Color3f groundSpecular = new Color3f( 0.8f, 0.6f, 0.6f );

        private SimpleUniverse u;
        private Canvas3D vFstCanvas3D;
        private BoundingSphere bounds;
        ViewingPlatform viewingPlatform;

        public static TransformGroup vpTransformGroup, joyTransformGroup;

    public void init() {
                BranchGroup bg = new BranchGroup();
        GraphicsConfiguration config =
                                                 
SimpleUniverse.getPreferredConfiguration();
                vFstCanvas3D = new Canvas3D( config )
                {
                                Dimension canvasPrefSize = new Dimension( 600, 800 );
                                public Dimension getPreferredSize() { return 
canvasPrefSize; }
                };

                u = new SimpleUniverse(vFstCanvas3D,2);
                setLayout( new BorderLayout() );
                add( vFstCanvas3D, BorderLayout.CENTER );

                viewingPlatform = u.getViewingPlatform();
                MultiTransformGroup multi = viewingPlatform.getMultiTransformGroup();
        joyTransformGroup = multi.getTransformGroup(0);
        vpTransformGroup = multi.getTransformGroup(1);

                viewingPlatform.setNominalViewingTransform();

        long initTime = System.currentTimeMillis();
                bg = createSceneGraph();
        System.out.println("Time taken to create 
BranchGroup:"+(System.currentTimeMillis() - initTime));

                u.addBranchGraph( bg );

        }


    public void actionPerformed(ActionEvent e) {

        }

    public BranchGroup createSceneGraph() {

                BranchGroup objRoot = new BranchGroup();


        // ground

        Appearance app = new Appearance();
        Material groundMa = new Material( groundAmbient,
                groundEmissive, new Color3f(0.6f, 0.6f, 0.6f), groundSpecular, 30.0f );
        groundMa.setLightingEnable( true );
        RenderingAttributes ra1 = new RenderingAttributes();
        ra1.setIgnoreVertexColors(true);
        app.setRenderingAttributes(ra1);
        app.setMaterial(groundMa);


        double height[] = new double[126];
        for (int i=0; i<63; i++)
                height[i]=0.d;
        for (int i=63; i<70; i++)
                height[i]=.5d;
        for (int i=70; i<74; i++)
                height[i]=.5d;
        for (int i=74; i<77; i++)
                height[i]=.2d;
        for (int i=77; i<81; i++)
                height[i]=.0d;
        for (int i=81; i<126; i++)
                height[i]=.2d;

        Elevation ele = new Elevation( 7, 18, 2, 3, height, app);

        Transform3D t = new Transform3D();
                // move the object upwards
        t.set(new Vector3f(0.0f, -.50f, 0.f));
    t.setScale(0.1);
        TransformGroup trans = new TransformGroup(t);
        trans.addChild(ele.getShape(0));
        objRoot.addChild(trans);


        OrbitBehavior orbit = new OrbitBehavior(vFstCanvas3D, 
OrbitBehavior.REVERSE_ALL);
        BoundingSphere bounds =
            new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
        orbit.setSchedulingBounds(bounds);
        viewingPlatform.setViewPlatformBehavior(orbit);


        //      add light
        Vector3f LightDirection = new Vector3f( -.70f, -.70f, -.50f );
        DirectionalLight dirLight = new DirectionalLight(
                new Color3f(1.f, 1.f, 1.f), LightDirection );
        dirLight.setInfluencingBounds( bounds );
        objRoot.addChild( dirLight );

        BoundingLeaf boundingLeaf = new BoundingLeaf( bounds );
        objRoot.addChild( boundingLeaf );

        // add backgroud
        Background background = new Background();
        background.setColor( bkground );
        background.setCapability( Background.ALLOW_COLOR_WRITE );
        background.setApplicationBoundingLeaf(boundingLeaf);
        objRoot.addChild( background );

        objRoot.compile();

        return objRoot;
    }


    public static void main(String[] args) {
        Tree3ele2 treeTest = new Tree3ele2();
                new MainFrame(treeTest, 1024, 512);

    }

}
Lan Wu-Cavener
Dept. of Landscape Architecture

Reply via email to