Hi Chien, sorry I did a wrong documentation in the header:
/* CHANGE THIS FOR TESTING: * * USE_BY_REF == false && USE_GEOM_INFO == false --> wrong TextureCoords * USE_BY_REF == true && USE_GEOM_INFO == false --> Everthing Right * USE_BY_REF == false && USE_GEOM_INFO == true --> Everthing Right * USE_BY_REF == true && USE_GEOM_INFO == true --> Exception */ private final static boolean USE_BY_REFERENCE = true; private final static boolean USE_GEOMETRY_INFO = true; for last case (now default), I attached the error output. please take a second look. regards -Michael Nischt
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.geometry.GeometryInfo;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.image.TextureLoader;
import javax.media.j3d.*;
import javax.vecmath.*;
public class GeometryTest extends Applet {
/* CHANGE THIS FOR TESTING:
*
* USE_BY_REFERENCE == false && USE_GEOMETRY_INFO == false --> wrong TextureCoords
* USE_BY_REFERENCE == true && USE_GEOMETRY_INFO == false --> Everthing Right
* USE_BY_REFERENCE == false && USE_GEOMETRY_INFO == true --> Everthing Right
* USE_BY_REFERENCE == true && USE_GEOMETRY_INFO == true --> Exception
*/
private final static boolean USE_BY_REFERENCE = true;
private final static boolean USE_GEOMETRY_INFO = true;
private SimpleUniverse u = null;
private GeometryArray createBox() {
int vertexFormat = IndexedTriangleArray.COORDINATES | IndexedTriangleArray.NORMALS | IndexedTriangleArray.TEXTURE_COORDINATE_2;
if(USE_BY_REFERENCE)
vertexFormat |= IndexedTriangleArray.BY_REFERENCE;
int[] numVerts = { coords.length/3, normals.length/3, tcoords.length/2};
int vertexCount;
if((vertexFormat & GeometryArray.BY_REFERENCE) != 0) {
vertexCount = getMinVertexCount(numVerts); // otherwise Excpetion
}
else {
vertexCount = getMaxVertexCount(numVerts); // otherwise Excpetion
}
int indexCount = coords.length;
IndexedTriangleStripArray triArray = new IndexedTriangleStripArray(vertexCount, vertexFormat, indexCount, stripCounts);
if((vertexFormat & GeometryArray.BY_REFERENCE) != 0) {
triArray.setCoordRefFloat(coords);
triArray.setNormalRefFloat(normals);
triArray.setTexCoordRefFloat(0, tcoords);
}
else {
triArray.setCoordinates(0, coords);
triArray.setNormals(0, normals);
triArray.setTextureCoordinate(0,0, tcoords);
}
triArray.setCoordinateIndices(0, coordIndices);
triArray.setNormalIndices(0, normalIndices);
triArray.setTextureCoordinateIndices(0,0, tcoordIndices);
return triArray;
}
private GeometryArray createBox2() {
GeometryInfo geomInfo = new GeometryInfo(GeometryInfo.TRIANGLE_STRIP_ARRAY);
geomInfo.setStripCounts(stripCounts);
geomInfo.setCoordinates(coords);
geomInfo.setCoordinateIndices(coordIndices);
geomInfo.setNormals(normals);
geomInfo.setNormalIndices(normalIndices);
geomInfo.setTextureCoordinateParams(1,2);
geomInfo.setTextureCoordinates(0, tcoords);
geomInfo.setTextureCoordinateIndices(0, tcoordIndices);
// BY_REFERENCE
if(USE_BY_REFERENCE)
return geomInfo.getIndexedGeometryArray(false, true, false, false, false);
// BY_COPYING
else
return geomInfo.getIndexedGeometryArray(false, false, false, false, false);
}
private Appearance createAp() {
Appearance ap = new Appearance();
Material ma = new Material();
ma.setAmbientColor(0.4f, 0.4f, 0.4f);
ma.setDiffuseColor(0.7f, 0.7f, 0.7f);
ma.setSpecularColor(0.4f, 0.4f, 0.4f);
ma.setEmissiveColor(0.1f, 0.1f, 0.1f);
ma.setShininess(0.0f);
ap.setMaterial(ma);
try {
java.awt.Image img = this.getImage(new java.io.File("wood.jpg").toURL());
TextureLoader texLoader = new TextureLoader(img, TextureLoader.Y_UP, this);
ap.setTexture(texLoader.getTexture());
TextureAttributes ta = new TextureAttributes();
ta.setTextureMode(TextureAttributes.MODULATE);
ap.setTextureAttributes(ta);
}
catch(Exception e) { e.printStackTrace(); }
return ap;
}
public BranchGroup createSceneGraph() {
Transform3D t3d = new Transform3D();
// Create the root of the branch graph
BranchGroup objRoot = new BranchGroup();
// Lights Setup
AmbientLight lightA = new AmbientLight();
lightA.setInfluencingBounds(new BoundingSphere(new Point3d(0.0,0.0,0.0),3200.0));
lightA.setColor(new Color3f(0.2f, 0.2f, 0.2f));
PointLight lightP = new PointLight();
lightP.setInfluencingBounds(new BoundingSphere(new Point3d(0.0,0.0,0.0),3200.0));
lightP.setColor(new Color3f(0.5f, 0.5f, 0.5f));
t3d.setIdentity();
t3d.setTranslation(new Vector3f(0.4f, 0.4f, 0.75f));
TransformGroup lightPos = new TransformGroup(t3d);
lightPos.addChild(lightA);
lightPos.addChild(lightP);
//lightPos.addChild(new Sphere(0.02f, createAp())); // <-- for watching the light source position
BranchGroup lightBG = new BranchGroup();
lightBG.addChild(lightPos);
objRoot.addChild(lightBG);
// move the objects away so we can see them properly
t3d.setIdentity();
t3d.setTranslation(new Vector3f(0,0,-4));
TransformGroup transTG = new TransformGroup(t3d);
objRoot.addChild(transTG);
// 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_WRITE);
transTG.addChild(objTrans);
// Create a simple Shape3D node; add it to the scene graph.
if(USE_GEOMETRY_INFO)
objTrans.addChild(new Shape3D(createBox2(), createAp()));
else
objTrans.addChild(new Shape3D(createBox(), createAp()));
// Create a new Behavior object that will perform the
// desired operation on the specified transform and add
// it into the scene graph.
Transform3D yAxis = new Transform3D();
Alpha rotationAlpha = new Alpha(-1, 4000);
RotationInterpolator rotator =
new RotationInterpolator(rotationAlpha, objTrans, yAxis,
0.0f, (float) Math.PI*2.0f);
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
rotator.setSchedulingBounds(bounds);
objRoot.addChild(rotator);
// Have Java 3D perform optimizations on this scene graph.
objRoot.compile();
return objRoot;
}
public GeometryTest() {
}
public void init() {
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();
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 destroy() {
u.removeAllLocales();
}
// getting right vertexCounnts ??
private static final int getMinVertexCount(int[] numVertices) {
int min = numVertices[0];
for(int i=1; i<numVertices.length; i++)
if(numVertices[i] < min)
min = numVertices[i];
return min;
}
private static final int getMaxVertexCount(int[] numVertices) {
int max = numVertices[0];
for(int i=1; i<numVertices.length; i++)
if(numVertices[i] > max)
max = numVertices[i];
return max;
}
// Box data
private static final float[] coords = {
// front-bottom-left -- 0
-1.0f, -1.0f, 1.0f,
// front-bottom-right -- 1
1.0f, -1.0f, 1.0f,
// front-top-left -- 2
-1.0f, 1.0f, 1.0f,
// front-top-right -- 3
1.0f, 1.0f, 1.0f,
// back-bottom-left -- 4
-1.0f, -1.0f, -1.0f,
// back-bottom-right -- 5
1.0f, -1.0f, -1.0f,
// back-top-left -- 6
-1.0f, 1.0f, -1.0f,
// back-top-right -- 7
1.0f, 1.0f, -1.0f,
};
private static final float[] tcoords = {
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f,
};
private static final float[] normals = {
0.0f, 0.0f, 1.0f, // front face
0.0f, 0.0f, -1.0f, // back face
1.0f, 0.0f, 0.0f, // right face
-1.0f, 0.0f, 0.0f, // left face
0.0f, 1.0f, 0.0f, // top face
0.0f, -1.0f, 0.0f, // bottom face
};
private static final int[] coordIndices = {
1, 3, 0, 2, // front face
4, 6, 5, 7, // back face
5, 7, 1, 3, // right face
0, 2, 4, 6, // left face
3, 7, 2, 6, // top face
0, 4, 1, 5, // bottom face
};
private static final int[] normalIndices = {
0, 0, 0, 0, // front face
1, 1, 1, 1, // back face
2, 2, 2, 2, // right face
3, 3, 3, 3, // left face
4, 4, 4, 4, // top face
5, 5, 5, 5, // bottom face
};
private static final int[] tcoordIndices = {
0, 1, 2, 3, // front face
0, 1, 2, 3, // back face
0, 1, 2, 3, // right face
0, 1, 2, 3, // left face
0, 1, 2, 3, // top face
0, 1, 2, 3, // bottom face
};
private static final int[] stripCounts = { 4,4,4,4,4,4 };
//
// The following allows HelloUniverse to be run as an application
// as well as an applet
//
public static void main(String[] args) {
new MainFrame(new GeometryTest(), 256, 256);
}
}
<<attachment: wood.jpg>>
java.lang.ArrayIndexOutOfBoundsException: GeometryArray: normal array length is
incorrect
at
javax.media.j3d.GeometryArrayRetained.setNormalRefFloat(GeometryArrayRetained.java:8695)
at javax.media.j3d.GeometryArray.setNormalRefFloat(GeometryArray.java:5092)
at com.sun.j3d.utils.geometry.GeometryInfo.fillIn(GeometryInfo.java:2343)
at
com.sun.j3d.utils.geometry.GeometryInfo.getIndexedGeometryArray(GeometryInfo.java:2709)
at GeometryTest.createBox2(GeometryTest.java:80)
at GeometryTest.createSceneGraph(GeometryTest.java:163)
at GeometryTest.init(GeometryTest.java:199)
at com.sun.j3d.utils.applet.MainFrame.run(MainFrame.java:262)
at java.lang.Thread.run(Thread.java:536)
