Codes attached.

Hi,

I am using Java3d 1.2 and JDK 1.3
I am trying to use byReference flag of GeometryArray.
I have a couple of problems to report:

- If I comment the line itsArray.setNormalRef3f (...) in GeometryHelper
class,
I get an exception.
The main method is in IndexTest.java

- If I use the geometry array returned by createIndTriStripArray (...) in a
geometryArray
and try ot create a Morph object out of this (as in TestMorphBehavior.java),
it gives me
an exception. If I disable the BY_REFERENCE flag and change the
corresponding set methods,
it works fine. However, this does not help me if I want to modify geometries
later.
If I use it without the BY_REFERENCE flag, and later on modify the geometry
array and do
a setGeometryArrays on the morph object, the behavior is as expected except
that the
geometries are not visible on the screen.

Any clues as to what I might be doing wrong?

Thanks,
Sameer


/*
 * GeometryHelper.java      1.0     08/09/2000
 *
 * Copyright (c) 2000-2005 Liqwid Krystal Inc.
 * Pearl House, 9/3 Museum Road, Bangalore, 560 001, India.
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of Liqwid
 * Krystal, Inc. ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Liqwid Krystal.
 */


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


/**Helper class for performing calculations for geometry and appearance
 * generation. 
 */
public class GeometryHelper
{

    /**The spline is required for calculating the surface that is to be
     * generated, <b>SHOULD BE REMOVED</b>.
     */
    // BiCubicSpline spline = new BiCubicSpline ();

    /**Method to retrieve an appearance object for use with the shape.
     */
    public Appearance getPageAppearance (ImageComponent2D image)
    {
        if (image == null)
        {
            return null;
        }

        Texture2D texture = new Texture2D (Texture2D.BASE_LEVEL, Texture2D.RGB,
                                        image.getWidth(), image.getHeight());
        texture.setImage (0, image);
        texture.setEnable (true);
        texture.setCapability (Texture.ALLOW_IMAGE_WRITE);
        TextureAttributes tAttrib = new TextureAttributes ();
        tAttrib.setTextureMode (tAttrib.MODULATE);

        Appearance pageAppearance = new Appearance ();
        pageAppearance.setTexture (texture);
        pageAppearance.setTextureAttributes (tAttrib);

        return pageAppearance;
    }

    /**Method to retrieve an appearance object for use with the shape.
     * @param image, the BufferedImage to use
     * @return an Appearance object with the image used as a texture.
     */
    public Appearance getPageAppearance (BufferedImage image)
    {
        if (image == null)
        {
            return null;
        }
        ImageComponent2D imageComp2d = new ImageComponent2D 
                                        (ImageComponent2D.FORMAT_RGB, image);
        return getPageAppearance(imageComp2d);
    }

    /**Method to retrieve an appearance object for use with the shape, 
     * and with a Material applied.
     * <p><em><b> The material object enforces Light sources, hence must be
     * explicitly added.  </b></em></p>
     */
    public Appearance getPageAppearance (ImageComponent2D image, 
                                                        boolean addMaterial)
    {
        if (image == null)
        {
            return null;
        }

        Appearance appear = getPageAppearance(image);

        if (addMaterial)
        {
            Material pageMaterial = new Material ();
            pageMaterial.setAmbientColor    (0.3f, 0.3f, 0.3f);
            pageMaterial.setDiffuseColor    (0.4f, 0.4f, 0.4f);
            pageMaterial.setEmissiveColor  (0.0f, 0.0f, 0.0f);
            pageMaterial.setSpecularColor   (0.7f, 0.7f, 0.7f);
            pageMaterial.setShininess       (32.0f);
            pageMaterial.setLightingEnable (true);

            appear.setMaterial(pageMaterial);
        }

        return appear;
    }
    /**Simple method to calculate a normal based on the points that are given.
     */
    private Vector3f calculateNormal (Point3d p1, Point3d p2, Point3d p3)
    {
        Vector3f v1 = new Vector3f ((float)(p3.x-p2.x), (float)(p3.y-p2.y), 
                                                        (float)(p3.z-p2.z));
        Vector3f v2 = new Vector3f ((float)(p1.x-p2.x), (float)(p1.y-p2.y), 
                                                        (float)(p1.z-p2.z));

        Vector3f retValue = new Vector3f ();
        retValue.cross (v1, v2);
        retValue.normalize();

        return retValue;
    }

