// Java 3D Test Applet // TexGenTest.java // Copyright (c) 1999 ENDO Yasuyuki // mailto:yasuyuki@javaopen.org // http://www.javaopen.org/j3dbook/index.html import java.applet.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.text.*; import javax.media.j3d.*; import javax.vecmath.*; import com.sun.j3d.utils.applet.MainFrame; import com.sun.j3d.utils.universe.SimpleUniverse; import com.sun.j3d.utils.behaviors.mouse.MouseRotate; import com.sun.j3d.utils.behaviors.mouse.MouseTranslate; import com.sun.j3d.utils.behaviors.mouse.MouseZoom; import com.sun.j3d.utils.image.TextureLoader; public class TexGenTest extends Applet { private TexCoordGeneration texgen = null; private boolean isStandalone = false; public TexGenTest() { this(false); } public TexGenTest(boolean isStandalone) { this.isStandalone = isStandalone; this.setLayout(new BorderLayout()); } public void init() { GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); Canvas3D canvas = new Canvas3D(config); this.add(canvas, BorderLayout.CENTER); SimpleUniverse universe = new SimpleUniverse(canvas); universe.getViewingPlatform().setNominalViewingTransform(); BranchGroup scene = createSceneGraph(); scene.compile(); universe.addBranchGraph(scene); } private BranchGroup createSceneGraph() { BranchGroup root = new BranchGroup(); root.setCapability(BranchGroup.ALLOW_DETACH); Bounds bounds = new BoundingSphere(new Point3d(), 100.0); Light light = new DirectionalLight(); light.setInfluencingBounds(bounds); root.addChild(light); Background bg = new Background(new Color3f(0.5f, 0.5f, 0.5f)); bg.setApplicationBounds(bounds); root.addChild(bg); TransformGroup trans = new TransformGroup(); trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); MouseRotate rotator = new MouseRotate(trans); rotator.setSchedulingBounds(bounds); root.addChild(rotator); MouseTranslate translator = new MouseTranslate(trans); translator.setSchedulingBounds(bounds); root.addChild(translator); MouseZoom zoomer = new MouseZoom(trans); zoomer.setSchedulingBounds(bounds); root.addChild(zoomer); // テクスチャーマップする立方体 Point3d[] vertices = new Point3d[8]; vertices[0] = new Point3d(0.0, 0.0, 0.0); // 左下 3+-----+2 vertices[1] = new Point3d(1.0, 0.0, 0.0); // 右下 | | vertices[2] = new Point3d(1.0, 1.0, 0.0); // 右上 | | vertices[3] = new Point3d(0.0, 1.0, 0.0); // 左上 0+-----+1 vertices[4] = new Point3d(0.0, 0.0, -1.0); // 左下 7+-----+6 vertices[5] = new Point3d(1.0, 0.0, -1.0); // 右下 | | vertices[6] = new Point3d(1.0, 1.0, -1.0); // 右上 | | vertices[7] = new Point3d(0.0, 1.0, -1.0); // 左上 4+-----+5 int[] indices = { 0, 1, 2, 3, // 前 5, 4, 7, 6, // 後 4, 0, 3, 7, // 左 1, 5, 6, 2, // 右 3, 2, 6, 7, // 上 4, 5, 1, 0 }; // 下 IndexedQuadArray geom = new IndexedQuadArray( vertices.length, GeometryArray.COORDINATES, indices.length ); geom.setCapability(Geometry.ALLOW_INTERSECT); geom.setCoordinates(0, vertices); geom.setCoordinateIndices(0, indices); Appearance ap = createAppearance(); Shape3D grid = new Shape3D(geom, ap); grid.setCapability(Shape3D.ALLOW_GEOMETRY_READ); trans.addChild(grid); // 立方体の辺 int[] sindices = { 0, 1, 1, 2, 2, 3, 3, 0, // 立方体の辺の index 4, 5, 5, 6, 6, 7, 7, 4, 1, 5, 2, 6, 0, 4, 3, 7 }; float[] scolors = { 0.5f, 0.5f, 0.5f, // グレー 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f }; IndexedLineArray geomSide = new IndexedLineArray( vertices.length, GeometryArray.COORDINATES | GeometryArray.COLOR_3, sindices.length ); geomSide.setCoordinates(0, vertices); geomSide.setCoordinateIndices(0, sindices); geomSide.setColors(0, scolors); geomSide.setColorIndices(0, sindices); Shape3D shapeSide = new Shape3D(geomSide); trans.addChild(shapeSide); // S平面の位置に置く平面ポリゴン Vector4f planeS = new Vector4f(); texgen.getPlaneS(planeS); TransformGroup strans = createPlaneTrans(planeS); trans.addChild(strans); double[] pverts = { -1.0, 1.0, 0.0, // 平面の位置に置くポリゴン -1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0 }; float[] pnormals = { 0.0f, 0.0f, 1.0f, // 法線 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }; QuadArray pgeom = new QuadArray( pverts.length/3, GeometryArray.COORDINATES | GeometryArray.NORMALS ); pgeom.setCapability(Geometry.ALLOW_INTERSECT); pgeom.setCoordinates(0, pverts); pgeom.setNormals(0, pnormals); Appearance appS = createPlaneApp(1.0f, 0.5f, 0.5f); // 赤半透明 Shape3D polygonS = new Shape3D(pgeom, appS); strans.addChild(polygonS); // T平面の位置に置く平面ポリゴン Vector4f planeT = new Vector4f(); texgen.getPlaneT(planeT); TransformGroup ttrans = createPlaneTrans(planeT); trans.addChild(ttrans); Appearance appT = createPlaneApp(0.5f, 1.0f, 0.5f); // 緑半透明 Shape3D polygonT = new Shape3D(pgeom, appT); ttrans.addChild(polygonT); // XYZ軸 double[] vertsAx = { -2.0, 0.0, 0.0, 2.0, 0.0, 0.0, // X 軸 0.0, -2.0, 0.0, 0.0, 2.0, 0.0, // Y 軸 0.0, 0.0, -2.0, 0.0, 0.0, 2.0 }; // Z 軸 float[] colorsAx = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // 赤 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // 緑 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }; // 青 LineArray geomAx = new LineArray( vertsAx.length/3, GeometryArray.COORDINATES | GeometryArray.COLOR_3); geomAx.setCoordinates(0, vertsAx); geomAx.setColors(0, colorsAx); Shape3D axis = new Shape3D(geomAx); trans.addChild(axis); root.addChild(trans); return root; } private TransformGroup createPlaneTrans(Vector4f plane) { Transform3D t3d = new Transform3D(); Vector3f zvec = new Vector3f(0.0f, 0.0f, 1.0f); Vector3f plane3f = new Vector3f(plane.x, plane.y, plane.z); zvec.sub(plane3f); zvec.normalize(); Quat4f quat = new Quat4f(zvec.x, zvec.y, zvec.z, 0.0f); t3d.setRotation(quat); Transform3D zt3d = new Transform3D(); Vector3f ztranslate = new Vector3f(0.0f, 0.0f, plane.w); zt3d.setTranslation(ztranslate); t3d.mul(zt3d); return new TransformGroup(t3d); } private Appearance createAppearance() { Appearance app = new Appearance(); Image image = null; if (this.isStandalone) { // アプリケーションとして実行されている final Toolkit toolkit = Toolkit.getDefaultToolkit(); image = toolkit.getImage("face.gif"); } else { // アプレットとして実行されている image = getImage(getCodeBase(), "face.gif"); } MediaTracker mt = new MediaTracker(this); mt.addImage(image, 0); mt.checkAll(true); try { mt.waitForID(0); } catch (InterruptedException e) { e.printStackTrace(); } Texture2D texture2d = (Texture2D)new TextureLoader(image, this).getTexture(); app.setTexture(texture2d); texgen = new TexCoordGeneration( TexCoordGeneration.OBJECT_LINEAR, TexCoordGeneration.TEXTURE_COORDINATE_2, new Vector4f(1.0f, 0.0f, 0.0f, 0.0f), // PlaneS new Vector4f(0.0f, 1.0f, 0.0f, 0.0f) ); // PlaneT app.setTexCoordGeneration(texgen); return app; } private Appearance createPlaneApp(float r, float g, float b) { Appearance app = new Appearance(); Material mat = new Material(); mat.setDiffuseColor(new Color3f(r, g, b)); mat.setSpecularColor(new Color3f(0.0f, 0.0f, 0.0f)); // 黒 app.setMaterial(mat); TransparencyAttributes tattr = new TransparencyAttributes(TransparencyAttributes.BLENDED, 0.7f); app.setTransparencyAttributes(tattr); PolygonAttributes pattr = new PolygonAttributes( PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 0.0f, true ); app.setPolygonAttributes(pattr); return app; } public static void main(String[] args) { TexGenTest applet = new TexGenTest(true); // isStandalone = true; Frame frame = new MainFrame(applet, 500, 500); } }