// Java 3Dテスト用アプレット // CollisionTest.java // Copyright (c) 1999 ENDO Yasuyuki // mailto:yasuyuki@javaopen.org // http://www.javaopen.org/j3dbook/index.html import java.applet.*; import java.awt.*; 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.universe.PlatformGeometry; import com.sun.j3d.utils.geometry.ColorCube; public class CollisionTest extends Applet { SimpleUniverse universe = null; private boolean isStandalone = false; public CollisionTest() { this(false); } public CollisionTest(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); universe = new SimpleUniverse(canvas); //universe.getViewingPlatform().setNominalViewingTransform(); universe.getViewer().getView().setFrontClipDistance(0.05); universe.getViewer().getView().setBackClipDistance(100.0); BranchGroup scene = createSceneGraph(); universe.addBranchGraph(scene); } private BranchGroup createSceneGraph() { BranchGroup root = new BranchGroup(); Bounds bounds = new BoundingSphere(new Point3d(), 100.0); // 視点側の TG を取得 TransformGroup vtrans = universe.getViewingPlatform().getViewPlatformTransform(); // 視点の前に置く物体の root PlatformGeometry pg = new PlatformGeometry(); // キーボードによる視点移動 Behavior SimpleKeyBehavior kb = new SimpleKeyBehavior(vtrans); kb.setSchedulingBounds(bounds); pg.addChild(kb); // 環境光源 AmbientLight alight = new AmbientLight(); alight.setInfluencingBounds(bounds); root.addChild(alight); // どこにaddChild()しても良い // 視点に固定する平行光源 DirectionalLight light = new DirectionalLight( new Color3f(1.0f, 1.0f, 1.0f), new Vector3f(0.57f, -0.57f, -0.57f) ); light.setInfluencingBounds(bounds); pg.addChild(light); // フロントバンパー Transform3D ft3d = new Transform3D(); ft3d.setTranslation(new Vector3d(0.0, -0.13, -0.5)); TransformGroup ftrans = new TransformGroup(ft3d); pg.addChild(ftrans); ColorCube fcube = new ColorCube(0.04); fcube.setCapability(ColorCube.ALLOW_BOUNDS_READ);//TEST ftrans.addChild(fcube); // 最小限の BoundingBox BoundingBox box = new BoundingBox( new Point3d(-0.04, -0.04, -0.04), new Point3d( 0.04, 0.04, 0.04) ); WallCollisionBehavior fcollision = new WallCollisionBehavior(vtrans, fcube, new Vector3d(0.0, 0.0, -1.0)); // 前向き fcollision.setSchedulingBounds(box); root.addChild(fcollision); // リヤバンパー Transform3D rt3d = new Transform3D(); rt3d.setTranslation(new Vector3d(0.0, -0.13, 0.5)); TransformGroup rtrans = new TransformGroup(rt3d); pg.addChild(rtrans); ColorCube rcube = new ColorCube(0.04); rcube.setCapability(ColorCube.ALLOW_BOUNDS_READ);//TEST rtrans.addChild(rcube); WallCollisionBehavior rcollision = new WallCollisionBehavior(vtrans, rcube, new Vector3d(0.0, 0.0, 1.0)); // 後ろ向き rcollision.setSchedulingBounds(box); root.addChild(rcollision); universe.getViewingPlatform().setPlatformGeometry(pg); // 衝突相手となる壁 root.addChild(createText3D( "Front", 0.0, -0.5, -3.0, 0.0, 0.0f, 1.0f, 0.0f )); // green root.addChild(createText3D( "Back", 0.0, -0.5, 3.0, Math.PI, 0.0f, 0.0f, 1.0f )); // blue root.addChild(createText3D( "Left", -3.0, -0.5, 0.0, (Math.PI / 2.0), 1.0f, 1.0f, 0.0f )); // yellow root.addChild(createText3D( "Right", 3.0, -0.5, 0.0, -(Math.PI / 2.0), 0.0f, 1.0f, 1.0f )); // cyan // チェッカー模様の床 (衝突判定の対象外) root.addChild(createFloor()); return root; } private TransformGroup createText3D( String text, double x, double y, double z, double angle, float r, float g, float b) { Transform3D t3d = new Transform3D(); t3d.setTranslation(new Vector3d(x, y, z)); Transform3D rt3d = new Transform3D(); rt3d.rotY(angle); t3d.mul(rt3d); TransformGroup trans = new TransformGroup(t3d); trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); Text3D text3d = new Text3D( new Font3D(new Font("dialog", Font.PLAIN, 1), new FontExtrusion() ), text, new Point3f(), Text3D.ALIGN_CENTER, Text3D.PATH_RIGHT ); Material mat = new Material(); mat.setDiffuseColor(new Color3f(r, g, b)); mat.setShininess(128); Appearance app = new Appearance(); app.setMaterial(mat); Shape3D shape = new Shape3D(text3d, app); shape.setCapability(Shape3D.ALLOW_BOUNDS_READ);//TEST shape.setUserData(trans); // ユーザーデータに親のTGをセットしておく trans.addChild(shape); return trans; } // チェッカー模様の床を作る private BranchGroup createFloor() { BranchGroup bg = new BranchGroup(); int roop = 40; Point3f[] vertices = new Point3f[roop * roop]; float start = -20.0f; float x = start; float z = start; float step = 1.0f; int[] indices = new int[(roop - 1)*(roop - 1) * 4]; int n = 0; Color3f white = new Color3f(1.0f, 1.0f, 1.0f); Color3f black = new Color3f(0.0f, 0.0f, 0.0f); Color3f[] colors = { white, black }; int[] colorindices = new int[indices.length]; for (int i=0; i