    /**Creates a GeometryArray by creating a smooth set of points from the
     * input control data points, and then calculating normals and texture
     * coordinates for the GeometryArray.
     * </p><p>
     * This is a convenience method for automatically applying smoothening to
     * the input points. If there is no need to smoothen the points, use the
     * alternate method with the appropriate value of the boolean parameter.
     * </p>
     * @param inputPoints This array of Point3d objects is a two dimensional
     * array of the control points [column][row]
     * @param drawFrontFace boolean value determining which order to use the
     * points.
     * @param tImage with inbuilt information of the size of the image to be
     * textured. 
     * @return IndexedTriangleStripArray created from the input points, ready
     * to be textured by the TextureImage tImage.
     */
    public GeometryArray createIndTriStripArray (Point3d[][] inputPoints,
                                boolean drawFrontFace, TextureImage tImage)
            throws InvalidPointDataException
    {
        return createIndTriStripArray(inputPoints, true, drawFrontFace, tImage);
    }
            
    /**Creates a GeometryArray by using the input points or creating a smooth
     * set of points from the input control data points, and then calculating
     * normals and texture coordinates for the GeometryArray.
     * @param inputPoints This array of Point3d objects is a two dimensional
     * array of the control points [column][row]
     * @param generateSmoothenedPoints boolean value instructing the method to
     * use the input points to get a BiCubicSpline smoothened set of points, or
     * to use the points as they are.
     * @param drawFrontFace boolean value determining which order to use the
     * points.
     * @param tImage
     * @return IndexedTriangleStripArray created from the input points, ready
     * to be textured by the TextureImage tImage.
     */
    public GeometryArray createIndTriStripArray (Point3d[][] inputPoints,
                    boolean generateSmoothenedPoints, boolean drawFrontFace, 
                    TextureImage tImage)
            throws InvalidPointDataException
    {
        //check the input points
        if (inputPoints == null)
        {
            throw new InvalidPointDataException ("Null input points passed");
        }
        int initCols = inputPoints.length;
        int initRows = -1;
        Point3d [] column = inputPoints[0];
        if (column == null)
        {
            throw new InvalidPointDataException ("First column is null");
        }
        else 
        {
            initRows = column.length;
        }
        for (int i=1;i<initCols;++i)
        {
            column = inputPoints[i];
            if (column == null || column.length != initRows)
            {
                throw new InvalidPointDataException ("Column " + i + 
                                " is either null, or not of length " + initRows);
            }
        }

        Point3d [][] orderedPoints = null;

        //order the points in the required manner, copying them to a new array,
        //if required.

        if (!drawFrontFace)     //reverse the points if required
        {
            orderedPoints = new Point3d [inputPoints.length][];

            for (int i=0;i<inputPoints.length;++i)
            {
                orderedPoints[initCols-1-i] = inputPoints [i];
            }
        }
        else                    //points won't be modified, just set the ref.
        {
            orderedPoints = inputPoints;
        }

        
        //get the number of rows and columns in the new set of points.
        int cols = -1;
        int rows = -1;
        
        Point3d [][] points2DimArray = null;

        //check whether to generate smooth surface, and if so
        //create a spline and get the surface points
        //if (generateSmoothenedPoints)
        //{
            //try
            //{
                //spline.setControlPoints (orderedPoints);
                //points2DimArray = spline.getCurvePoints();
                //cols = spline.getNumberOfColumns();
                //rows = spline.getNumberOfRows();
            //}
            //catch (DrawingException de)
            //{
                //System.err.println ("Error in drawing : \n" + de.getMessage());
                //return null;
            //}
        //}
        //else    // use the points as they are.
        {
            points2DimArray = orderedPoints;
            cols = initCols;
            rows = initRows;
        }

        //get the converted points array
        Point3d [] points = convert2DimensionalArray (points2DimArray, 
                                                                cols, rows);
        //get the strip count array
        int[] stripCount = createStripCountArrayIndTriStripArray (cols, rows);
        
        //get the normals array
        Vector3f[] normalsArray = calculateNormalsArray (points, 
                                                    cols, rows, drawFrontFace);
        
        //get the texCoord array
        TexCoord2f [] texCoordsArray = calculateTextureCoordinates (points,
                cols, rows,
                tImage.getMinHorTextureCoord(), tImage.getMaxHorTextureCoord(),
                tImage.getMinVerTextureCoord(), tImage.getMaxVerTextureCoord());
        
        //get the indices array
        int [] indicesArray = createIndicesArrayIndTriStripArray (cols, rows, 
                                                                drawFrontFace);
        
        //put them together
        int vertexCount = points.length;
        //int vertexFormat =  GeometryArray.COORDINATES;
        int vertexFormat =  GeometryArray.COORDINATES   | 
                            GeometryArray.NORMALS       |
                            GeometryArray.BY_REFERENCE  |
                            GeometryArray.TEXTURE_COORDINATE_2 ;
        int indexCount  = indicesArray.length;
        IndexedTriangleStripArray itsArray = 
                new IndexedTriangleStripArray (vertexCount, vertexFormat, 
                                                        indexCount, stripCount);

        itsArray.setCapability (GeometryArray.ALLOW_COUNT_READ);
        itsArray.setCapability (GeometryArray.ALLOW_FORMAT_READ);
        itsArray.setCapability (GeometryArray.ALLOW_COORDINATE_READ);
        itsArray.setCapability (GeometryArray.ALLOW_COORDINATE_WRITE);
        itsArray.setCapability (GeometryArray.ALLOW_REF_DATA_READ);
        itsArray.setCapability (GeometryArray.ALLOW_REF_DATA_WRITE);
        itsArray.setCapability (IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ);

        itsArray.setCoordRef3d (points);
        itsArray.setNormalRef3f (normalsArray);
        itsArray.setTexCoordRef2f (0, texCoordsArray);
        // itsArray.setCoordinates (0, points);
        // itsArray.setNormals (0, normalsArray);
        // itsArray.setTextureCoordinates (0, 0, texCoordsArray);

        itsArray.setCoordinateIndices (0, indicesArray);
        //itsArray.setNormalIndices (0, indicesArray);
        itsArray.setTextureCoordinateIndices(0, 0, indicesArray);


        //done
        return itsArray; 
    }

