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)