// Java 3D Test Applet // RotationPathTest.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 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.picking.PickRotateBehavior; import com.sun.j3d.utils.behaviors.picking.PickObject; import com.sun.j3d.utils.behaviors.picking.PickingCallback; import com.sun.j3d.utils.geometry.ColorCube; import com.sun.j3d.utils.geometry.Primitive; import com.sun.j3d.utils.geometry.Box; public class RotationPathTest extends Applet { private Canvas3D canvas = null; private Quat4f[] quats = null; private float[] knots = { 0.0f, 0.5f, 1.0f }; private AlphaPanel apanel = null; private RotationPathInterpolator rinterp = null; private TuplePanel tp0 = null; private TuplePanel tp1 = null; private TuplePanel tp2 = null; public RotationPathTest() { this.setLayout(new BorderLayout()); apanel = new AlphaPanel(); this.add(apanel, BorderLayout.NORTH); Panel ppanel = new Panel(); ppanel.setLayout( new GridLayout(3, 0) ); this.add(ppanel, BorderLayout.SOUTH); Panel[] ppanels = new Panel[3]; for (int i=0; i<3; i++) { ppanels[i] = new Panel(); ppanel.add(ppanels[i]); } final Button sbutton = new Button("Start"); sbutton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { String blabel = sbutton.getLabel(); if (blabel.equals("Start")) { rinterp.setEnable(true); apanel.reset(); sbutton.setLabel("Stop"); } else if (blabel.equals("Stop")) { rinterp.setEnable(false); sbutton.setLabel("Start"); } } }); ppanels[0].add(sbutton); quats = new Quat4f[3]; for (int i=0; i<3; i++) quats[i] = new Quat4f(0.0f, 0.0f, 0.0f, 0.0f); ppanels[0].add( new Label("k0") ); TextField k0field = new TextField("0.0"); k0field.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float k = 0.0f; try { k = Float.parseFloat(e.getActionCommand()); if (k < 0.0f) k = 0.0f; if (k > 1.0f) k = 1.0f; knots[0] = k; rinterp.setKnot(0, k); } catch (NumberFormatException ex) {} } }); ppanels[0].add(k0field); tp0 = new TuplePanel(quats[0]); String[] label0 = {"q0.x", "q0.y", "q0.z", "q0.w"}; tp0.setLabels(label0); ppanels[0].add(tp0); ppanels[1].add( new Label("k1") ); TextField k1field = new TextField("0.5"); k1field.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float k = 0.0f; try { k = Float.parseFloat(e.getActionCommand()); if (k < 0.0f) k = 0.0f; if (k > 1.0f) k = 1.0f; knots[1] = k; rinterp.setKnot(1, k); } catch (NumberFormatException ex) {} } }); ppanels[1].add(k1field); tp1 = new TuplePanel(quats[1]); String[] label1 = {"q1.x", "q1.y", "q1.z", "q1.w"}; tp1.setLabels(label1); ppanels[1].add(tp1); ppanels[2].add( new Label("k2") ); TextField k2field = new TextField("1.0"); k2field.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float k = 0.0f; try { k = Float.parseFloat(e.getActionCommand()); if (k < 0.0f) k = 0.0f; if (k > 1.0f) k = 1.0f; knots[2] = k; rinterp.setKnot(2, k); } catch (NumberFormatException ex) {} } }); ppanels[2].add(k2field); tp2 = new TuplePanel(quats[2]); String[] label2 = {"q2.x", "q2.y", "q2.z", "q2.w"}; tp2.setLabels(label2); ppanels[2].add(tp2); GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); canvas = new Canvas3D(config); this.add(canvas, BorderLayout.CENTER); SimpleUniverse universe = new SimpleUniverse(canvas); universe.getViewingPlatform().setNominalViewingTransform(); BranchGroup scene = createSceneGraph(); universe.addBranchGraph(scene); } private BranchGroup createSceneGraph() { BranchGroup root = new BranchGroup(); root.setCapability(BranchGroup.ALLOW_DETACH); BoundingSphere bounds = new BoundingSphere(new Point3d(), 100.0); TransformGroup mtrans = new TransformGroup(); mtrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); mtrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); mtrans.setCapability(TransformGroup.ENABLE_PICK_REPORTING); mtrans.setUserData("mtrans"); root.addChild(mtrans); final TransformGroup rtrans = new TransformGroup(); rtrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); rtrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); root.addChild(rtrans); TransformGroup p0trans = createCube(0.07, new Vector3d(-0.4, -0.7, 0.0), true); p0trans.setUserData("p0"); rtrans.addChild(p0trans); TransformGroup p1trans = createCube(0.07, new Vector3d(0.0, -0.7, 0.0), true); p1trans.setUserData("p1"); rtrans.addChild(p1trans); TransformGroup p2trans = createCube(0.07, new Vector3d(0.4, -0.7, 0.0), true); p2trans.setUserData("p2"); rtrans.addChild(p2trans); PickRotateBehavior mrotator = new PickRotateBehavior(root, canvas, bounds, PickObject.USE_GEOMETRY); mrotator.setupCallback( new PickingCallback() { public void transformChanged(int type, TransformGroup trans) { if (trans != null) { String udata = (String)trans.getUserData(); if (udata != null) { //System.out.println(udata);//DEBUG Transform3D t3d = new Transform3D(); trans.getTransform(t3d); if (udata.equals("mtrans")) { rtrans.setTransform(t3d); } else if (udata.equals("p0")) { t3d.get(quats[0]); tp0.set(quats[0]); rinterp.setQuat(0, quats[0]); } else if (udata.equals("p1")) { t3d.get(quats[1]); tp1.set(quats[1]); rinterp.setQuat(1, quats[1]); } else if (udata.equals("p2")) { t3d.get(quats[2]); tp2.set(quats[2]); rinterp.setQuat(2, quats[2]); } } } } }); root.addChild(mrotator); double[] vertices = { -0.8, -0.8, 0.0, -0.8, 0.8, 0.0, -0.4, -0.8, 0.0, -0.4, 0.8, 0.0, 0.0, -0.8, 0.0, 0.0, 0.8, 0.0, 0.4, -0.8, 0.0, 0.4, 0.8, 0.0, 0.8, -0.8, 0.0, 0.8, 0.8, 0.0, -0.8, -0.8, 0.0, 0.8, -0.8, 0.0, -0.8, -0.4, 0.0, 0.8, -0.4, 0.0, -0.8, 0.0, 0.0, 0.8, 0.0, 0.0, -0.8, 0.4, 0.0, 0.8, 0.4, 0.0, -0.8, 0.8, 0.0, 0.8, 0.8, 0.0 }; LineArray geom = new LineArray( vertices.length / 3, GeometryArray.COORDINATES); geom.setCapability(GeometryArray.ALLOW_INTERSECT); geom.setCoordinates(0, vertices); Shape3D grid = new Shape3D(geom); grid.setCapability(Shape3D.ALLOW_GEOMETRY_READ); mtrans.addChild(grid); mtrans.addChild( createCorner(0.05f, new Vector3d(-0.8, -0.8, 0.0)) ); mtrans.addChild( createCorner(0.05f, new Vector3d( 0.8, -0.8, 0.0)) ); mtrans.addChild( createCorner(0.05f, new Vector3d(-0.8, 0.8, 0.0)) ); mtrans.addChild( createCorner(0.05f, new Vector3d( 0.8, 0.8, 0.0)) ); TransformGroup ctrans = createCube(0.4, new Vector3d(), false); mtrans.addChild(ctrans); Transform3D rt3d = new Transform3D(); rinterp = new RotationPathInterpolator( apanel.getAlpha(), ctrans, rt3d, knots, quats ); rinterp.setSchedulingBounds(bounds); rinterp.setEnable(false); root.addChild(rinterp); return root; } private TransformGroup createCorner(float size, Vector3d position) { Transform3D t3d = new Transform3D(); t3d.set(position); TransformGroup trans = new TransformGroup(t3d); Appearance app = new Appearance(); Box box = new Box(size, size, size, Primitive.ENABLE_GEOMETRY_PICKING, app); trans.addChild(box); return trans; } private TransformGroup createCube(double size, Vector3d pos, boolean pick) { Transform3D t3d = new Transform3D(); t3d.set(pos); TransformGroup ctrans = new TransformGroup(t3d); ctrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); ctrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); if (pick) ctrans.setCapability(TransformGroup.ENABLE_PICK_REPORTING); ColorCube cube = new ColorCube(size); cube.setCapability(Shape3D.ALLOW_GEOMETRY_READ); cube.getGeometry().setCapability(GeometryArray.ALLOW_INTERSECT); ctrans.addChild(cube); return ctrans; } public static void main(String[] args) { RotationPathTest applet = new RotationPathTest(); Frame frame = new MainFrame(applet, 500, 600); } }