    /**Calculates the normals for the set of input points.
     * This method replaces the use of Sun's utility class, since the
     * performance of that class needed improvement, and also changed the
     * number of vertices on occassion.
     * <p>
     * The normal for each triangle is first calculated, then the normal for
     * each vertex is calculated by checking how many triangles that it
     * contributes to.
     * </p>
     * @param inputPoints the Point3d[][] array of input points in column major
     * format.
     * @param cols an integer, the number of columns, (cols >= 2)
     * @param rows an integer, the number of rows, (rows >= 2)
     * @param drawFrontFace boolean, represengint the side to be drawn. This is
     * important as it determines the selection of triangles.
     * @return the array of Vector3f representing the normals.
     */
    Vector3f[] calculateNormalsArray (Point3d[] inputPoints, int cols, int rows,
                                                    boolean drawFrontFace)
    {
        //check input
        if (inputPoints == null  || inputPoints.length != rows*cols ||
                rows < 1 || cols < 1)
        {
            return null;
        }

        //construct a Vector3f[cols][rows][1 - 2] for the normals for each tri.
        Vector3f[][][] triangleNormals = new Vector3f [cols-1][][];
        for (int i=0;i<cols-1;++i)
        {
            triangleNormals[i] = new Vector3f [rows] [];
            for (int j=0;j < rows-1; ++j)
            {
                triangleNormals[i][j] = new Vector3f[2];
                //fill the vector.
                triangleNormals[i][j][0] = 
                        calculateNormal (   inputPoints[(rows*i) + j],
                                            inputPoints[(rows*(i+1)) + j],
                                            inputPoints[(rows*i) + (j+1)]);
                triangleNormals[i][j][1] = 
                        calculateNormal (   inputPoints[(rows*i) + (j+1)],
                                            inputPoints[(rows*(i+1)) + j],
                                            inputPoints[(rows*(i+1)) + (j+1)]);
            }
        }
        //construct an array to hold the normals for the surface.
        Vector3f [] normals = new Vector3f [rows * cols];
        
        //for each point, calculate the average of all tris. it is part of.
        int count = -1;
        Vector3f normal = null;
        for (int i=0;i<cols;++i)
        {
            for (int j=0;j<rows;++j)
            {
                count = 0;
                normal = new Vector3f(0f,0f,0f);
                //check each of six triangles, in four locations
                if (i<cols-1 && j<rows-1)
                {
                    normal.add (triangleNormals[i][j][0]);
                    count ++;
                }
                if (i<cols-1 && j>0)
                {
                    normal.add (triangleNormals[i][j-1][0]);
                    normal.add (triangleNormals[i][j-1][1]);
                    count += 2;
                }
                if (i>0 && j>0)
                {
                    normal.add (triangleNormals[i-1][j-1][1]);
                    count ++;
                }
                if (i>0 && j<rows-1)
                {
                    normal.add (triangleNormals[i-1][j][0]);
                    normal.add (triangleNormals[i-1][j][1]);
                    count += 2;
                }
                //now set this to be normalized.
                normal.normalize();

                if (!drawFrontFace)
                {
                    normal.negate();
                }
                //finally put this is in it's place in the vector.
                normals [(rows*i)+j] = normal;
            }
        }
        
        //done.
        return normals;
    }

