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);
}
}