    /**Simple method that converts a two-dimentsional array and converts it to
     * the single dimension array required for the GeometryArray.
     * @param inputPoints the Point3d[][] array of input points, [column][row]
     * @param cols an integer, the number of columns, (cols >= 2)
     * @param rows an integer, the number of rows, (rows >= 2)
     * @return Point3d[] the converted set of points.
     */
    Point3d[] calculatePointsArray (Point3d[][] inputPoints, int cols, int rows)
    {
        //first check the parameters.
        if (inputPoints == null || cols < 2 || rows < 2)
        {
            return null;
        }

        int numPointsPerRow = 2 * rows;
        
        Point3d[] points = new Point3d [numPointsPerRow * (cols-1)];

        int count = 0;
        int baseColumn = -1;
        int baseIndex = -1;
        for (int i=0;i<cols-1;++i)
        {
            baseColumn = i * numPointsPerRow;
            
            for (int j=0;j<rows;++j)
            {
                baseIndex = baseColumn + (2*j);
                
                points [baseIndex]   = inputPoints[i][j];
                points [baseIndex+1] = inputPoints[i+1][j];
            }
        }

        return points;
    }

    /**Calculates the texture coordinates for each of the points in the input
     * array, based on the usable area, as specified by the remaining
     * parameters.
     * @param inputPoints the Point3d[] array of input points in a column major
     * format. <b>This value not used currently, values set by dead
     * reckoning.</b>
     * @param cols          an integer giving the number of cols (>=2)
     * @param rows          an integer giving the number of rows (>=2)
     * @param minHorizontal a float value in the range [0,1]
     * @param maxHorizontal a float value in the range [0,1]
     * @param minVertical   a float value in the range [0,1]
     * @param maxVertica    a float value in the range [0,1
     * @return the array of the TexCoord2f values to use in a form required by
     * the GeometryArray, or null if the inputs are out of range, or min is not
     * less than max.
     */
    TexCoord2f [] calculateTextureCoordinates (Point3d[] inputPoints, 
                int cols,            int rows,
                float minHorizontal, float maxHorizontal, 
                float minVertical,   float maxVertical)
    {
        //first check the parameters.
        if (inputPoints == null       || cols < 2 || rows < 2 ||
                minHorizontal < 0.0f  || maxHorizontal > 1.0f ||
                minVertical   < 0.0f  || maxVertical   > 1.0f ||
                minHorizontal >= maxHorizontal    ||
                minVertical   >= maxVertical)
        {
            return null;
        }
        
        //input is OK, now create the ouput array.
        TexCoord2f [] tCoords = new TexCoord2f [rows * cols];

        float rangeHor = maxHorizontal - minHorizontal;
        float rangeVer = maxVertical   - minVertical;

        float x = 0.0f;
        float y = 0.0f;

        for (int i=0;i<cols;++i)
        {
            for (int j=0;j<rows;++j)
            {
                x = minHorizontal + ((i / (cols-1.0f)) * rangeHor);
                y = minVertical +   ((j / (rows-1.0f)) * rangeVer);
                tCoords[(i*rows)+j] = new TexCoord2f(x,y);
            }
        }
        
        return tCoords;
    }

    /**Resets the texture coordinates of the shape to use the texturable area
     * of the image and resets the Appearance object to use the new
     * TextureImage.
     * @param shape the Shape3D to be reset
     * @param cols  int, the number of columns in the shape ([cols][rows])
     * @param rows  int, the number of rows in the shape ([cols][rows])
     * @param tImage the TextureImage to be applied to shape
     * @return a boolean value indicating whether the operation succeeded.
     */
    public boolean reApplyTexture (Shape3D shape, int cols, int rows, 
                                                        TextureImage tImage)
    {
        return false;
    }
    /**This method resets the texture coordinates of the shape to use the
     * texturable area of the new image.
     * @param gArray the GeometryArray which is to be modified, a
     * TriangleStripArray is expected.
     * @param cols  int, the number of columns in the shape ([cols][rows])
     * @param rows  int, the number of rows in the shape ([cols][rows])
     * @param tImage the TextureImage to be applied to shape
     * @return a boolean value indicating whether the operation succeeded.
     */
    boolean reCalculateTextureCoordinates (GeometryArray gArray, 
                            int numColumns, int numRows, TextureImage tImage)
    {
        return false;
    }

    /**Resets the appearance of this object to use the given TextureImage.
     * @param appear the Appearance object to use.
     * @param tImage the TextureImage to be applied.
     * @return a boolean value indicating whether the operation succeeded.
     */
    boolean reSetAppearance (Appearance appear, TextureImage tImage)
    {
        return false;
    }

    /**Converts the given 2 dimensional array of points [column][row] to a
     * single dimensional array.
     * @param inputPoints the 2-Dim array of Point3d
     * @param cols an int describing the number of columns.
     * @param rows an int describing the number of rows.
     * @return a single dimension array of Point3d, null if the input is null,
     * or does not have the correct number of rows and columns.
     */
    Point3d [] convert2DimensionalArray (Point3d [][] inputPoints, 
                                                        int cols, int rows)
    {
        if (inputPoints == null || inputPoints.length != cols)
        {
            return null;
        }
        for (int i=0;i<cols;++i)
        {
            if (inputPoints[i].length != rows)
            {
                return null;
            }
        }
        //input points are ok.

        Point3d [] points = new Point3d [rows * cols];
        for (int i=0;i<cols;++i)
        {
            for (int j=0; j<rows; ++j)
            {
                points [(i*rows)+j] = inputPoints[i][j];
            }
        }
        return points;
    }

    /**Creates the indices array used for the IndexedTriangleStripArray.
     * @param cols an int describing the number of columns.
     * @param rows an int describing the number of rows.
     * @param drawFrontFace boolean, determining whether the front or back face
     * of the given surface is to be drawn. This is the second action taken
     * when this parameter is given; the first is to reverse the point[][]
     * array if required.
     * @return an int[] of the indices to be used for creating a
     * IndexedTriangleStripArray, or null if cols or rows less than 2.
     */
    int [] createIndicesArrayIndTriStripArray (int cols, int rows, 
                                                        boolean drawFrontFace)
    {
        if (cols < 2 || rows < 2)
        {
            return null;
        }

        int numPointsPerRow = rows * 2;
        int []  indices = new int [numPointsPerRow * (cols - 1)];

        int indexCount = 0;

        for (int i=0; i<cols-1; ++i)
        {
            for (int j=0; j < rows; ++j)
            {
                indices [indexCount++] = (rows * i) + j;
                indices [indexCount++] = (rows * (i+1)) + j;
                //if (drawFrontFace)
                //{
                    //indices [indexCount++] = (rows * i) + j;
                    //indices [indexCount++] = (rows * (i+1)) + j;
                //}
                //else
                //{
                    //indices [indexCount++] = (rows * (i+1)) + j;
                    //indices [indexCount++] = (rows * i) + j;
                //}
            }
        }
        return indices;   
    }

    /**Creates the array of strip counts for the IndexedTriangleStripArray.
     * @param cols an int describing the number of columns.
     * @param rows an int describing the number of rows.
     * @return int[] containing the number of vertices in each strip, or null
     * if cols or rows less than 2.
     */
    int [] createStripCountArrayIndTriStripArray (int cols, int rows)
    {
        if (cols < 2 || rows < 2)
        {
            return null;
        }

        int numPointPerStrip = rows * 2;
        
        int [] stripCounts = new int [cols-1];
        
        for (int i=0; i< cols-1; ++i)
        {
            stripCounts [i] = numPointPerStrip;
        }

        return stripCounts;
    }

}
/*
 * ImageResizer.java      1.0     08/09/2000
 *
 * Copyright (c) 2000-2005 Liqwid Krystal Inc.
 * Pearl House, 9/3 Museum Road, Bangalore, 560 001, India.
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of Liqwid
 * Krystal, Inc. ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Liqwid Krystal.
 */


import java.awt.image.*;

/**Utility class for taking an image and creating a larger image out of it,
 * that has a size of 2^m x 2^n (width and height are powers of 2, so that it
 * can be textured in Java3D.
 */
public class ImageResizer
{
    /**Creates a TextureImage of the input image that is larger that the given
     * image and has widht and height as powers of 2. This allows the resultant
     * image to be used for texturing.
     */
    public TextureImage createResizedImage (BufferedImage image)
    {
        if (image == null)
        {
            return null;
        }

        int preWidth  = image.getWidth();
        int preHeight = image.getHeight();

        int width  = getNextPowerOfTwo(preWidth);
        int height = getNextPowerOfTwo(preHeight);

        if (preHeight == height && preWidth == width)
        {
            if (image instanceof TextureImage)
            {
                return (TextureImage)image;
            }
            else
            {
                TextureImage tImage = new TextureImage (width, height,
                                                            image.getType());
                int [] rgbData = image.getRGB (0, 0, preWidth, preHeight, null, 
                                                                0, preWidth);
                tImage.setRGB (0, 0, preWidth, preHeight, rgbData, 0, preWidth);
                tImage.setTextureCoordinateLimits (width, height);
                return tImage;
            }
        }

        int [] preData = image.getRGB (0, 0, preWidth, preHeight, null, 
                                                                    0, preWidth);

        int [] rgbData = new int [width * height];

        for (int i=0; i < height; ++i)
        {
            for (int j=0; j < width; ++j)
            {
                if (i < preHeight)
                {
                    copyData (rgbData, width * i, preData, preWidth *i, preWidth);
                    padData  (rgbData, width * i + preWidth, width - preWidth);
                }
                else
                {
                    padData (rgbData, width * i, width);
                }
            }
        }
        TextureImage tImage = new TextureImage (width, height, image.getType());
        tImage.setRGB (0, 0, width, height, rgbData, 0, width);
        tImage.setTextureCoordinateLimits(preWidth, preHeight);
        return tImage;
    }

    private void copyData (int[] dest, int destOffset, int[] src, 
                                                    int srcOffset, int length)
    {
        for (int i=0; i<length;++i)
        {
            dest[destOffset+i] = src[srcOffset+i];
        }
        return;
    }

    private void padData (int[] dest, int destOffset, int len)
    {
        int padValue = -1; // white, opaque
        for (int i=0;i<len;++i)
        {
            dest[destOffset + i] = padValue;
        }
        return;
    }

    /**Returns the smallest power of two greater than or equal to the input
     * value.
     */
    public static int getNextPowerOfTwo (int value)
    {
        if ((value & (value-1)) == 0)
        {
            return value;
        }

        int i = value;
        int power = 0;
        while (i != 0)
        {
            i = i >> 1;
            power ++;
        }

        int retVal = 1 << power;
        if (value == (retVal >> 1))
        {
            retVal = retVal >> 1;
        }
      

        return 1 << power;
    }
}

imageTest.jpg

/*
 *      @(#)IndexTest.java 1.49 00/03/20 09:07:23
 *
 * Copyright (c) 1996-2000 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
 * modify and redistribute this software in source and binary code form,
 * provided that i) this copyright notice and license appear on all copies of
 * the software; and ii) Licensee does not utilize the software in a manner
 * which is disparaging to Sun.
 *
 * This software 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 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.
 */

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.event.*;
import java.awt.GraphicsConfiguration;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.image.*;
import javax.media.j3d.*;
import java.awt.*;
import java.awt.image.*;
import javax.vecmath.*;
import com.sun.j3d.utils.behaviors.mouse.*;


public class IndexTest extends Applet {
    public BranchGroup createSceneGraph() {
        // Create the root of the branch graph
        BranchGroup objRoot = new BranchGroup();

        // Create the TransformGroup node and initialize it to the
        // identity. Enable the TRANSFORM_WRITE capability so that
        // our behavior code can modify it at run time. Add it to
        // the root of the subgraph.
        TransformGroup objTrans = new TransformGroup();
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
        objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRoot.addChild(objTrans);

    //GET THE POINTS
    Point3d[][] points = PointArraySource.get2DimPointArray("smallControlSurface");

    //GET THE IMAGE AND APPEARANCE OBJECTS
    Frame dummy = new Frame();
    TextureLoader tLoader = new TextureLoader ("imageTest.jpg", dummy);
    BufferedImage image = tLoader.getImage().getImage();
    ImageResizer iResizer = new ImageResizer();
    TextureImage tImage = iResizer.createResizedImage(image);

    GeometryHelper gHelper = new GeometryHelper();
    GeometryArray itsArrayFront = null;
    GeometryArray itsArrayBack = null;
    try
    {
        itsArrayFront = gHelper.createIndTriStripArray (points, true,  tImage);
        itsArrayBack  = gHelper.createIndTriStripArray (points, false, tImage);
    }
    catch (InvalidPointDataException ipdExc)
    {
        System.err.println ("The points you gave were bad!");
        System.exit(0);
    }
    Appearance appear = gHelper.getPageAppearance (tImage);
    

    Shape3D shapeFront = new Shape3D (itsArrayFront, appear);
    Shape3D shapeBack  = new Shape3D (itsArrayBack, appear);
    
    
    // ------
        //objTrans.addChild(new ColorCube(0.4));
        objTrans.addChild(shapeFront);
        objTrans.addChild(shapeBack);

        BoundingSphere bounds =
            new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);


                // adding a mouse rotation behaviour
         MouseRotate rotBehaviour = new MouseRotate (objTrans);
         objTrans.addChild (rotBehaviour);
         rotBehaviour.setSchedulingBounds (bounds);

                // adding a mouse zoom behaviour
         MouseZoom zoomBehaviour = new MouseZoom (objTrans);
         objTrans.addChild (zoomBehaviour);
         zoomBehaviour.setSchedulingBounds (bounds);

                // adding a translation behaviour
         MouseTranslate translateBehaviour = new MouseTranslate (objTrans);
         objTrans.addChild (translateBehaviour);
         translateBehaviour.setSchedulingBounds (bounds);

        // Have Java 3D perform optimizations on this scene graph.
        objRoot.compile();

        return objRoot;
    }

    public IndexTest() {
        setLayout(new BorderLayout());
        GraphicsConfiguration config =
           SimpleUniverse.getPreferredConfiguration();

        Canvas3D c = new Canvas3D(config);
        add("Center", c);

        // Create a simple scene and attach it to the virtual universe
        BranchGroup scene = createSceneGraph();
        SimpleUniverse u = new SimpleUniverse(c);

        // This will move the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        u.getViewingPlatform().setNominalViewingTransform();

        u.addBranchGraph(scene);
    }

    //
    // The following allows HelloUniverse to be run as an application
    // as well as an applet
    //
    public static void main(String[] args) {
        new MainFrame(new IndexTest(), 700, 700);
    }
}



public class InvalidPointDataException
    extends Exception
{
    public InvalidPointDataException (String s)
    {
        super (s);
        return;
    }

    public InvalidPointDataException ()
    {
        super ();
        return;
    }
}

import javax.vecmath.*;

public class PointArraySource
{
    static PointArraySource pas = null;

    public static Point3d [][] get2DimPointArray (String argument)
    {
        if (pas == null)
        {
            pas = new PointArraySource ();
        }

        if (argument.equalsIgnoreCase ("smallControlSurface"))
        {
            return pas.getSmallControlSurface ();
        }
        return null;

    }

    public Point3d [][] getSmallControlSurface()
    {
        Point3d [][] points =
            {
                {
                    new Point3d ( -1.5d, -1.5d,  0.0d),
                    new Point3d ( -1.5d, -0.5d,  0.0d),
                    new Point3d ( -1.5d,  0.5d,  1.0d),
                    new Point3d ( -1.5d,  1.5d,  0.0d)
                },
                {
                    new Point3d ( -0.5d, -1.5d, -1.0d),
                    new Point3d ( -0.5d, -0.5d,  0.0d),
                    new Point3d ( -0.5d,  0.5d,  0.0d),
                    new Point3d ( -0.5d,  1.5d, -1.0d)
                },
                {
                    new Point3d (  0.5d, -1.5d, -1.0d),
                    new Point3d (  0.5d, -0.5d,  0.0d),
                    new Point3d (  0.5d,  0.5d,  0.0d),
                    new Point3d (  0.5d,  1.5d, -1.0d)
                },
                {
                    new Point3d (  1.5d, -1.5d,  0.0d),
                    new Point3d (  1.5d, -0.5d,  1.0d),
                    new Point3d (  1.5d,  0.5d,  1.0d),
                    new Point3d (  1.5d,  1.5d,  0.0d)
                }
            };

            return points;
    }

}

/*
 * TextureImage.java      1.0     08/09/2000
 *
 * Copyright (c) 2000-2005 Liqwid Krystal Inc.
 * Pearl House, 9/3 Museum Road, Bangalore, 560 001, India.
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of Liqwid
 * Krystal, Inc. ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Liqwid Krystal.
 */


import java.awt.image.BufferedImage;

/**This class holds the image used for texturing, and thus creates a resized
 * image as required.
 */
public class TextureImage
    extends BufferedImage
{
    public TextureImage (int width, int height, int type)
    {
        super (width, height, type);

        
        return;
    }

    private float maxHorTextureCoord = 1.0f;
    private float minHorTextureCoord = 0.0f;
    private float maxVerTextureCoord = 1.0f;
    private float minVerTextureCoord = 0.0f;

    /**Returns the min horizontal texture coordinate value to be used.
     * @return a float of the value, in the range [0.0, 1.0]
     */
    public float getMinHorTextureCoord ()
    {
        return minHorTextureCoord;
    }

    /**Returns the min vertical texture coordinate value to be used.
     * @return a float of the value, in the range [0.0, 1.0]
     */
    public float getMinVerTextureCoord ()
    {
        return minVerTextureCoord;
    }

    /**Returns the max horizontal texture coordinate value to be used.
     * @return a float of the value, in the range [0.0, 1.0]
     */
    public float getMaxHorTextureCoord ()
    {
        return maxHorTextureCoord;
    }

    /**Returns the max vertical texture coordinate value to be used.
     * @return a float of the value, in the range [0.0, 1.0]
     */
    public float getMaxVerTextureCoord ()
    {
        return maxVerTextureCoord;
    }

    
    /**The size of the image initially used is set here, and this sets the
     * limits of the texture coordinates to be used.
     * @param preHeight The height of the image used for generation.
     * @param preWidth The width of the image used for generation.
     * @return void, the method sets the values and returns.
     */
    public void setTextureCoordinateLimits (int preWidth, int preHeight)
    {
        maxVerTextureCoord = 1.0f;
        
        int height = getHeight();
        minVerTextureCoord =  (((height - preHeight) * 1.0f) /height);

        minHorTextureCoord = 0.0f;
        int width = getWidth();
        maxHorTextureCoord = (preWidth * 1.0f) / (width);
        return ;
    }

    ///**The width of the image used for creation is set here, and the resultant
     //* texture coordinate is returned.
     //* @param preWidth The width of the image used for generation.
     //* @return the float value of the textureCoordinate to be set is returned.
     //*/
    //public void setInitialImageWidth (int preWidth)
    //{
        //minHorTextureCoord = 0.0f;
        //int width = getWidth();
        //maxHorTextureCoord = (preWidth * 1.0f) / (width);
        //return ;
    //}
}

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Label;
import java.awt.ScrollPane;
import java.awt.Toolkit;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.GraphicsConfiguration;
import java.io.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.behaviors.mouse.*;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.image.*;
import com.sun.j3d.utils.picking.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import javax.swing.JWindow;
import java.util.*;


/**This class is used to create morph transform group.
 */
public class TestMorphBehavior
    extends Applet
{

    public TestMorphBehavior () {
        setLayout(new BorderLayout());
        GraphicsConfiguration config =
           SimpleUniverse.getPreferredConfiguration();

        Canvas3D c = new Canvas3D(config);
        add("Center", c);

        // Create a simple scene and attach it to the virtual universe
        BranchGroup scene = createSceneGraph();
        SimpleUniverse u = new SimpleUniverse(c);

        // This will move the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        u.getViewingPlatform().setNominalViewingTransform();

        u.addBranchGraph(scene);
    }

    public void getGeometries (GeometryArray[] frontGeometries, int numGeometries, TextureImage ti)
    {
                // create a store for points to be retrieved.
        Point3d [][] inputPoints = null;

        Vector axes = new Vector ();
        GeometryHelper gh = new GeometryHelper ();

        try
        {
            // Base Geom 0
            inputPoints = (PointArraySource.get2DimPointArray ("smallControlSurface"));
            frontGeometries[0] = gh.createIndTriStripArray (inputPoints, true, ti);
        }
        catch (InvalidPointDataException ipde)
        {
            ipde.printStackTrace ();
            return;
        }
    }


    public TransformGroup createTransformGroup ()
    {
        TransformGroup objTrans = new TransformGroup ();

        objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

                // Load the geometries.
        int numGeometries = 1;
        GeometryArray []  frontGeometries = new GeometryArray [numGeometries];

        TextureLoader frontLoader = new TextureLoader ("imageTest.jpg", this);
        BufferedImage image = frontLoader.getImage().getImage();
        ImageResizer iResizer = new ImageResizer();
        TextureImage ti = iResizer.createResizedImage(image);

        getGeometries (frontGeometries, numGeometries, ti);

                // Now build the Morph objects.
        //First the front object.
        Morph frontMorph = new Morph (frontGeometries);
        frontMorph.setCapability (Morph.ALLOW_WEIGHTS_WRITE);
        frontMorph.setCapability (Morph.ALLOW_GEOMETRY_ARRAY_READ);
        frontMorph.setCapability (Morph.ALLOW_GEOMETRY_ARRAY_WRITE);

        ImageComponent2D frontImage = frontLoader.getImage ();
        Appearance frontAppear = getPageAppearance(frontImage);

        frontMorph.setAppearance (frontAppear);
        objTrans.addChild (frontMorph);

        return objTrans;
    }

    /**Method to retrieve an appearance object for use with the shape.
     */
    private Appearance getPageAppearance (ImageComponent2D image)
    {
        Texture2D texture = new Texture2D (Texture2D.BASE_LEVEL, Texture2D.RGB,
                                        image.getWidth(), image.getHeight());
        texture.setImage (0, image);
        texture.setEnable (true);
        texture.setCapability (Texture.ALLOW_IMAGE_WRITE);
        TextureAttributes tAttrib = new TextureAttributes ();
        tAttrib.setTextureMode (tAttrib.MODULATE);

        Appearance appearance = new Appearance ();
        appearance.setTexture (texture);
        appearance.setTextureAttributes (tAttrib);

        return appearance;
    }

    public BranchGroup createSceneGraph() {
        // Create the root of the branch graph
        BranchGroup objRoot = new BranchGroup();

        // Create the TransformGroup node and initialize it to the
        // identity. Enable the TRANSFORM_WRITE capability so that
        // our behavior code can modify it at run time. Add it to
        // the root of the subgraph.
        TransformGroup objTrans = createTransformGroup ();
        objRoot.addChild(objTrans);

        BoundingSphere bounds =
            new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);

                // adding a mouse rotation behaviour
         MouseRotate rotBehaviour = new MouseRotate (objTrans);
         objTrans.addChild (rotBehaviour);
         rotBehaviour.setSchedulingBounds (bounds);

                // adding a mouse zoom behaviour
         MouseZoom zoomBehaviour = new MouseZoom (objTrans);
         objTrans.addChild (zoomBehaviour);
         zoomBehaviour.setSchedulingBounds (bounds);

                // adding a translation behaviour
         MouseTranslate translateBehaviour = new MouseTranslate (objTrans);
         objTrans.addChild (translateBehaviour);
         translateBehaviour.setSchedulingBounds (bounds);

        // Have Java 3D perform optimizations on this scene graph.
        objRoot.compile();

        return objRoot;
    }

    //
    // The following allows HelloUniverse to be run as an application
    // as well as an applet
    //
    public static void main(String[] args) {
        new MainFrame(new IndexTest(), 700, 700);
    }
}

Reply via email to